Using PowerShell, you can easily query many computers at once and set the service logon account on all of them!

A few years ago I was in a position where I was to implement a new Active Directory password policy. All employee user passwords were to begin expiring after 6 months. I had all the 10,000 Active Directory accounts accounted for. I had tagged all user accounts that I thought should be used for services and all that were employees.

Proper notification was sent out to the entire IT department asking if any employee user accounts were running services on any of the servers. Nope!

The password policy was implemented and the help desk lit up. Why? There were dozens of services on servers running as employee user accounts that had gotten expired! In hindsight, I shouldn't have taken their word for it and queried all the servers myself but you live you learn. My solution was to throw together this script to set the service logon account with PowerShell.

This script loops through all of the services in the CSV, connects to the server in question, changes the service account, stops the service and then restarts the service to ensure the change is committed. This was written a few years ago so I'm not using Get-CimInstance instead of Get-WmiObject among a few other things.

Although, it should still work great for anyone that may be in a similar position I was.

Function ChangeServiceAccount($sServiceName,$sComputerName,$sUsername,$sPassword) {
	$oService = Get-WmiObject -ComputerName $sComputerName -Query "SELECT * FROM Win32_Service WHERE Name = '$sServiceName'"
	$oService.Change($null,$null,$null,$null,$null,$null,"$sUsername",$sPassword) | Out-Null
	$oService.StopService() | Out-Null
	while ($oService.Started) {
		sleep 1
		$oService = Get-WmiObject -ComputerName $sComputerName -Query "SELECT * FROM Win32_Service WHERE Name = '$sServiceName'"
	}##endwhile
	$oService.StartService() | Out-Null
}##endfunction

if (!$sCsvFile) {
	Write-Error 'No CSV file specified' -RecommendedAction 'Please specify CSV file as first parameter'
} elseif (!(Test-Path $sCsvFile)) {
	Write-Error "CSV file '$sCsvFile' not found";
} elseif ((gc $sCsvFile | select -First 1) -ne 'Service,Server,Username,Password') {
	Write-Error "CSV headers are incorrect.  They must be 'Service,Server,Username,Password'"
} else {
	$aRows = Import-Csv $sCsvFile;
	foreach ($oRow in $aRows) {
    	## Set service logon account PowerShell
		changeServiceAccount $oRow.Service $oRow.Server $oRow.Username $oRow.Password
		Write-Host "Changed service account $($oRow.Service) on $($oRow.Server) to $($oRow.Username) and restarted service"
	}##endforeach
}##endif

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!