[breadcrumb]
This PowerShell script is specific to a piece of software called Idera Up.Time Infrastructure Monitor. We have recently started using this great monitoring application, but I found some parts of rolling it out across our infrastructure a little bit tedious or prone to human error. One such part being setting the up.time agent’s password.
I had a list of 50 servers to deploy the agent on. It was only at sever 36 that I realised I had forgotten to set the password. Knowing that I had around another 400 servers to deploy the agent to, I didn’t fancy logging back onto each server and sorting the password out manually with potential for me to forget again in the future.
To work around this, I have created this PowerShell script to automate setting the password. The way it works is a password is passed to the script, along with a list of servers in a text file. For each of the servers in the text file, it checks if the “Remote Registry” service is started. If it isn’t, it’ll start it and make a note that it had to do this. It’ll then attempt to write the password to the machine, first assuming it is a 64-bit Windows box. If it doesn’t find it, it’ll attempt 32-bit Windows instead. If it had to start the “Remote Registry” service to do its job, it’ll stop it again. If it was already running, then it’ll leave it alone.
Usage: .\UptimePasswordSet.ps1 -Password password -Agents list.txt
Download Idera up.time Agent Password Setter v1.1
[Screenshot]
Source Code
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
################################################################################################# # # # up.time agent password setter v1.1 # # # # Written by: Mike Oldfield # # Date: 18/05/2016 # # # # This PS1 automates setting the password for up.time agents. # # # # Usage: .\UpTimePasswordSet.ps1 -Password password -Agents list.txt # # # # Create a text file called list.txt and store it in the same location as the script. # # This text file should then contain a list of servers you wish to change the password on. # # # # Change Log: # # v1.1 (23/05/2016) - (1) Fixed an error catching issue where Access Denied to start Remote # # Registry service was not caught and parsed accordingly. # # # # (2) If "Remote Registry" was stopped when the script was launched, the # # script now goes back and stops it again when it has completed its task # # rather than leaving it running. # # # ################################################################################################# ############################# # # # PARAMETERS # # # ############################# # Set some avaialble paramters. This bit must come first param ( [Parameter(Mandatory=$true)] # Set the following parameter to be mandatory [string]$Password, # -Password: What password do you want to set? [string]$Agents = "list.txt" # -Agents: Where is your list of agents? Default: list.txt ) $scriptVer = "v1.1" # What version of the script is this? Used for header info $scriptAuth = "Mike Oldfield" # Who wrote the script? $scriptLastUpdate = "18/05/2016" # When was the script last updated? # Set error value to 0 $errVal = 0 # Set Remote Registry service status to 0. If changed to 1 by the script, it was stopped. $RRServStopped = 0 ############################# # # # SCRIPTY BIT # # # ############################# # Write a pretty header Write-Host "`r`n##################################################`r`n" -ForegroundColor darkcyan -NoNewLine Write-Host "##### " -ForegroundColor darkgray -NoNewLine Write-Host "up.time agent password setter $scriptVer " -ForegroundColor gray -NoNewLine Write-Host "#####`r`n##### " -ForegroundColor darkgray -NoNewLine Write-Host "Written by: $scriptAuth " -ForegroundColor gray -NoNewLine Write-Host " #####`r`n##### " -ForegroundColor darkgray -NoNewLine Write-Host "Last Updated: $scriptLastUpdate " -ForegroundColor gray -NoNewLine Write-Host " #####`r`n" -ForegroundColor darkgray -NoNewLine Write-Host "##################################################`r`n" -ForegroundColor darkcyan # Try to grab the list of server agents... try { $Servers = Get-Content $Agents -ErrorAction Stop # If the file doesn't exist, or some other error occurs... } catch [System.Exception] { Write-Host "Error! $_`r`n" -ForegroundColor red # Tell us it was not OK and why. Make it red to stand out. Write-Host "Script completed with 1 error!" -ForegroundColor red # Confirm we encountered an error and make it red. Exit # Kill the script. Don't bother doing anything else. } # The following block of the script will apply to each line of the $Servers text file. Each line referred to as a $Server foreach ($Server in $Servers){ # Tell us what we're trying to do... Write-Host "Attempting to set password on $Server ... " -NoNewLine # Start trying to set the password... try { # Find out if the "Remote Registry" service is stopped or started $RRService = Get-Service -Name "Remote Registry" -ComputerName $Server -ErrorAction Stop # If the last command told us the service is stopped... if ( $RRService.Status -ne "Running" ) { # Start the service $RRService | Set-Service -Status Running -ErrorAction Stop # Set $RRServStopped to 1 to tell us we had to start the service $RRServStopped = 1 } # Connect to the remote registry of the requested $Server $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $Server) # Open the location where the password is stored on a 64-bit machine (HKLM\SOFTWARE\Wow6432Node\uptime software\up.time agent) # We check 64-bit first as we would like to think most machines are 64-bit $regKey = $reg.OpenSubKey("SOFTWARE\\Wow6432Node\\uptime software\\up.time agent",$true) # Set the value of "CmdsPassword" to whatever we asked the password to be $regKey.SetValue("CmdsPassword", "$Password", "String") # Check if we had to start the service earlier. If we did... if ( $RRServStopped -eq 1 ) { # Stop the service again. We don't want to leave it running as it was likely disabled for a reason Invoke-Command -ComputerName $Server -ScriptBlock { Stop-Service -Name "Remote Registry" -ErrorAction Stop } # Set $RRServStopped back to 0 $RRServStopped = 0 } # Tell us everything was OK! Make it a pretty green Write-Host "OK!" -ForegroundColor green # But if there was any errors, catch them. } catch [System.Exception] { # Check if the error said "You cannot call a method on a null-valued expression" # If it did, it means we asked it to set the value in the Wow6432Node area of a 32-bit machine # Wow6432Node does not exist on a 32-bit machine, so we need to try again somewhere else! if ($_ -match "You cannot call a method.*") { # Start to try setting the password again... try { #Find out if the "Remote Registry" service is stopped or started $RRService = Get-Service -Name "Remote Registry" -ComputerName $Server # If the last command told us the service is stopped... if ( $RRService.Status -ne "Running" ) { # Start the service $RRService | Set-Service -Status Running -ErrorAction Stop # Set $RRServStopped to 1 to tell us we had to start the service $RRServStopped = 1 } # Connect to the remote registry of the requested $Server $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $Server) # Open the location where the password is stopred on a 32-bit machine (HKLM\SOFTWARE\uptime software\up.time agent) $regKey = $reg.OpenSubKey("SOFTWARE\\uptime software\\up.time agent",$true) # Set the value of "CmdsPassword" to whatever we asked the password to be $regKey.SetValue("CmdsPassword", "$Password", "String") #Check if we had to start the service earlier. If we did... if ( $RRServStopped -eq 1 ) { # Stop the service again. We don't want to leave it running as it was likely disabled for a reason Invoke-Command -ComputerName $Server -ScriptBlock { Stop-Service -Name "Remote Registry" -ErrorAction Stop } # Set $RRServStopped back to 0 $RRServStopped = 0 } # Tell us everything was OK! Make it a pretty green Write-Host "OK!" -ForegroundColor green # But if an error is still received, tell us what the error was. } catch [System.Exception] { # Tell us everything was not OK and why. Make it red to stand out. Write-Host "ERROR! $_" -ForegroundColor red # Increase the number of errors encountered by 1 $errVal = $errVal + 1 } # But if we didn't receive "You cannot call a method on null-valued expression", then check # if we received a different error. This time, "Service 'Remote Registry (RemoteRegistry)' # cannot be configured due to the following error: Access is denied" # # If this was the error we received, it's quite a long error but could be common... } elseif ($_ -match "Service \'Remote Registry \(RemoteRegistry\)\' cannot be configured due to the following error: Access is denied") { # Tell us it was not OK and give us a shorter version of the actual error to make it a cleaner output. Make it red to stand out Write-Host "ERROR! Failed to start Remote Regsitry service. Access is denied" -ForegroundColor red # Increase the number of errors encountered by 1 $errVal = $errVal + 1 # We've captured the two common errors, so if it wasn't either of those errors, # then just output a generic error. } else { # Tell us it was not OK and why. Make it red to stand out Write-Host "ERROR! $_" -ForegroundColor red # Increase the number of errors encountered by 1 $errVal = $errVal + 1 } } } # Check if we encountered any errors. If we encountered just one error... if ( $errVal -eq 1 ) { # Tell us the script completed, but we received an error. Make it red to stand out. Write-Host "`r`nScript completed with $errVal error!" -ForegroundColor red # but if we received more than one error (this just handles "1 error" vs "1 errors")... } elseif ($errVal -gt 1 ) { # Tell us the script completed, but we received some errors. Make it red to stand out. Write-Host "`r`nScript completed with $errVal errors!" -ForegroundColor red # But if everything was OK (of course it was!)... } else { # Tell us everything completed successfully and make it a pretty green! Write-Host "`r`nScript completed successfully!" -ForegroundColor green } |