You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用PowerShell结合ADSI凭据远程修改Windows账户密码(需旧密码验证)

用显式凭据验证旧密码并修改远程Windows账户密码

你当前的脚本依赖运行账户的权限,所以非提升权限时会失败。要实现“先验证旧密码获取权限,再修改新密码”的需求,核心是显式使用包含旧密码的高权限凭据来绑定ADSI对象,而不是用当前用户上下文。下面是具体的实现方案:

实现思路

  1. 用旧密码创建高权限账户的凭据对象,以此验证旧密码的有效性;
  2. 通过这个凭据显式绑定远程服务器的ADSI用户对象,确保操作拥有足够权限;
  3. 验证凭据有效后,调用SetPassword修改为新密码。

完整脚本示例

# 配置参数
$server = "Server1"
$adminID = "Administrator"
$oldPassword = "OldPassword"
$newPassword = "NewPassword"

# 将旧密码转换为安全字符串,创建凭据对象
$secureOldPassword = ConvertTo-SecureString $oldPassword -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($adminID, $secureOldPassword)

try {
    # 显式绑定远程用户的ADSI对象,传入凭据验证旧密码
    $userEntry = New-Object System.DirectoryServices.DirectoryEntry(
        "WinNT://$server/$adminID",
        $credential.UserName,
        $credential.GetNetworkCredential().Password,
        [System.DirectoryServices.AuthenticationTypes]::Secure
    )

    # 尝试读取用户名称属性,验证凭据是否有效(旧密码错误会在此抛出异常)
    $null = $userEntry.Name

    # 验证通过后修改密码并提交更改
    $userEntry.SetPassword($newPassword)
    $userEntry.CommitChanges()

    Write-Host "✅ 远程账户密码修改成功!"
}
catch {
    Write-Error "❌ 操作失败:$($_.Exception.Message)"
}

关键细节说明

  • 为什么不用[ADSI]快捷方式?[ADSI]默认使用当前运行脚本的账户上下文,无法显式传入凭据。改用System.DirectoryServices.DirectoryEntry构造函数,可以直接指定用户名、密码和加密验证方式,确保权限和安全性。
  • 提前验证凭据:读取$userEntry.Name是为了在修改密码前就确认旧密码是否正确,避免到修改步骤才报错,方便排查问题。
  • 加密验证:指定AuthenticationTypes::Secure会强制加密身份验证过程,防止旧密码在网络传输中泄露。
  • 安全建议:实际使用时不要在脚本中明文存储密码,建议用Read-Host -AsSecureString让用户交互式输入,比如:
    $oldPassword = Read-Host "请输入旧密码" -AsSecureString
    $newPassword = Read-Host "请输入新密码" -AsSecureString
    # 注意:SetPassword需要明文密码,所以要转换:
    $newPasswordPlain = [System.Net.NetworkCredential]::new("", $newPassword).Password
    

注意事项

  • 远程服务器需允许WinNT协议访问(默认开启,若有防火墙需确保SMB相关端口开放);
  • 所用的高权限账户(如示例中的Administrator)必须拥有修改目标账户密码的权限(本地管理员默认具备此权限);
  • 若目标是域账户,需将WinNT路径改为LDAP格式,但你的需求是本地账户,所以WinNT路径适用。

内容的提问来源于stack exchange,提问作者J. DuBois

火山引擎 最新活动