在 Windows Server 2008 R2 上,我有一个标准(非管理员)本地用户(不是 Active Directory 帐户,尽管服务器在域中),该用户只能通过 PowerShell Remoting 访问服务器。该用户无法通过 RDP 登录。
我希望该用户能够更改其密码。即使用户试图更改自己的密码,'net user' 命令也需要管理员权限。
标准用户如何从命令行更改密码?
答案1
下面是一些使用域帐户执行所需操作的 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)
WinNT://computername/username
ASDI 提供程序也支持该方法的语法ChangePassword()
。ADSystemInfo
但是,该对象不适用于机器本地帐户,因此仅用WinNT://...
语法改造上述代码是不可行的。
(有人想建议使用代码进行编辑以区分本地帐户和域帐户吗?)
从完全不同的角度来说,旧NetUserChangePassword
API 也适用于本地(和域,前提是您以 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)
此代码假定您正在本地机器(“。”)上更改密码。
答案2
在 PowerShell 中这实际上非常简单:
([ADSI]'LDAP://CN=User,CN=Users,DC=domain').ChangePassword('currentpassword','newpassword')
答案3
我尝试了上述两种方法,但都无济于事,因为我无法更改未加入域的本地管理员的密码。不过,查阅评论后,我找到了我需要的信息。
对于当前接受的答案的第二部分,您想要更新签名以long
代替bool
返回值,并且可以在以下位置对这些进行故障排除:系统错误代码文档.因此你最终得到:
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 中,更改本地管理员密码竟然如此复杂,这真是太荒谬了。如果您在系统上存储了安全字符串,则必须通过提供旧密码来更新密码,否则可能会失去正确解密这些安全字符串的能力!
答案4
这结合了本主题中多个贡献者的信息以及代码后引用的主题
# For local system userids, try entering the hostname for the User Domain
param (
[string]$domain = $( Read-Host "User Domain "),
[string]$userName = $( Read-Host "User Name "),
[string]$oldPassword = $( Read-Host "Old password")
)
$punc = @(0x2e,0x2b,0x2a,0x2d,0x5f)
$digits = 48..57
$upper = 65..90
$lower = 97..122
$combined = $punc + $upper + $digits + $lower
function generatePass {
$pass = ""
Get-Random -Count 1 -InputObject $lower | %{$pass += [char]$_}
Get-Random -Count 1 -InputObject $upper | %{$pass += [char]$_}
Get-Random -Count 1 -InputObject $punc | %{$pass += [char]$_}
Get-Random -Count 1 -InputObject $digits | %{$pass += [char]$_}
Get-Random -Count 19 -InputObject $combined | %{$pass += [char]$_}
return $pass
}
$newPassword = generatePass
write $newPassword
$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
$winErrCode = $NetAPI32::NetUserChangePassword($domain, $userName, $oldPassword, $newPassword)
# You want to see 0/Success as the final output line
write $winErrCode
密码生成的想法是从这个主题中收集的,然后进行了简化。 https://stackoverflow.com/questions/37256154/powershell-password-generator-how-to-always-include-number-in-string