Link to home
Start Free TrialLog in
Avatar of barnesco
barnesco

asked on

How to set a service account password in PowerShell

The below script assigns an account to the service, but the password never seems to take, despite it being correct. I always have to manually reset the service account password in the services console. I'd like to be able to run the script so that the service has it's account and password set and restarted. Thanks.

$localaccount = ".\anAccount"
$newpassword = "strongPassword"
$strCompName = ""
$filter = "avbackup"

$service = Get-WmiObject win32_Service -Filter "Name='$filter'" 
$service.Change($null,$null,$null,$null,$null,$null,$localaccount,$newpassword)
$service.StopService()
  while ($service.Started){
    sleep 2
    $service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
  }
  $service.StartService()

Open in new window

Avatar of Qlemo
Qlemo
Flag of Germany image

Are you getting an error when calling .Change? If not, the password is set correctly, and you might need to assign the Log on as a Service privilege to the account used.
Avatar of barnesco
barnesco

ASKER

There's no error. The Log on as a Service privilege would be assigned when the service is restarted, but it won't restart due to an incorrect password (or so it thinks). That's why I have to reset the password and manually restart it myself.
I cannot see how the privilege should get assigned. Do you have other code for doing so, or are you using a group policy to do? "Would be assigned when the service is restarted" is not true without taking other actions.
I can't recall exactly, but the effects from this privilege missing might be the same as if you set a wrong password.
If it is the privilege, changing to a wrong password should report a script failure. Changing it back should succeed, and the password being set properly.
Here's what I run first to create the account and password:

$computername = $env:computername   # place computername here for remote access
$username = 'anAccount'
$password = 'StrongPassword'
$desc = 'Backup service account'


$computer = [ADSI]"WinNT://$computername,computer"
$user = $computer.Create("user", $username)
$user.SetPassword($password)
$user.Setinfo()
$user.description = $desc
$user.setinfo()
$user.UserFlags = 65536
$user.SetInfo()
$group = [ADSI]("WinNT://$computername/administrators,group")
$group.add("WinNT://$username,user")

Open in new window

$password = ConvertTo-SecureString 'StrongPassword' -AsPlainText -Force

Really though you should be storing your passwords in an encrypted fashion if they're being used in a script:

https://blog.kloud.com.au/2016/04/21/using-saved-credentials-securely-in-powershell-scripts/
$localaccount = ".\anAccount"
$newpassword = ConvertTo-SecureString "strongPassword" -AsPlainText -Force
$strCompName = ""
$filter = "avbackup"

$service = Get-WmiObject win32_Service -Filter "Name='$filter'"
$service.Change($null,$null,$null,$null,$null,$null,$localaccount,$newpassword)
$service.StopService()
  while ($service.Started){
    sleep 2
    $service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
  }
  $service.StartService()
Same error--The service did not start due to a logon failure.
I think you have to stop the service before attempting to change the password.  Try this:

$localaccount = ".\anAccount"
$newpassword = ConvertTo-SecureString "strongPassword" -AsPlainText -Force
$strCompName = ""
$filter = "avbackup"

$service = Get-WmiObject win32_Service -Filter "Name='$filter'"
$stop = $service.StopService()
if ($stop.returnvalue -eq 0) {
  $change = $service.Change($null,$null,$null,$null,$null,$null,$localaccount,$newpassword,$null,$null,$null)
  if ($change.returnvalue -eq 0) {
    Write-Host "The $filter service credentials were changed successfully" -ForegroundColor Green
  }
  else { 
    Write-Host "There was an error attempting to change the $filter service account credentials.  The error code was $($change.returnvalue)" -ForegroundColor Red
    break
  }
}
else {
  Write-Host "There was an error attempting to stop the $filter service.  The error code was $($stop.returnvalue)" -ForegroundColor Red
}

Open in new window

Says here that you cannot use a secure string for change method.,   Also It looks like there are 11 parameters.  Not sure you need $null identifying them all.   Meaning adding 3 more $nulls after the eighth. (which is for password.

https://mcpmag.com/articles/2015/01/22/password-for-a-service-account-in-powershell.aspx


$localaccount = ".\anAccount"
 $newpassword = ConvertTo-SecureString "strongPassword" -AsPlainText -Force
  $BSTR = [system.runtime.interopservices.marshal]::SecureStringToBSTR($newpassword)
  $newpassword = [system.runtime.interopservices.marshal]::PtrToStringAuto($BSTR)



 $strCompName = ""
 $filter = "avbackup"

 $service = Get-WmiObject win32_Service -Filter "Name='$filter'"
 $service.Change($null,$null,$null,$null,$null,$null,$localaccount,$newpassword)
 $service.StopService()
   while ($service.Started){
     sleep 2
     $service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
   }
   $service.StartService()
Man it looks like we're trying to reinvent the wheel.  There is already a script for this in the Gallery:

https://gallery.technet.microsoft.com/Powershell-How-to-change-be88ce7e
ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Impressive work as always Qlemo
Thank you. I've used the carbon.dll to remotely restart the account from another server, but I hadn't tried locally, so this will be the best solution. Thanks to everyone who contributed.