Solved

How to set a service account password in PowerShell

Posted on 2016-10-31
13
84 Views
Last Modified: 2016-11-18
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

0
Comment
Question by:barnesco
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
  • 3
  • +1
13 Comments
 
LVL 69

Expert Comment

by:Qlemo
ID: 41867315
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.
0
 

Author Comment

by:barnesco
ID: 41867329
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.
0
 
LVL 69

Expert Comment

by:Qlemo
ID: 41867335
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.
0
Edgartown IT Case Study

Learn about Edgartown's quest to ensure the safety and security of the entire town's employee and citizen data. Read the case study!

 

Author Comment

by:barnesco
ID: 41867356
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

0
 
LVL 15

Expert Comment

by:Jason Crawford
ID: 41867472
$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/
0
 
LVL 4
ID: 41867509
$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()
1
 

Author Comment

by:barnesco
ID: 41869203
Same error--The service did not start due to a logon failure.
0
 
LVL 15

Expert Comment

by:Jason Crawford
ID: 41869263
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

0
 
LVL 4
ID: 41869281
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()
0
 
LVL 15

Expert Comment

by:Jason Crawford
ID: 41869325
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
0
 
LVL 69

Accepted Solution

by:
Qlemo earned 500 total points
ID: 41870542
Jason, that doesn't really help much. It adds some error handling and comfort, but it doesn't fix the issue.

Own observations:
In my tests, I was able to set the password with ReturnValue 0 no matter if
* the account has Log on as Service privilege
* the password is correct
the account name has been checked, however. The wrong password or missing privilege is resulting in a ResultValue of 15 when trying to start the service.
(Note: The service needs to be stopped prior to applying changes, otherwise they might not be reflected.)

Having assigned the Log on as Service privilege manually, the .Change works as expected. Wrong password = ReturnValue 15 on start, good password = ReturnValue 0 at start (ok).

So I was correct that the behaviour is the same if the password is wrong or the Log on as Service privilege missing,
but wrong about the .Change returning an error with a wrong password.

Further:
([ADSI]"WinNT://$computername,computer").GetObject('user', $username).UserFlags

Open in new window

does not reflect the Log on as Service privilege. After assigning the priv manually the UserFlags value did not change.
Reading more about it, the common suggestions are as stated in http://www.morgantechspace.com/2013/11/Set-or-Grant-Logon-As-A-Service-right-to-User.html, which either involves the usage of a custom DLL you can download, or the good old ntrights from one of the Windows Resource Kits.
1
 
LVL 15

Expert Comment

by:Jason Crawford
ID: 41870782
Impressive work as always Qlemo
0
 

Author Closing Comment

by:barnesco
ID: 41893496
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.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article will help you understand what HashTables are and how to use them in PowerShell.
The following article is intended as a guide to using PowerShell as a more versatile and reliable form of application detection in SCCM.
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

735 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question