Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET!
PowerShell

PowerShell Problem Solver: Use PowerShell to Find Non-System Service Accounts

A common task for many IT Pros is to keep tabs on service accounts. That is the say, the account that a service runs under. For the majority of services, this account is determined automatically and is something like LocalSystem or LocalService. But sometimes there is a need to run a service under a local user account or even a domain account. It is important to know where those accounts are being used so you can coordinate password changes. Of course, you don’t want to have to navigate the Services management console to find these accounts. PowerShell can make this a pretty easy task.

If you are new to PowerShell you might first think to use the Get-Service cmdlet. Sadly, this cmdlet doesn’t expose the service account information.

Use PowerShell to Find Non-System Service Accounts

As you can see there are no properties to indicate the service account. Fortunately, this information is found using WMI. Let’s get the same service and look at all of the properties to discover the correct property name.

Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

get-wmiobject win32_service -filter "Name = 'mssqlserver'" | select *

I’ve highlighted the relevant property name.

Now that I know the property name I can filter and work with it. For example, you may want to know what service accounts are in use on a given computer.

Get-CimInstance win32_service | Group StartName

I switched to the Get-CimInstance cmdlet to query the same WMI information. And even though my examples are searching locally, it is just easy to search one or more remote computers.

But what I really want is to identify that service running under .\Jeff which is a local user account. It could just as easily be a domain account. So I need to filter out anything that is LocalSystem, LocalService or NetworkService. You might be tempted to try an expression like this:

Get-CimInstance win32_service | where { $_.startname -notmatch 'LocalSystem|^NT Authority'} | Select Name,Displayname,Start*,State

Yes, this works, but is not a best practice especially if you are querying multiple remote computers. This is an example of late-filtering. I am retrieving all of the services and then filtering for the startname. The better approach is to use filtering with Get-CimInstance, or Get-WMIObject. Although I’ll admit the syntax can get a little tricky.

Get-CimInstance win32_service -filter "NOT (startname LIKE 'NT Authority%' OR startname LIKE 'LocalSystem')" | group startname

I suppose if I were looking for a specific account name that would be easier. But instead I am filtering out all non system service accounts. Here’s how I might search multiple remote computers.

Get-CimInstance win32_service -filter "NOT (startname LIKE 'NT Authority%' OR startname LIKE 'LocalSystem')" -computername chi-dc01,chi-dc02,chi-dc04,chi-core01,chi-hvr2,chi-fp02 | Select Name,Displayname,Start*,State,PSComputername

I have one service running under the domain administrator account, which is probably not a good thing. So I might as well change the account name. Or you might want to change the password if it is a legitimate service account.

The Set-Service cmdlet won’t work in this case. Again, we need to turn to WMI and the Change() method from the Win32_Service class.

$c = get-cimclass win32_service
$c.cimclassmethods["change"].parameters

Once you know the property names, using Invoke-CimMethod is pretty easy.

get-ciminstance win32_service -filter "Name='SharedAccess'" -computer chi-core01 | 
Invoke-CimMethod -Name Change -Arguments @{Startname="LocalSystem";StartPassword="[email protected]"}

Checking the service again, I can see the new service account.

Note that if the service had been running you may have needed to restart it for changes to take effect. You could have used Restart-Service or the WMI methods.

When solving a problem like this with PowerShell, I encourage you to start small and work locally. Once your syntax is under control, it is generally a pretty simple task to scale your command out.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.

RSVP Now

Sponsored By