How Can I Determine the SID for a User Account?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I determine the SID for a user account?

— MD

SpacerHey, Scripting Guy! AnswerScript Center

Hey, MD. For those of you whose eyes glaze over any time they see an acronym (not that we blame you), SID is short for Security Identifier. A SID is a unique ID string (e.g., S-1-5-21-1454471165-1004336348-1606980848-5555) that is assigned to each account created in a domain or on a local computer. For our purposes, we’ll just say that SID is how the operating system keeps track of accounts. For example, you can rename the Administrator account on a computer and still use that account to function as an administrator because Windows doesn’t really care what the name is; Windows still knows that this account is the Administrator account because the SID remains the same regardless of the account name. It’s like your Social Security Number which – assuming you haven’t had your identify hijacked – uniquely identifies you regardless of the name you go by.


Most of the time you don’t need to worry about SIDs, which is good: obviously it’s easier to deal with an account name like kenmyer than it is to deal with a SID like S-1-5-21-1454471165-1004336348-1606980848-5555. However, there are times when it’s useful to know which SID goes with which user account. WMI’s security classes, for example, rely on SIDs; likewise, the Windows registry tracks user profiles by SID rather than by name (take a look at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList to see what we mean). You might be able to live your entire scripting life without ever needing to know a user’s SID. But, then again ….


So how do we find a user’s SID? Well, we use a script similar to this, which returns the SID for the user kenmyer with an account in the fabrikam domain:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set objAccount = objWMIService.Get _
(“Win32_UserAccount.Name=’kenmyer’,Domain=’fabrikam'”)
Wscript.Echo objAccount.SID


As you can see, the SID is practically longer than the script. All we do here is connect to the WMI service, and then use the Get method to bind to a specified instance of the Win32_UserAccount class. Notice we don’t use ExecQuery and return a collection of all the SIDs in our domain; that won’t work. Instead, we have to use Get and specify a particular user account. After that, it’s simply a matter of echoing the SID, which we do in the last line of the script.


Incidentally, this works just as well for local user accounts. The only difference is that you don’t specify a domain name for the Domain parameter; instead, you specify the name of the local computer. For example, this script returns the SID for the local user account kenmyer on the computer atl-ws-01:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set objAccount = objWMIService.Get _
(“Win32_UserAccount.Name=’kenmyer’,Domain=’atl-ws-01′”)
Wscript.Echo objAccount.SID


Pretty slick, huh?


Of course, it’s possible that you might need to go the other direction; that is, you might have a SID and need to know which account that SID belongs to. Can you do that? Of course you can:

strComputer = “.”
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)

Set objAccount = objWMIService.Get _
(“Win32_SID.SID=’S-1-5-21-1454471165-1004336348-1606980848-5555′”)
Wscript.Echo objAccount.AccountName
Wscript.Echo objAccount.ReferencedDomainName


The big difference here is that instead of getting an instance of the Win32_UserAccount class we get an instance of the Win32_SID class (and note that we pass the SID as the parameter to the Get method). As soon as we’ve retrieved that instance, we echo the account name and domain name, and we’re off and running.