PowerShell Problem Solver: Find Local User Accounts Using PowerShell

Posted on April 10, 2015 by Jeff Hicks in PowerShell with 0 Comments

I got a good question from a Petri reader on Twitter not long ago. I was asked about finding local user accounts on a list of servers. Seems like a reasonable task and something that PowerShell can handle quite nicely. If you merely want to enumerate local user accounts, WMI is a great place to start. We can use the Win32_UserAccount class.

You can use with Get-WMIObject or Get-CIMInstance. Using the latter is preferred these days as it uses the PowerShell remoting ports and is much more firewall friendly. With either cmdlet it is also very easy to list users from multiple computers.

When developing a PowerShell expression using WMI, I like to test locally first if at all possible. This ensures my syntax is correct.

Use the Get-CIMInstance cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

Use the Get-CIMInstance cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

That seemed pretty easy. My computer does not belong to a domain so the Domain property reflects the computername. As with most things in PowerShell, there is more here than meets the eye. I could re-run this command and pipe to Select-Object *, or I can use Get-CIMClass to discover the properties.

Obtaining properties in Windows PowerShell. (Image Credit: Jeff Hicks)

Obtaining properties in Windows PowerShell. (Image Credit: Jeff Hicks)

 

Once you know the properties, it is simple enough to include them.

Including the properties. (Image Credit: Jeff Hicks)

Including the properties. (Image Credit: Jeff Hicks)

 

Here’s a nice report with accounts grouped on whether they are disabled or not. I can repeat this process and specify a remote computer.

A report that displays grouped accounts. (Image Credit: Jeff Hicks)

A report that displays grouped accounts. (Image Credit: Jeff Hicks)

 

Since I knew I was going to format results as a table, I can omit the Select-Object portion of my expression. Of course in PowerShell if I can do something for one computer, I can do it for many.

I can do just about anything I want with the result from here. I can export to a CSV file, create an HTML report or re-format.

I’ve typed out the computer names, but you can get those values from anywhere, even a text list using Get-Content.

Or perhaps need to limit your search. Don’t pipe your command to Where-Object to filter. Instead take advantage of WMI filtering and do it at the source, i.e. the remote server.

Sponsored

This is especially important if you are querying many remote computers. Let’s say you want to find all the disabled local accounts. Again, test locally first.

WMI filters use the legacy operators like the = sign and instead of the PowerShell option $True or $False, you need to use the string. Now it is a simple matter to extend this to my list of computers.

Or perhaps I need to find all enabled local accounts other than Administrator.

Finding enabled accounts with Windows PowerShell. (Image Credit: Jeff Hicks)

Finding enabled accounts with Windows PowerShell. (Image Credit: Jeff Hicks)

 

I’ve been using Get-CIMInstace, which I think is the better choice. If necessary, you can also use Get-WMIObject. The syntax is identical.

Using the Get-wmiobject cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

Using the Get-wmiobject cmdlet in Windows PowerShell. (Image Credit: Jeff Hicks)

 

You get the same information, although technically this is a different type of object.

Sponsored

Before we wrap up, let me point out that if you query a domain controller you will get domain accounts.

Querying a domain controller in Windows PowerShell. (Image Credit: Jeff Hicks)

Querying a domain controller in Windows PowerShell. (Image Credit: Jeff Hicks)

 

Sometimes this can be useful, but if your goal is to identify local user accounts on domain members, you’ll need to make sure no domain controllers are in your list. By the way, if you need to use alternate credentials, you will need to create CIMSessions for each remote computers. My examples have been ad-hoc with PowerShell setting up and tearing down temporary CIMSessions.

Now I have a collection of CIMSessions, which I can use like this:

And because I can reuse these sessions, subsequent CIM commands run much faster.

With a single command I created a CSV report of enabled local accounts. I could set this up as a PowerShell scheduled job to audit local accounts on a monthly basis, send them via email, or log them to a SQL database. Once you understand some PowerShell fundamentals and grasp the power of the pipeline, you’ll be amazed at what you can accomplish.

Sponsored

Tagged with , , , ,