我正在尝试创建一个脚本,用于重置我组织中的远程计算机的本地管理员密码。我对 powershell 还很陌生,我通过尝试和失败来学习大部分内容。到目前为止,我拥有的脚本是:
Import-Module ActiveDirectory
$computer = Read-Host -Prompt "Enter computer Name Here"
$password = Read-Host -Prompt "Enter Password Here"
Set-ADAccountPassword - Identity $computer -NewPassword $password
这很可能只是一个愚蠢的错误,所以请对我温柔一点:)
答案1
总结
我同意另一个答案PowerShell ADSI 适配器适用于此。我还同意以下评论:如果您想以交互方式提供凭据,则应使用Get-Credential
和 而不是Read-Host
。
这是我的方法 - 我想我是从某个网站上获取了这个脚本,但我很尴尬,因为我没有评论或记录我从哪里获得它,所以我不能给予信任。
准备
首先,我的脚本测试连接:
if((Test-Connection -ComputerName $Computer -count 1 -ErrorAction 0)) {
$Isonline = "ONLINE"
Write-Verbose "`t$Computer is Online"
} else { Write-Verbose "`t$Computer is OFFLINE" }
密码更改
然后我的脚本用来try/catch
尝试设置密码并记录和报告成功或失败:
try {
$account = [ADSI]("WinNT://$Computer/-PUT THE USERNAME YOU WANT TO CHANGE HERE-,user")
$account.psbase.invoke("setpassword",$password)
Write-Verbose "`tPassword Change completed successfully"
}
catch {
$status = "FAILED"
Write-Verbose "`tFailed to Change the administrator password. Error: $_"
}
这里有一些不同。首先,我事先知道要更改的帐户的用户名(我的脚本是一次性更改所有本地管理员密码)。您可以使用
$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user"
而不是像另一个答案中提到的那样。另外,我的脚本(在 2012 R2 服务器上为我工作)使用$user.psbase.invoke("setpassword",$password)
而不是$user.SetPassword($password)
。我承认我不知道有什么区别,也不知道一个是否比另一个更好。
报告
最后,我的脚本会报告成功/失败。这是因为我使用脚本遍历环境中的所有服务器来更新所有本地管理员密码,所以我需要知道哪些服务器发生故障(如果有的话),以便我可以手动返回并解决它们。这对您来说可能根本没有必要。
$obj = New-Object -TypeName PSObject -Property @{
ComputerName = $Computer
IsOnline = $Isonline
PasswordChangeStatus = $Status
}
$obj | Select ComputerName, IsOnline, PasswordChangeStatus
if($Status -eq "FAILED" -or $Isonline -eq "OFFLINE") {
$stream.writeline("$Computer `t $isonline `t $status")
}
答案2
如果您拥有 Powershell 5.0 或更早版本,则需要使用 Powershell ADSI 适配器来操作远程计算机上的本地用户帐户:
$computer = Read-Host -Prompt "Enter Computer Name Here";
$credential = Get-Credential -UserName "Administrator" -Message "Enter new password";
$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user";
$user.SetPassword($credential.GetNetworkCredential().Password);
$user.SetInfo();
您可能需要在实际尝试连接远程计算机之前检查是否可以 ping 远程计算机,并在用户在凭据输入对话框中单击“取消”时处理该情况。
$computer = Read-Host -Prompt "Enter Computer Name Here";
If (Test-Connection -ComputerName $computer -Count 2 -Quiet) {
Write-Host "The computer responded to our ping request. Connecting...";
$credential = Get-Credential -UserName "Administrator" -Message "Enter new password";
If ($credential -eq $null) {
Write-Warning "The username and/or the password is empty! I quit.";
Exit;
}
$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user";
$user.SetPassword($credential.GetNetworkCredential().Password);
$user.SetInfo();
} Else {
Write-Warning "The computer does not respond to our ping request. I quit.";
}
编辑:在 Windows 10 build 1607 中,新的 Powershell 5.1 引入了该Set-LocalUser
命令。您可以使用它代替 ADSI 适配器执行此任务,但它需要在远程计算机上启用 Powershell 远程服务(默认情况下禁用)。要允许接受远程命令,您需要Enable-PSRemoting
在远程计算机上的提升的 Powershell 终端中运行。
如果启用了 PS 远程处理,则修改后的脚本将如下所示:
$computer = Read-Host -Prompt "Enter Computer Name Here";
If (Test-Connection -ComputerName $computer -Count 2 -Quiet) {
Write-Host "The computer responded to our ping request. Connecting...";
Invoke-Command -ComputerName $computer -ScriptBlock {
$credential = Get-Credential -UserName "Administrator" -Message "Enter new password";
If ($credential -eq $null) {
Write-Warning "The username and/or the password is empty! I quit.";
Exit;
}
Set-LocalUser -Name $credential.UserName -Password $credential.Password;
}
} Else {
Write-Warning "The computer does not respond to our ping request. I quit.";
}