Restablecer la contraseña de administrador local para una computadora remota usando Powershell

Restablecer la contraseña de administrador local para una computadora remota usando Powershell

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-Credentialy 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/catchintenta 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-LocalUsercomando. 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-PSRemotingen 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.";
}

información relacionada