Use PowerShell to Find User Profiles on a Computer

Summary: Learn how to use Windows PowerShell to find all user profiles on a computer, and to display the date when each profile was last used.

Hey, Scripting Guy! I would like to find a good way to see which profiles exist on my laptop. I found a Hey, Scripting Guy! post to do this, but it uses VBScript. Can this be done using Windows PowerShell?

—CW

Hello CW,

Microsoft Scripting Guy Ed Wilson here. A few years ago (actually more like six years ago), there was a Hey, Scripting Guy! Blog post entitled Hey, Scripting Guy! How Can I List All the User Profiles on a Computer? That post talks about enumerating a registry key to find the profile information. The registry location did not change in Windows 7, so the VBScript would still work. Here is the registry location:

The registry location viewed in the Registry Editor appears in the following figure.

Using Windows PowerShell, it is really easy to get and to display registry keys. I can enumerate the profile keys in a single command. However, due to the length of registry keys, I am going to do it in two lines. In the code that follows, I first store the path to the registry (using the HKLM Windows PowerShell drive) in a variable. Next, I use the Get-ChildItem cmdlet (dir is an alias) to list the registry profile keys:

Now that I have a listing of the profiles on the machine, I need to expand a couple of properties, such as ProfileImagePathand Sid. This should be a simple matter of using the Get-ItemProperty cmdlet to retrieve the nameproperty from the list above. When I do this, however, an error arises. The command and associated error are shown here.

There are actually two problems going on here. The first is that what is displayed under the Namecolumn in the default output from the Get-Childitem cmdlet is not the actual value stored in the actual nameproperty. The second problem is that even if that were fixed, the value HKEY_LOCAL_MACHINE that the nameproperty contains as part of the value is not the name of the Windows PowerShell drive used by the Get-ItemProperty cmdlet. I discovered this by piping the results of the Get-ChildItem command to the Format-List cmdlet (fl is an alias for Format-List) and analyzing the output. The following figure illustrates this process.

From the results discovered via Format-List, I ascertain I need to use the pspathproperty because it includes the registry provider. I can then pipe the results to the Select-Object cmdlet, and choose the ProfileImagePathproperty and the Sidproperty. This code and associated output are shown here (the % character is an alias for the Foreach-Object cmdlet and Select is an alias for the Select-Object cmdlet):

CW, that is an interesting excursion into working with the registry to retrieve user profile information. However, if it were me, I would just use Windows Management Instrumentation (WMI) instead. In fact, it returns even more information that is obtainable via the registry. Here is a simple command to return exactly the same information we just got from the registry (gwmi is an alias for the Get-WmiObject cmdlet):

gwmi win32_userprofile | select localpath, sid

The command and associated output are shown here:

PS C:\> gwmi win32_userprofile | select localpath, sid

localpath sid

--------- ---

C:\Users\Administrator S-1-5-21-1266540227-3509270964-2815946151-500

C:\Users\UpdatusUser S-1-5-21-1266540227-3509270964-2815946151-1001

C:\Users\edwils S-1-5-21-124525095-708259637-1543119021-179756

C:\Windows\ServiceProfiles\NetworkService S-1-5-20

C:\Windows\ServiceProfiles\LocalService S-1-5-19

C:\windows\system32\config\systemprofile S-1-5-18

If I run the WMI command with administrator rights, I can find the last time each profile was used. This information might be useful from a cleanup perspective. Here is the command to do that. Here are the aliases the following command uses:

PS C:\> Get-Alias gwmi, select, ft

CommandTypeNameDefinition

Alias gwmi Get-WmiObject

Alias select Select-Object

Alias ft Format-Table

Here is the code to get the user profiles, convert the time from WMI format to a regular date time value, and display the path and SID:

thanks for showing again, how easy we can access the registry and retrieve WMI (here we are again 🙂 information with powershell.

Though I still haven't fallen in love with the registry provider and its items and itemproperties this example is definitely simple and quite straight if you know that "PsPath" property is the key to success!

WMI is still becoming more and more a friend of mine!!!

And the real deal here is, apart from simplicity(!), that we have objects again!

And as you showed here, the resulting WMI object from "gwmi Win32_Userprofile" comes along with two ready to use script methods:

ConvertFromDateTime ScriptMethod System.Object ConvertFromDateTime();

ConvertToDateTime ScriptMethod System.Object ConvertToDateTime();

OK, you might argue that it would be even better, if we won't need to do the conversion between DateTime formats ourselves because Get-WMI could already have done that for us … but that depends on what we are going to do with the information later on and this conversion may be undesirable at times.

@Klaus Shulte You are welcome. Yes, I intended to just show the Registry portion, and then I just could not help myself and I felt I needed to contrast it with the WMI. In this case, in my mind, the WMI class is the hands down winner. And you are correct, the two convert* methods on the WMI object are way powerful and greatly simplify working with dates. Sure, it might be better if the Get-WmiObject automatically converted the date, except for those occasions when you need to provide a cim datetype BACK to another WMI class. In those cases, WMI requires the cim type … of course, there are converters for those as well …