Windows – Resetting local admin password for a remote computer using Powershell

active-directorypowershellwindows

I'm trying to create a script for resetting local admin password for a remote computer in my organization.
I'm pretty new to powershell, and I'm learning most of it by trying and failling in the process.
The script I have so far:

Import-Module ActiveDirectory
$computer = Read-Host -Prompt "Enter computer Name Here"
$password = Read-Host -Prompt "Enter Password Here"
Set-ADAccountPassword - Identity $computer -NewPassword $password

Most likely it's just a stupid mistake, so please be gentle with me 🙂

Best Answer

TL;DR

I agree with the other answer that the PowerShell ADSI adapter works for this. I also agree with the comments that if you want to interactively provide credentials, you should use Get-Credential and not Read-Host.


Here's how I did it - I think I grabbed this script from some web site and I'm embarrassed I can't give credit because I didn't comment or keep track of where I got it from.

Preparation

First, my script tests the connection:

if((Test-Connection -ComputerName $Computer -count 1 -ErrorAction 0)) {
    $Isonline = "ONLINE"
    Write-Verbose "`t$Computer is Online"
} else { Write-Verbose "`t$Computer is OFFLINE" }

The password change

Then my script uses try/catch to attempt to set the password and record and report success or failure:

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: $_"
}

There are some differences here. First, I knew the username of the account I wanted to change in advance (my script was to change all the local admin passwords at once). You can use

$user = [adsi]"WinNT://$computer/$($credential.GetNetworkCredential().Username),user"

instead as mentioned in the other answer. Also, my script (which worked for me on 2012 R2 servers) uses $user.psbase.invoke("setpassword",$password) instead of $user.SetPassword($password). I confess I don't know what the difference is or whether one will work better than the other.

Reporting

Finally, my script reports on success/failure. This is because I used my script to iterate through all of the servers in the environment to update all of the local admin passwords, so I needed to know which servers failed, if any, so I could manually go back and address them. This may not be necessary for you at all.

$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")
}