Changing Service Passwords

This topic contains 13 replies, has 5 voices, and was last updated by Profile photo of Tom Carnahan Tom Carnahan 2 years, 1 month ago.

  • Author
    Posts
  • #19500
    Profile photo of Tom Carnahan
    Tom Carnahan
    Participant

    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

  • #19501
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

  • #19507
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

    • #19512
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

      Great info ... thanks Don!

    • #19514
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

      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

  • #19515
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

    • #19523
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

      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

  • #19527
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.)

    • #19549
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

      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

  • #19577
    Profile photo of Aaron Jensen
    Aaron Jensen
    Participant

    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.

    • #19579
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

      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: [b]C:\abc.ps1[/b] How do I invoke the function from another script or interactively?

      Thanks,

      Tom

    • #19582
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

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

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

      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, [u]the function comes back and tells me it failed.
      [/u]

      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.

      [b]Question: [/b] what can I do to debug this function?

  • #19583

    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]

    • #19637
      Profile photo of Tom Carnahan
      Tom Carnahan
      Participant

      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

You must be logged in to reply to this topic.