Changing Service Passwords

Hi, I am new to posh. I was just recently asked to see if I can automate our “password rotation” process.

We have a dozen + servers all running various application services. Each of those has a number of services that support our Application. On a frequent basis, we have to go in and change the password on all those services … a real chore. Involves:

  1. Logging on to the server
  2. Pulling up the Services application
  3. Find the services we manage
  4. Right clicking on the service and selecting Properties
  5. Changing the password in two places
  6. Saving, getting out, and going to the next service

I think I have steps 1, 2, 3, & 6 figured out. I am stumped on #4 and #5.

Would anyone know what cmdlet or object I need to use to set the password? Would you have an example?

The manual way of achieving this is shown in my two attachments.

Thanks ahead of time for any help you can provide!

Tom

You could automate that, but you’d be reinventing the wheel to some degree. Before you go down that road, I’d recommend that you read up on the “Managed Service Accounts” feature of Active Directory. (or its newer version, “Group Managed Service Accounts”.) That may take care of your needs already.

They work basically just like computer accounts, where Windows and AD automatically change the password every so often without the need for explicit administrator intervention.

The Win32_Service class, accessible via WMI or CIM, has a Change() method that lets you designate a new password for a service. http://poshcode.org/92 shows an example of how you could use that in a function to automate password changes for services.

Great info … thanks Don!

Don,

 I saved the code from the link and ran it with the following invocation:
$service = 'Benefits Server Job Launcher: UATIWA'
$server  = 'vavt-bws-apu21'
$user    = 'NRECA\xxx'   # This is an admin user 
$pw      = '12345'

# Param     $server,  $service  , $user   ,  $password 
"C:\Posh_Scripts\Change-ServicePassword.ps1", $server  , $service  , $user  , $pw

I ran it with elevated privileges and I didn’t get any error. However, the only result was the echo of the text above, none of the write-hosts from inside the script.

Example:

C:\Posh_Scripts\Change-ServicePassword.ps1
vavt-bws-apu21
Benefits Server Job Launcher: UATIWA
NRECA\xxx
12345

I am not sure I am invoking the code correctly or if there is something else at work here. I even logged on to the remote server and ran the script locally … same results.

Any idea what I might be doing wrong?

Tom

If you want to call a script, the syntax would look like this:

C:\Posh_Scripts\Change-ServicePassword.ps1 $server  $service  $user  $pw

Note that there are no commas between the parameters; they’re space-separated, just like when you call cmdlets. In this case, you’re passing 4 different arguments positionally rather than using a named parameter (which would look something like -Server $server , etc)

You don’t need quotation marks around your script name unless it contains spaces. If you do put quotes around it, you also need to use the call operator:

& "C:\Posh_Scripts\Change-ServicePassword.ps1" $server  $service  $user  $pw

Otherwise PowerShell doesn’t see that string as something that’s supposed to be executed; it’s just a string.

Hi Dave, I took your suggestion as follows (note: this is a different path to the script after I moved it):

C:\REPOSITORY\Tmc1\_____POSH_Discovery\SCRIPTS\Change-ServicePassword.ps1 $server $service $user $pw

The result was:

ChangeServicePass : The term 'ChangeServicePass' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the 
spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\REPOSITORY\Tmc1\_____POSH_Discovery\SCRIPTS\Change-ServicePassword.ps1:51 char:12
+         if[ChangeServicePass -Srv $s -ms $service -usr $user -pwd $password]
+            ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: [ChangeServicePass:String] [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

I am running PowerShell v4 as Administrator. Apparently, it doesn’t like “ChangeServicePass” in the script. I copied the script to my computer verbatim. It is obviously finding the script otherwise it would not have complained about “ChangeServicePass”.

Any thoughts?

Tom

Yeah, that poshcode entry isn’t going to work as written. At the very least, the function definition and the call to it don’t match (ChangeServicePassword versus ChangeServicePass). It’s also using Write-Host, and doesn’t have any error handling, so I would probably not choose to use it without modifications anyway.

What it does have, though, is a nice example of how to call the Change method (assuming it works; I haven’t tested that code.)

Dave,

  I am a real newbie (had a course on posh and now I am just getting started). 

 [u][b]If[/b][/u] I did want to call the [u]function[/u][b]"ChangeServicePassword"[/b] contained in the PowerShell script file "C:\REPOSITORY\Tmc1\_____POSH_Discovery\SCRIPTS\[b]Change-ServicePassword.ps1[/b]",  how would I do it?  I understand a PS1 file can have multiple functions in it.  

It could be that I am trying to call the script file vs. the function. My class did not do a very good job of teaching how to call a function from a library of functions in an external PS1 file.

Thanks,

Tom

There’s a typo in the script. It defined a ChangeServicePassword function, but when it calls that function on line 51, it uses the name ChangeServicePass.

Aaron,

I changed line 51 as you suggested, but it still does not do anything. While I don’t get any errors, code execution is never getting to the “write-host”'s, and the password is not changed.

Given my parameters in my comment (October 8, 2014 at 8:41 am) above, could you please give me the syntax to call your function embedded in the PS1 file?
For clarity, assume that my PS1 file that contains your function is: C:\abc.ps1 How do I invoke the function from another script or interactively?

Thanks,

Tom

Ok … call me a dummy. I was invoking the function by putting commas between the parameters … my bad.

I would still like to know how one calls one of multiple functions that are in the same PS1 file.

Now I have the function running. I first use other code to stop the service, then I call the change password function, then I re-start the service

… however, the function comes back and tells me it failed.

I have a valid Domain Admin user … I am running the script with elevated privileges … I am able to get to the server and start/stop the service.

Question: what can I do to debug this function?

Quite a while ago I wrote a function for exactly this situation. It worked well for me.

[PRE]
Function Set-ServicePassword {
[CmdletBinding()]
Param (
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [String]$ComputerName,
[Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName)] [String]$ServiceName,
[Parameter()] [String]$AccountName,
[Parameter()] [String]$Password
)
Begin {
Function SetPassword ($HostName,$Service) {
Try {
$ServiceObject = Get-WmiObject -Class Win32_Service -ComputerName $HostName -Filter “Name=‘$($Service)’” -ErrorAction Stop
}
Catch {
Write-Warning “Error getting service ‘$($Service)’ on computer ‘$($HostName)’”
Write-Warning $_
Return
}
Try {
$ServiceObject.Change($Null,$Null,$Null,$Null,$Null,$Null,$AccountName,$Password) | Out-Null
}
Catch {
Write-Warning “Error setting service account for service ‘$($Service)’ on computer ‘$($HostName)’”
Write-Warning $_
Return
}
Write-Host “Changed service account for service ‘$($Service)’ on computer ‘$($HostName)’”
}
}
Process {
ForEach ($Computer in $ComputerName) {
SetPassword $Computer $ServiceName
}
}
End {
}
}
[/PRE]

Gilbert,

I ran your function using an authorized service account and a second time using one I made up. In both cases, it came back with:

Changed service account for service 'Benefits Server Assembly Updater: UATIWA' on computer 'vavt-bws-apu21'

In both cases, it failed to set the changed password. Any thoughts on what might be happening?

Thanks,

Tom