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

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

在 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/usernameASDI 提供程序也支持该方法的语法ChangePassword()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)

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

答案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

相关内容