Updating RunAs Service Accounts (passwords) Remotely

Facebook
Twitter
LinkedIn
Email

It’s that time of year – for me, anyway – the time of year when all of our Domain Service Account(s) passwords expire.


Side note: We did a security overhaul last year when the zero-day Exchange vulnerability CVEs CVE-2021-26855, CVE-2021-26857, CVE-2021-26858 and CVE-2021-27065 became wide-spread. I finally convinced our IT Management to reset Admin accounts, remove dated accounts and enable MFA for all Sys Admins.
Consequences be damned, we did it and fixed the services configured to use service accounts 20 years ago, and the initial pains were worth it – I would recommend any organization do it ASAP (and this script will help).


Which brings me to this year, when dozens of service accounts are scheduled to expire and it’s time to go change all of them 1-by-1.


PowerShell to the rescue!

The following script takes care of all this time-consuming work for you.

It will 1) import a CSV from the current directory containing the username,passwords of the service accounts you are changing, 2) search all Domain Computers (based on your OU of choice), 3) find what services are configured to use any of the usernames in the CSV, 4) apply the new password of the associated service account, 5) restart the services.

The script requires two configurable variables:

  1. The Domain OU Structure you wish to search
  2. The name of a CSV containing the updated Service Account Usernames and Passwords.

As a fail-safe, the script will display your configured variables and ask to confirm before execution, giving you the opportunity to open/edit the file directly from the PowerShell window to make changes.

cls

$SearchOU = "OU=SQL,OU=Servers,DC=molloy,DC=rocks" # Where to search in Active Directory for servers which might be using Service Accounts
$CSVName = "ServiceAccounts.csv" # Name of the local CSV file to be imported. 


# DO NOT EDIT BEYOND THIS LINE

Echo `n 
write-host "You are using CSV File " -f cyan -nonewline 
write-host ".\$CSVName" -f red -nonewline
write-host " and searching Active Directory OU and sub-OUs " -f Cyan -NoNewline
Write-Host "'$SearchOU'" -f red -NoNewline
Write-Host " for Service Accounts to update automatically." -f Cyan
Echo `n 
Write-Host "Please verify all variables before proceeding!" -foregroundcolor red

$ans1 = Read-Host "Do you want to change the OU or check your variables before continuing? [Y/N]"
if ($ans1 -eq "Y"){
powershell_ise.exe .\UpdateAccounts.ps1}
elseif ($ans1 -eq "N"){ 

$ans2 = Read-Host "Confirm execution [Y/N]"
if ($ans2 -eq "N"){
Read-Host -Prompt "Invalid response or execution aborted."
exit}
elseif ($ans2 -eq "Y"){ 

# GO time.


$CSV = Import-CSV .\$CSVName

Import-Module ActiveDirectory
Get-ADComputer -Filter {(Enabled -eq $True)} -Searchbase $SearchOU | Select Name | ForEach {
    $computerName = $_.Name
     Write-Host "----"


Echo "Searching $computerName for Service Accounts"
  
Invoke-Command -ComputerName $Computername -ScriptBlock { 


foreach ($user in $Using:CSV) {
    $acct = $user.acct
    $pass = $user.pass

    foreach($a in $acct){
$Service = Get-WmiObject -Class Win32_Service -Filter  "StartName LIKE '%\\$a' OR  StartName LIKE '$a@%'"

if ($Service.Name) { 

foreach ($c in $Service.Name) {

$svc_Obj= Get-WmiObject Win32_Service -filter "name='$($c)'"


$StopStatus = $svc_Obj.StopService() 
If ($StopStatus.ReturnValue -eq "0") {
Write-host "The service '$Service' Stopped successfully on $Using:Computername" -f Green
} Else { 
Write-host "Failed to Stop the service '$Service'. Error code: $($StopStatus.ReturnValue)" -f Red
}
 
Start-Sleep -Seconds 10

$ChangeStatus = $svc_Obj.change($null,$null,$null,$null,$null,
                      $null, $null,$pass,$null,$null,$null)
If ($ChangeStatus.ReturnValue -eq "0")  {
Write-host "Log on account updated sucessfully for the service '$Service'" -f Green
} Else {
Write-host "Failed to update Log on account in the service '$Service'. Error code: $($ChangeStatus.ReturnValue)" -f Red
}
Start-Sleep -Seconds 10

$StartStatus = $svc_Obj.StartService() 
If ($StartStatus.ReturnValue -eq "0")  {
Write-host "The service '$Service' Started successfully" -f Green
} Else {
Write-host "Failed to Start the service '$Service'. Let's try again..." -f Red
$StartStatus = $svc_Obj.StartService() 
If ($StartStatus.ReturnValue -eq "0")  {
Write-host "The service '$Service' Started successfully" -f Green
} Else {
Write-host "Failed to Start the service '$Service' AGAIN! Error code: $($StartStatus.ReturnValue)" -f Red
}
}

}
Echo `n
Echo `n
Echo `n
Write-host "The following Service Account Passwords have been changed on $Using:Computername" -f Green
$Service | Select Name, StartName, State 
Echo `n
}

}
} 

}}}}

 
 Read-Host -Prompt "Process complete! Review the output and manually verify service states as necessary." 

The result?

BlueIris Services reset after successful RunAs service account password change.

All services with a RunAs account listed in the CSV have had their passwords changed on all servers in the Domain OU (one here for testing).


Combined this with my Scheduled Task RunAs script and I am good for another year!


Let me know if I am helping.

Was this helpful?

More to explorer

Updating Scheduled Task (accounts) Remotely

It’s that time of year – for me, anyway – the time of year when all of our Domain Service Account(s) passwords expire, and for me that means changing dozens of scheduled task RunAs accounts.

Switch Port Discovery Tools

Have you ever been out in the field and needed to know what port a device is plugged into? Perhaps you cannot

Leave a comment

Your email address will not be published. Required fields are marked *