If you have multiple users sharing one computer with you, you may wonder how many users actually have the user profiles set up on your computer and where these user profiles are located. Here is a pretty cool way that lets you find out using PowerShell.
Running the following snippet in your PowerShell window and see what you get.
$path = 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' Get-ItemProperty -Path $path | Select-Object -Property PSChildName, ProfileImagePath
What it does is to retrieve the ProfileList info from Windows Registry and return each user’s SID and its profile location. Something like this:
Pretty neat, but it would be nice if we see the actual of the accounts instead of the SID. Basically, what we need to figure out is how to determine which account a SID belongs to. According to this Technet tip, we can use the following snippet to get the account name that a specified SID belongs to.
$objSID = New-Object System.Security.Principal.SecurityIdentifier("SID") $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) $objUser.Value
Basically, it creates a new instance of the SecurityIdentifier class with the SID in question, then uses the Translate method to convert this SID to an instance of the NTAccount.
So now, we need to implement this code into the first snippet that gets the info from the registry. Here is what I came up with, which you can download at the bottom of this post.
$path = 'Registry::HKey_Local_Machine\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\*' $items = Get-ItemProperty -path $path Foreach ($item in $items) { $objUser = New-Object System.Security.Principal.SecurityIdentifier($item.PSChildName) $objName = $objUser.Translate([System.Security.Principal.NTAccount]) $item.PSChildName = $objName.value } echo $items | Select-Object -Property PSChildName, ProfileImagePath
The result:
Of course, you can also use the built-in User Profiles dialog box to find the same or maybe more info but I have to admit that it’s pretty cool in PowerShell way, isn’t it?
/Update on August 27, 2018/
There is a better way that can get a list of user profiles on both local and remote computers, using the Get-WmiObject cmdlet with Win32_UserProfile, such as below to get the list of user profiles on the local computer.
Get-WmiObject -ClassName Win32_UserProfile
To get the same info from a remote computer,
Get-WmiObject -ClassName Win32_UserProfile -ComputerName computername
Moreover, to get the user profile used by the latest user.
Get-WmiObject -ClassName Win32_UserProfile -ComputerName computerame | Sort-Object LastUseTime | Select-Object -Last 1
Need to find the user account name and ID for that user profile?
Get-ADUser (Get-WmiObject -ClassName Win32_UserProfile -ComputerName computername | Sort-Object LastUseTime | Select-Object -Last 1).sid
I was wondering if you ever thought of changing the structure of your site? Its very well written; I love what youve got to say. But maybe you could a little more in the way of content so people could connect with it better. Youve got an awful lot of text for only having one or two images. Maybe you could space it out better?
What about for a remote computer?
Check the updated post.
Hi there, all is going well here and ofcourse
every one is sharing facts, that’s genuinely fine, keep up writing.
Excellent blog, there’s a typo in one of the snippets mind:
Get-WmiObject -ClassName Win32_UseProfile -ComputerName computerame | Sort-Object LastUseTime | Select-Object -Last 1
Should be Win32_UserProfile.
Get-WmiObject -ClassName Win32_UserProfile -ComputerName computerame | Sort-Object LastUseTime | Select-Object -Last 1
Indeed, thank you for pointing it out. 🙂
Thank you for this – worth calling out I think – your 2018 update is labeled “better” however some differences that I think are worth calling out and make it a bit more subjective – indeed these differences are what landed me here while trying to find a solution 🙂
– your first option can be run entirely local on a server and requires no ADDS access – e.g. can be run with an account that has no domain access.
– your first option can be run on a server that doesn’t have the AD module for powershell, which most servers will not by default.
– your first option (this really was the solution I was hunting) provides a way to seperate cached domain user profiles from local profiles, that works irrespective of connecting to AD. The bottom option, which it might be good for say… confirming a profile belongs to a disabled user, is not going to be able to tell you anything about a local user profile and thus programatically would appear the same as a deleted user.
All of which is to say, each option has value. In my case the best option is using the first registry based query to find defunct profiles, and user the .delete method of the WMI profile class to remove the matched-by-SID profiles. Thank you again for this post!
Nice, thank you for the feedback.
Thanks Kent. Very helpful post. However, I’m getting following error on the very last command.
“Get-ADUser : Cannot find an object with identity: ‘S-1-5-18’ under: ‘DC=au,DC=xxxxxxxxxx,DC=net,DC=au’.
At line:1 char:1”
Am I missing something here?
That isn’t an AD SID, so AD can’t find it.
try
[System.Security.Principal.SecurityIdentifier]::new(‘S-1-5-18’).Translate([System.Security.Principal.NTAccount]).Value
[System.Security.Principal.SecurityIdentifier]::new($item.SID).Translate([System.Security.Principal.NTAccount]).Value