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()
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.
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.
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.
ASKER
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")
$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/
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,$nul l,$null,$n ull,$null, $null,$loc alaccount, $newpasswo rd)
$service.StopService()
while ($service.Started){
sleep 2
$service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
}
$service.StartService()
$newpassword = ConvertTo-SecureString "strongPassword" -AsPlainText -Force
$strCompName = ""
$filter = "avbackup"
$service = Get-WmiObject win32_Service -Filter "Name='$filter'"
$service.Change($null,$nul
$service.StopService()
while ($service.Started){
sleep 2
$service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
}
$service.StartService()
ASKER
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
}
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.interopser vices.mars hal]::Secu reStringTo BSTR($newp assword)
$newpassword = [system.runtime.interopser vices.mars hal]::PtrT oStringAut o($BSTR)
$strCompName = ""
$filter = "avbackup"
$service = Get-WmiObject win32_Service -Filter "Name='$filter'"
$service.Change($null,$nul l,$null,$n ull,$null, $null,$loc alaccount, $newpasswo rd)
$service.StopService()
while ($service.Started){
sleep 2
$service = Get-WMIObject -ComputerName $strCompName -namespace "root\cimv2" -class Win32_Service -Filter $filter
}
$service.StartService()
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.interopser
$newpassword = [system.runtime.interopser
$strCompName = ""
$filter = "avbackup"
$service = Get-WmiObject win32_Service -Filter "Name='$filter'"
$service.Change($null,$nul
$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
https://gallery.technet.microsoft.com/Powershell-How-to-change-be88ce7e
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Impressive work as always Qlemo
ASKER
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.