Learning PowerShell a.k.a. “How to change 50 local admin passwords in 2 minutes”
When someone leaked a local administrator account password to roughly 50 web servers in our hosted environment my first reaction was @#$%*&^! because they’re not on a domain and I knew that meant I would be spending the next hour changing passwords. So, I decided that I can’t put it off anymore… I need to learn PowerShell. After reading the Intro paragraph of the dust-covered PowerShell book sitting on my desk and 45 minutes of scouring the web I was ready to go! The script prompts for the username who’s password you want to change, the new password, the username/password of the account logging in to actually make the change. It uses a list of servers called ServerList.txt (I didn’t incorporate any kind of AD query since this was used for non-domain servers). I’ve also included simple but informative screen output as well as some simple error checking and logging.
So without further delay here is my first PowerShell script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #************************************************************************************ # # NAME: AdminPWreset.ps1 # # AUTHOR: Allen Oliver # # EMAIL: admin@evilemuofdoom.com # # COMMENTS: # ***NOTE*** Requires Powershell 2.0! (I think... it's possible I might have fixed # this but I no longer have Powershell 1.0 installed anywhere to test) # # This script takes entries in a text file called ServerList.txt and resets the # password to the specified local account (Administrator by default). It also # provides a simple dated log file. # # SPECIAL THANKS!: # Thanks goes out to the numerous contributors at poshcode.com! # Since installing Windows 7 on my laptop I lost my reference links :( If you # think your site contributed to this script, let me know so I can give proper # credit. # Thanks @octopauly for the "–assecurestring" parameter to mask PW! # # VERSION HISTORY: # 1.0 - 7/28/2009 - Wrote and tested script # 2.0 - 8/3/2009 - Added logging and comments # #************************************************************************************ cls #Hide errors from console, set logfile name to PWChange-MM-DD-YYYY.log $ErrorActionPreference = "SilentlyContinue" $logFile = "PWChange-$((get-date).ToString('MM-dd-yyyy')).log" #Prompt for Username who's PW will be changed $UserName = Read-Host "Enter the local username who's password you want changed (Leave blank for Administrator)" #If username is left blank, set to "Administrator" If($UserName -match $null){ $UserName = "Administrator"} #Prompt for new PW $NewPW = Read-Host –assecurestring "Enter the new password" #Get login credentials $AdminUser = Read-Host "Please enter the username used to login to the servers (Leave blank for Administrator)" If($AdminUser -match $null){ $AdminUser = "Administrator"} $AdminPW = Read-Host –assecurestring "Enter Password" cls $Time = (Get-Date -format g) Add-Content "$Time - Script started" -path $logFile -passthru #Set pw for each server in ServerList.txt with simple error checking and logging. foreach($Server in get-content ServerList.txt){ $x = 0 $myuser = new-Object System.DirectoryServices.DirectoryEntry("WinNT://$Server/$UserName,user",$AdminUser,$AdminPW) If($?){$x = $x + 1} Else{$x = 0} $myuser.psbase.invoke("SetPassword",$NewPW) If($?){$x = $x + 1} Else{$x = 0} $myuser.psbase.CommitChanges() If($?){$x = $x + 1} Else{$x = 0} $Time = (Get-Date -format g) If($x -eq 3){ Add-Content "$Time - Password Reset was Successful for $Server" -path $logFile -passthru } Else{ Write-Host "$Time - Password Reset FAILED for $Server" -ForegroundColor black -BackgroundColor red Add-Content "$Time - Password Reset FAILED for $Server" -path $logFile } } $Time = (Get-Date -format g) Add-Content "Completed on $Time. Results logged to $logFile" -path $logFile -passthru Add-Content "-------------------------------------------------------------------------------" -path $logFile -passthru Write-Host "" Write-Host "Press any key to continue..." $x = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") |
All in all I think it’s not bad for my first PowerShell script. It could be a little prettier or arranged in functions but it’ll do for now. It was a great learning experience that has led me into using PowerShell to perform administrative tasks in VMware, but that’s another post entirely
. Feedback, corrections, or suggestions are welcome.
Update: Thanks @octopauly for the following VERY helpful suggestion via Twitter
@evilemuofdoom By adding the –assecurestring parameter you can mask the data entered. Good practice with passwords. http://tr.im/vYC2