How Can I Determine the SID for a User Account?

How Can I Determine the SID for a User Account?

  • Comments 12
  • Likes
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.


Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hello,

    Here command-line for the lazy IT guys

    Current domain-user:

    wmic path win32_useraccount where name="%username%" get sid

    Other domain-user

    wmic path win32_useraccount where name="xxxxxxx" get sid

    Regards,

  • Does anybody know whether this lines here

    strComputer = "."

    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

    Set objAccount = objWMIService.Get _

       ("Win32_SID.SID='S-1-5-21-1454471165-1004336348-1606980848-5555'")

    find the user, if he has another SID but this SID stored in his SIDHistory?

    It's a bit hard for me to try it out as I don't have any users where the SIDHistory is filled in and I didn't find an easy way to fill the attribute (which does not surprise me very much as that would give room to hijack someones identity).

    Does anybody know? Or do you have a domain with migrated users where the SIDHistory attribute is filled in and can try this out for me quickly?

    Thank your very much.

  • What do you type this script into and what do you save it is to make this code work? I'm brand new to any kind of scripting and I'm self teaching so I'm just trying to keep up. Thanks for any help I get guys.

  • @Chha I am not certain, but I do not believe that it will retrieve SID History. I cannot test that scenario, and that was not in the test matrix for the original article.

    @Stew14 The code shown here is VBScript code. We have an Excellent getting started with VBScript page that will walk you through the steps for using this code. The link is off of the Script Center home page.

    technet.microsoft.com/.../dd940112.aspx

    Hope this helps,

    ed wilson

    Microsoft Scripting Guy

  • Unfortunately that method won't work when using a locally cached profile of a Domain account...

  • Even lazier command-line (Win2k3 +)

    Whoami /user

  • @willig you are right. wmoami /user works great.

  • Your script does not work

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

    Windows Script Host

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

    Script : C:\Users\toto\Desktop\sid.vbs

    Ligne : 4

    Caract. : 1

    Erreur : Non trouvé

    Code : 80041002

    Source : SWbemServicesEx

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

    OK  

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

  • how do I replace the SID in this line with a variable from standard input ?

    ("Win32_SID.SID='S-1-5-21-1454471165-1004336348-1606980848-5555'")

    i.e

    ("Win32_SID.SID='inputvariable'")

    I want the user of the script to be able to enter the SID found in another application and be given the account name and domain.

  • Hello Scripting Guy!!

    This there any waywe can get the SID of a LOCal Account without using WMI?

  • @Vasudevan You can with PowerShell:

    ([System.Security.Principal.NTAccount]'username').translate([system.security.principal.securityidentifier])

  • Hello !

    You can also run this command :

    dsquery * -filter "&(objectcategory=user)(samaccountname=user_samaccountname)" -attr objectsid