Estoy intentando crear una secuencia de comandos para restablecer la contraseña de administrador local para una computadora remota en mi organización. Soy bastante nuevo en PowerShell y estoy aprendiendo la mayor parte intentándolo y fallando en el proceso. El guión que tengo hasta ahora:
Import-Module ActiveDirectory
$computer = Read-Host -Prompt "Enter computer Name Here"
$password = Read-Host -Prompt "Enter Password Here"
Set-ADAccountPassword - Identity $computer -NewPassword $password
Lo más probable es que sea un error estúpido, así que sé amable conmigo :)
Respuesta1
TL;DR
Estoy de acuerdo con la otra respuesta de que elAdaptador PowerShell ADSIfunciona para esto. También estoy de acuerdo con los comentarios de que si desea proporcionar credenciales de forma interactiva, debe usar Get-Credential
y no Read-Host
.
Así es como lo hice: creo que tomé este script de algún sitio web y me da vergüenza no poder dar crédito porque no comenté ni mantuve un registro de dónde lo obtuve.
Preparación
Primero, mi script prueba la conexión:
if((Test-Connection -ComputerName $Computer -count 1 -ErrorAction 0)) {
$Isonline = "ONLINE"
Write-Verbose "`t$Computer is Online"
} else { Write-Verbose "`t$Computer is OFFLINE" }
El cambio de contraseña
Luego, mi secuencia de comandos try/catch
intenta establecer la contraseña y registrar e informar el éxito o el fracaso:
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: $_"
}
Hay algunas diferencias aquí. Primero, sabía de antemano el nombre de usuario de la cuenta que quería cambiar (mi secuencia de comandos era cambiar todas las contraseñas de administrador local a la vez). Puedes usar
$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user"
en lugar de eso, como se menciona en la otra respuesta. Además, mi script (que funcionó para mí en servidores 2012 R2) usa $user.psbase.invoke("setpassword",$password)
en lugar de $user.SetPassword($password)
. Confieso que no sé cuál es la diferencia ni si uno funcionará mejor que el otro.
Informes
Finalmente, mi guión informa sobre el éxito o el fracaso. Esto se debe a que utilicé mi script para recorrer todos los servidores del entorno para actualizar todas las contraseñas de administrador local, por lo que necesitaba saber qué servidores fallaron, si los hubo, para poder regresar manualmente y abordarlos. Puede que esto no sea necesario para usted en absoluto.
$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")
}
Respuesta2
Si tiene Powershell 5.0 o una versión anterior, deberá utilizar el adaptador ADSI de Powershell para manipular una cuenta de usuario local en una computadora remota:
$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();
Es posible que desee verificar que puede hacer ping a la computadora remota antes de intentar conectarse a ella y manejar ese caso cuando el usuario hace clic en Cancelar en el cuadro de diálogo de entrada de credenciales.
$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.";
}
Editar:En Windows 10 build 1607, el nuevo Powershell 5.1 introdujo el Set-LocalUser
comando. Puede usarlo para esta tarea en lugar del adaptador ADSI, pero requiere que el servicio de comunicación remota Powershell esté habilitado (que está deshabilitado de forma predeterminada) en las computadoras remotas. Para permitir la aceptación de comandos remotos, debe ejecutar ejecutar Enable-PSRemoting
en una terminal Powershell elevada en la computadora remota.
Si la comunicación remota de PS está habilitada, el script modificado se verá así:
$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.";
}