組織内のリモート コンピューターのローカル管理者パスワードをリセットするスクリプトを作成しようとしています。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
。
これが私がやった方法です。このスクリプトはどこかの Web サイトから取得したものだと思いますが、どこから取得したのかコメントも記録もしていないため、クレジットを付与できないのが恥ずかしいです。
準備
まず、スクリプトで接続をテストします。
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 ビルド 1607 では、新しい Powershell 5.1 でSet-LocalUser
コマンドが導入されました。ADSI アダプターの代わりにこれをこのタスクに使用できますが、リモート コンピューターで Powershell リモート処理サービスが有効になっている必要があります (デフォルトでは無効になっています)。リモート コマンドを受け入れるには、リモート コンピューターの管理者Enable-PSRemoting
特権の Powershell ターミナルで run を実行する必要があります。
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.";
}