The PowerShell script discussed here allows you to change the local administrator password on multiple remote computers. You can also use the script to change the password of other accounts.

I still remember the days (way back in 2003-2004) when we were asked to change the local administrator password manually on all 2000+ computers in a weekend. Back then, system administrators in my region were pretty far removed from automation. But things evolved greatly after that, and system administrators started using programming languages (like VBScript) to automate tasks. Automation tasks have become much easier these days with the introduction of PowerShell.

So, let us see how we can change the local administrator password for a given list of computers using a PowerShell script.

Changing the administrator password with PowerShell

$password = Read-Host "Enter the password" -AsSecureString
$confirmpassword = Read-Host "Confirm the password" -AsSecureString
$pwd1_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.
  InteropServices.Marshal]::SecureStringToBSTR($password))
$pwd2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.
  InteropServices.Marshal]::SecureStringToBSTR($confirmpassword))
if($pwd1_text -ne $pwd2_text) {
   Write-Error "Entered passwords are not same. Script is exiting"
exit
}

As you will notice in the above code, I am prompting to confirm the password twice so that it won’t be entered wrong and cause the script to run again. I am also reading the password in a secure manner so that no one else can see it when it is being typed. Once the password is confirmed, the next two lines of dotnet code convert the password into plain text for comparison. If the comparison fails, the script exits; otherwise, it continues.

Now that we have the password, it is time to read the list of computers from a text file.

Reading list of computers

if(!(Test-Path $InputFile)) {
Write-Error "File ($InputFile) not found. Script is exiting"
exit
}

$Computers = Get-Content -Path $InputFile

Before reading the text file, I am doing a small check to see if that file exists or not. If the file is not found, the script exits. Otherwise, the script reads the contents of the file using the Get-Content cmdlet and stores the list in an array called $computers.

Now that we have the list of computers, we can start changing the password for each computer. That is what the below code does.

Chaging the password on multiple computers

foreach ($Computer in $Computers) {
   $Computer    =    $Computer.toupper()
   $Isonline    =    "OFFLINE"
   $Status        =    "SUCCESS"
    Write-Verbose "Working on $Computer"
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 {
   $account = [ADSI]("WinNT://$Computer/Administrator,user")
   $account.psbase.invoke("setpassword",$pwd1_text)
   Write-Verbose "`tPassword Change completed successfully"
}
catch {
  $status = "FAILED"
  Write-Verbose "`tFailed to Change the administrator password. Error: $_"
}

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

}

I am looping through each computer account in the array and first checking if it is online or not by using the Test-Connection cmdlet. This cmdlet does a ping check by sending one ICMP packet to the computer. If the ping is successful, the script changes the password. To do that, I am using the WinNT interface, which is pretty famous from VBScript days. After I get the reference to the administrator account, I invoke a method called SetPassword to change the password. If the password change fails, the respective error will be recorded using the catch block.

That’s it. The script has done its job and you will see the result in the console.

Change administrator password PowerShell

As you’ll notice in the output, the script creates a list of computers where the password has failed. The file "failed-computers.txt" is stored in the directory where the script picked up the computers list. If you want to provide a different directory where you want to store files, just pass the directory name to the -OutputDirectory parameter while executing the script.

Download the complete script from here.

A few tips for using this script

Type “Get-Help .\Update-LocalAdministratorPassword.ps1 -Detailed” in a PowerShell console for help.

  • Use the -Verbose switch from the command line if you want to see the debug information and error messages at each stage.
  • Passing the file name to the script is optional. The script will prompt you for the file if you don’t pass it.
  • Using this script, you can change the password of any local account. Just replace “administrator” with the account name for which you want to change the password.
avatar
56 Comments
  1. ketan 8 years ago

    How to add multiple computer name and password in below script
    please help me

  2. megamobileman 8 years ago

    Good Stuff Sitaram Pamarthi,  Much obliged for the info..

  3. Sameer 8 years ago

    Am getting error below error when I run the script

    At C:\Users\scha\Desktop\Set-Password.ps1:3 char:73
    + $pwd1_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.
    +                                                                         ~
    Missing ] at end of attribute or type literal.
    At C:\Users\scha\Desktop\Set-Password.ps1:3 char:74
    + $pwd1_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.
    +                                                                          ~
    Missing ‘)’ in method call.
    At C:\Users\scha\Desktop\Set-Password.ps1:4 char:3
    +   InteropServices.Marshal]::SecureStringToBSTR($password))
    +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Unexpected token ‘InteropServices.Marshal]::SecureStringToBSTR’ in expression or statement.
    At C:\Users\scha\Desktop\Set-Password.ps1:4 char:58
    +   InteropServices.Marshal]::SecureStringToBSTR($password))
    +                                                          ~
    Unexpected token ‘)’ in expression or statement.
    At C:\Users\scha\Desktop\Set-Password.ps1:5 char:73
    + $pwd2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.
    +                                                                         ~
    Missing ] at end of attribute or type literal.
    At C:\Users\scha\Desktop\Set-Password.ps1:5 char:74
    + $pwd2_text = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.
    +                                                                          ~
    Missing ‘)’ in method call.
    At C:\Users\scha\Desktop\Set-Password.ps1:6 char:3
    +   InteropServices.Marshal]::SecureStringToBSTR($confirmpassword))
    +   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Unexpected token ‘InteropServices.Marshal]::SecureStringToBSTR’ in expression or statement.
    At C:\Users\schabbi99\Desktop\Set-Password.ps1:6 char:65
    +   InteropServices.Marshal]::SecureStringToBSTR($confirmpassword))
    +                                                                 ~
    Unexpected token ‘)’ in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : EndSquareBracketExpectedAtEndOfAttribute

  4. Dineshkumar M 7 years ago

    HI I checked this script. Its working but i cant change multiple computers. i given my host name and other two host name. But password changed only my host machine. another two shows Failed. Even that computers is online and same network. Kindly help on this.

    Thanks

  5. Adnan 7 years ago

    i tried the script and seems to failing any ideas

    PS D:\Windows> .\Update-LocalAdministratorPassword.ps1 D:\Windows\Computers.txt -Verbose
    VERBOSE: Working on webserver
    VERBOSE:     webserver is Online
    VERBOSE:     Failed to Change the administrator password. Error: Exception calling “Invoke” with “2” argument(s): “The network path was not found.

    Failed computers list is saved to D:\Windows\failed-computers.txt
    ComputerName IsOnline PasswordChangeStatus
    ———— ——– ——————–
    webserver     ONLINE   FAILED

  6. Henry 6 years ago

    Thanks for the script!   It worked for me like a champ.  Very smooth!

    HJ

  7. Deepak Roy 5 years ago

    Hi Guys,

    I have modified the script to read computer names from text file and will display results with detailed error also which will give you csv output

    $computers = Get-Content -path "E:\Automate\Admin Pass chnage\computers.txt"
    $password = Read-Host -prompt "Enter new password for user" -assecurestring
    $decodedpassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password))
    foreach ($Computer in $Computers) {
    $Computer = $Computer.toupper()
    $Isonline = "OFFLINE"
    $Status = "SUCCESS"
    $StatsError ="Failed"
    if((Test-Connection -ComputerName $Computer -count 1 -ErrorAction 0)) {
    $Isonline = "ONLINE"
    } else { $StatsError= "`t$Computer is OFFLINE" }
    
    try {
    $account = [ADSI]("WinNT://$Computer/Administrator,user")
    $account.psbase.invoke("setpassword",$decodedpassword)
    $StatsError="Administrator Password changed successfully"
    }
    catch {
    $status = "FAILED"
    $StatsError="$_"
    }
    
    $obj = New-Object -TypeName PSObject -Property @{
    ComputerName = $Computer
    IsOnline = $Isonline
    PasswordChangeStatus = $Status
    DetailedStatus=$StatsError
    }
    
    $obj | Select ComputerName, IsOnline, PasswordChangeStatus,DetailedStatus
    $obj | Export-Csv -Append -Path "E:\Automate\Admin Pass chnage\output.csv"
    }
    
    avatar
  8. Hamid Jafary 5 years ago

    Gents,

    Tnx for this nice script. I have a question;

    Is this correct?  $Isonline = “OFFLINE”

    Shoudn’t be  like this?  $Isonline = “ONLINE”

    Greetings,

    Hamid

    • @hamid
      Yes the name of the variable is missleading.
      It would have been easier to read it the value of the $IsOnline variable would have been $True or $False.
      But in this script, the value of $IsOnline can be either ‘OFFLINE’ or ‘ONLINE’.
      The final result is the same. It’s just more difficult to read…

      • Mark 4 years ago

        i simply did a replace all on "IsOnline" and change it to "Availability"

  9. Hamid 5 years ago

    Tnx Luc for your explanation!

    avatar
  10. gopi 4 years ago

    server,username,password , each server with seperate password for give username in  csv file

     

    thanks in advance

  11. Anil (Rank 1) 4 years ago

    Hi Sitharam, I have used some scripts from Sysops..i am looking for Com+ application services shutdown and start command. I know this is not correct mail that i should ask..

    • Raki 4 years ago

      may i know how to connect the server with putty using powershell script

      • Leos Marek (Rank 4) 4 years ago

        I dont think you can anyhow control Putty tool (UI) with powershell. If you ask about how to connect to a server via SSH with powershell, there are some modules for that, use Google.

  12. Mark 4 years ago

    worked without issue, flawless, thank you much..

  13. jaya 4 years ago

    thanks helpful

  14. Martin 4 years ago
    $account = [ADSI]("WinNT://$Computer/Administrator,user")

    When I check $account after this, it returns an error "format-default :

    The following exception occurred while retrieving member "distinguishedName": "Unknown error (0x80005000)".

    Hence the value $account is empty.

  15. Has the local administrator account been renamed?

    Coralon

    • Martin 4 years ago

      The issue was quite simple. The "WinNT" part IS case sensitive.

  16. Cesar 4 years ago

    Hi All,

    I have been trying to change a little bit this script in order to have it reading the password from an encrypted string but I am getting an error. Anyone could help please? 
    It is returning: "

    FAILED,"Exception calling ""Invoke"" with ""2"" argument(s): ""Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))""","BRWS0600","ONLINE"
    
    $encrypted = "01000000d08c9ddf0115d1118c7a00c04fc297eb010000002181bf0465f52042ae8317400e02fb180000000002000000000003660000c000000010000000a657fc648c59a5a0ab3acf406357b21c0000000004800000a0000000100000004d42dab0c6fd84cf13eddc4ac4f1397818000000f6814fef5f55b9e56e4f1b65739afc8f1f2b1af51418b0e514000000ce239768be374411161a062b64e71f6eaa24b10b" 
    #$user = "labvikass" 
    $password = ConvertTo-SecureString -string $encrypted 
     
    #$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$password
    
    
    $computers = Get-Content -path "C:TempScriptlist.txt"
    
    foreach ($Computer in $Computers) {
    $Computer = $Computer.toupper()
    $Isonline = "OFFLINE"
    $Status = "SUCCESS"
    $StatsError ="Failed"
    if((Test-Connection -ComputerName $Computer -count 1 -ErrorAction 0)) {
    $Isonline = "ONLINE"
    } else { $StatsError= "`t$Computer is OFFLINE" }
    
    try {
    $account = [ADSI]("WinNT://$Computer/Administrator,user")
    
    $account.psbase.invoke("setpassword",$password)
    $StatsError="Administrator Password changed successfully"
    }
    catch {
    $status = "FAILED"
    $StatsError="$_"
    }
    
    $obj = New-Object -TypeName PSObject -Property @{
    ComputerName = $Computer
    IsOnline = $Isonline
    PasswordChangeStatus = $Status
    DetailedStatus=$StatsError
    }
    
    $obj | Select ComputerName, IsOnline, PasswordChangeStatus,DetailedStatus
    $obj | Export-Csv -Append -Path "C:TempScriptoutput.csv"
    }
    
    

  17. Tomas 3 years ago

    Hi

    when I try to run script i receive this error: 

    Error: Exception calling "Invoke" with "2" argument(s): "The
    network path was not found.

    What I can fix it?

    Thanks
    Tomas

  18. KEVIN 3 years ago

    Hi guys, 

    how can i integrate the date and time of the password change into your script ? Like a log file, Please ?

  19. Here I put this together..

    $encrypted = "01000000d08c9ddf0115d1118c7a00c04fc297eb010000002181bf0465f52042ae8317400e02fb180000000002000000000003660000c000000010000000a657fc648c59a5a0ab3acf406357b21c0000000004800000a0000000100000004d42dab0c6fd84cf13eddc4ac4f1397818000000f6814fef5f55b9e56e4f1b65739afc8f1f2b1af51418b0e514000000ce239768be374411161a062b64e71f6eaa24b10b" 
    $password = ConvertTo-SecureString -string $encrypted 
     
    $Report = foreach ($Computer in (Get-Content -path "C:\Temp\Scriptlist.txt")) {
        $IsOnline = Test-Connection -ComputerName $Computer -Quiet -Count 2
        if ($IsOnline) {
            try {
                $Account = [ADSI]('WinNT://{0}/Administrator,user' -f $Computer)
                $Account.PSBase.Invoke('setpassword', $Password)
                $Result = $true
                $ResultMessage = 'Successfully changed password on {0}' -f $Computer
            }
            catch {
                $Result = $false 
                $ResultMessage = 'Failed to change password on {0}' -f $Computer 
            }
        }
        else {
            $Result = $false
            $ResultMessage = 'Computer: {0} appears to be offline' -f $Computer
        }
    
        $ResultObject = [pscustomobject]@{
            ComputerName            = $Computer.ToUpper()
            IsOnline                = $IsOnline
            PasswordChangeResult    = $Result
            StatusMessage           = $ResultMessage
            TimeStamp               = [datetime]::Now().ToString()
        }
    }
    
    $Report | Export-CSV -Path 'c:\temp\ScriptOutput.csv' -NoTypeInformation
    

    Coralon

  20. Faez Bhanji 3 years ago

    Hi Sitaram,

    Thank you so much for your most valuable information.  However just wondering, should you not Zero the BTSR variable that you created in your script.  I have found that being Powershell I don't need to, but I would just like to confirm this with you or any of your peers here.

    cheers

  21. Kevin 2 years ago

    Hi Guys ,

    I would like to implement when the server is in French with an “Administrateur” account. The current script only takes into account the "Administrator" account. I would like the verification between these two accounts

    avatar
    • Leos Marek (Rank 4) 2 years ago

      Kevin,

      what do you mean with the verification?

      If you have French OS, simple replace the account name in the script.

      Cheers

      • Olivier 2 years ago

        Hi All, This post is very old now. If you are in a AD Domain, have you consider to use LAPS (Local Administror Password Solution) to manage Administrator (local) Accounts ?

        Regards

        Olivier

        avatar
        • Leos Marek (Rank 4) 2 years ago

          Hi Olivier,

          yes LAPS was covered dozens of times here. There are some limitations tho – it can only manage one acccount, etc.

          Also, LAPS might not be well implemented everywhere.

          Cheers

  22. Was giving this some thought.. and you could do this as a relatively language/name independent way of handling this.. 

    $encrypted = "01000000d08c9ddf0115d1118c7a00c04fc297eb010000002181bf0465f52042ae8317400e02fb180000000002000000000003660000c000000010000000a657fc648c59a5a0ab3acf406357b21c0000000004800000a0000000100000004d42dab0c6fd84cf13eddc4ac4f1397818000000f6814fef5f55b9e56e4f1b65739afc8f1f2b1af51418b0e514000000ce239768be374411161a062b64e71f6eaa24b10b" 
    $password = ConvertTo-SecureString -string $encrypted 
    
    $Report = foreach ($Computer in (Get-Content -path "C:\Temp\Scriptlist.txt")) {
        $IsOnline = Test-Connection -ComputerName $Computer -Quiet -Count 2
        if ($IsOnline) {
            try {
                $CIMProps = @{
                    ComputerName = $Computer 
                    ClassName = Win32_UserAccount
                    Filter = 'SID LIKE "%-500" AND LocalAccount = TRUE'
                }
                $AccountName = Get-CimInstance @CIMProps | Select-Object -ExpandProperty Name 
                $Account = [ADSI]( 'WinNT://{0}/{1},user' -f $Computer, $AccountName)
                $Account.PSBase.Invoke('setpassword', $Password)
                $Result = $true
                $ResultMessage = 'Successfully changed password on {0}' -f $Computer
            }
            catch {
                $Result = $false 
                $ResultMessage = 'Failed to change password on {0}' -f $Computer 
            }
        }
        else {
            $Result = $false
            $ResultMessage = 'Computer: {0} appears to be offline' -f $Computer
        }
    
        $ResultObject = [pscustomobject]@{
            ComputerName            = $Computer.ToUpper()
            IsOnline                = $IsOnline
            PasswordChangeResult    = $Result
            StatusMessage           = $ResultMessage
            TimeStamp               = [datetime]::Now().ToString()
        }
    }
    
    $Report | Export-CSV -Path 'c:\temp\ScriptOutput.csv' -NoTypeInformation

    It should take care of renamed accounts, foreign languages etc. 

    David F. 

  23. Puthearith (Rank 1) 2 years ago

    Hi All, I tested on Server 2016 not working with result’s wrong as Offline status and VERBOSE: Failed to Change the administrator password. Error: Exception calling “Invoke” with “2” argument(s): “Unknown error (0x80005008)”

    Could you anyone help on this?

    Thanks!

Leave a reply to David Figueroa (Rank 3) Click here to cancel the reply

Please enclose code in pre tags

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account