标准Windows用户如何从命令行更改密码?


18

在Windows Server 2008 R2上,我有一个标准的(非管理员)本地用户(尽管该服务器位于域中,但不是Active Directory帐户),该用户只能通过PowerShell Remoting访问该服务器。用户无法通过RDP登录。

我希望该用户能够更改其密码。即使用户试图更改自己的密码,“ net user”命令也需要管理员权限。

标准用户如何从命令行更改密码?

Answers:


18

以下是一些PowerShell代码,可用来执行您要使用域帐户进行的操作:

param (
    [string]$oldPassword = $( Read-Host "Old password"),
    [string]$newPassword = $( Read-Host "New password")
)

$ADSystemInfo = New-Object -ComObject ADSystemInfo
$type = $ADSystemInfo.GetType()
$user = [ADSI] "LDAP://$($type.InvokeMember('UserName', 'GetProperty', $null, $ADSystemInfo, $null))"
$user.ChangePassword( $oldPassword, $newPassword)

ASDI提供程序还支持WinNT://computername/usernameChangePassword()方法的语法。ADSystemInfo但是,该对象不适用于本地计算机帐户,因此仅使用WinNT://...语法对上面的代码进行改型是行不通的。

(有人想建议带代码的编辑来区分本地帐户和域帐户吗?)

使用完全不同的方法,旧的NetUserChangePasswordAPI也可以与本地(和域,只要您使用NetBIOS语法指定域名)帐户一起使用:

param (
    [string]$oldPassword = $( Read-Host "Old password"),
    [string]$newPassword = $( Read-Host "New password")
)

$MethodDefinition = @'
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public static extern bool NetUserChangePassword(string domainname, string username, string oldPassword, string newPassword);
'@

$NetAPI32 = Add-Type -MemberDefinition $MethodDefinition -Name 'NetAPI32' -Namespace 'Win32' -PassThru

$NetAPI32::NetUserChangePassword('.', $env:username, $oldPassword, $newPassword)

此代码假定您正在更改本地计算机上的密码(“。”)。


1
您击败了我,但是我赢得了字符保护;)您是否知道有必要使用多余的部分吗?还是只是为了更加正式和恰当?
charleswj81 2014年

1
您肯定会获得代码高尔夫奖。我只是正式而适当的……实际上,这主要是使脚本对可能是剪切粘贴类型的其他人更有用。
Evan Anderson

1
@ charleswj81-Evan的答案更加完整。它是一个独立的PS1脚本,可以使用或不使用参数来调用。它也更具可读性。代码是关于人类理解别人写的东西而不是计算机的东西。两种解决方案都不会比另一种更快。
Mark Henderson

1
这看起来很有希望,但我应该澄清一下,该帐户是系统本地的。我尝试了以下操作: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS") 但是返回了“密码不符合密码策略要求...”。不过,新密码确实满足了这些要求。
elijahbuck

1
实际上,将用户添加到“远程桌面用户”并尝试以这种方式更改密码后,我遇到了相同的错误。我认为更改本地帐户的正确方法是: ([ADSI]'WinNT://localhost/USERNAME').ChangePassword("OLDPASS", "NEWPASS")
elijahbuck 2014年

9

在PowerShell中,这实际上非常简单:

([ADSI]'LDAP://CN=User,CN=Users,DC=domain').ChangePassword('currentpassword','newpassword')

3

对于更改未加入域的本地管理员的密码,我尝试了以上两个答案均无济于事。浏览评论可以得到我所需要的。

对于当前接受的答案的第二部分,您想更新签名以使用long而不是bool返回值,并且可以在系统错误代码docs它们进行故障排除。因此,您最终得到:

param (
    [string]$oldPassword = $( Read-Host "Old password"),
    [string]$newPassword = $( Read-Host "New password")
)

$MethodDefinition = @'
[DllImport("netapi32.dll", CharSet = CharSet.Unicode)]
public static extern **long** NetUserChangePassword(string domainname, string username, string oldPassword, string newPassword);
'@

$NetAPI32 = Add-Type -MemberDefinition $MethodDefinition -Name 'NetAPI32' -Namespace 'Win32' -PassThru

$NetAPI32::NetUserChangePassword('.', $env:username, $oldPassword, $newPassword)

但是,这对我没有用。错误代码在86和2221之间交替变化,具体取决于我如何设置参数。打算放弃并深入讨论,最终在做事中取得了成功:

([ADSI]'WinNT://./USERNAME').ChangePassword("OLDPASS‌​", "NEWPASS")

简直太荒谬了,在Powershell中,简单地更改本地管理员密码是如此复杂。如果您在系统上完全存储安全字符串,则必须通过提供旧密码来完成密码的更新,否则可能会失去正确解密这些安全字符串的能力!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.