Я пытаюсь создать скрипт для сброса пароля локального администратора для удаленного компьютера в моей организации. Я довольно новичок в 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
TL;DR
Я согласен с другим ответом, чтоАдаптер 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();
Возможно, вам захочется проверить возможность пингования удаленного компьютера, прежде чем пытаться подключиться к нему, и обработать случай, когда пользователь нажимает «Отмена» в диалоговом окне ввода учетных данных.
$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 (которая по умолчанию отключена). Чтобы разрешить прием удаленных команд, вам нужно запустить run 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.";
}