Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

I SID You Not!

Posted on March 11, 2022March 11, 2022

As usually happens during my day, I get sidetracked to another issue, and before you know it, I have a new PowerShell tool. In this instance, I was looking at event logs using Get-WinEvent. One of the event record properties is a UserID.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!
Sample SID

That's very nice, but who is this? In this particular instance, the UserID property is SecurityIdentifier object.

System.Security.Principal.SecurityIdentifier

To resolve the SID, you can use the Translate() method.

translate sid

Nice. I can take this a step further to get a simple string.

$a.userid.Translate([system.security.principal.ntaccount]).value

But what if I only have the SID value as a string? You might encounter this in plain text log files.

sample SID string

How do I resolve this?

It is actually pretty easy. I can create a SecurityIdentifier object from the string.

[System.Security.Principal.SecurityIdentifier]::new($sid)

This gives me the object with the Translate() method.

convert SID string to object

It is not required, but I can resolve the SID as a string with a single expression.

[System.Security.Principal.SecurityIdentifier]::new($sid).Translate([system.security.principal.NTAccount]).value
resolving a SID string

Creating a PowerShell Tool

Naturally, the next step is to create a PowerShell tool to simplify the entire process and add a touch of extra value.

Function Resolve-SID {
    [cmdletbinding()]
    [OutputType("ResolvedSID", "String")]
    Param(
        [Parameter(
            Position = 0,
            Mandatory,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            HelpMessage = "Enter a SID string."
        )]
        [ValidateScript({
            If ($_ -match 'S-1-[1235]-\d{1,2}(-\d+)*') {
                $True
            }
            else {
                Throw "The parameter value does not match the pattern for a valid SID."
                $False
            }
        })]
        [string]$SID,
        [Parameter(HelpMessage = "Display the resolved account name as a string.")]
        [switch]$ToString
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converting $SID "
        Try {
            if ($SID -eq 'S-1-5-32') {
                #apparently you can't resolve the builtin account
                $resolved = "$env:COMPUTERNAME\BUILTIN"
            }
            else {
                $resolved = [System.Security.Principal.SecurityIdentifier]::new($sid).Translate([system.security.principal.NTAccount]).value
            }

            if ($ToString) {
                $resolved
            }
            else {
                if ($resolved -match "\\") {
                    $domain = $resolved.Split("\")[0]
                    $username = $resolved.Split("\")[1]
                }
                else {
                    $domain = $Null
                    $username = $resolved
                }
                [pscustomObject]@{
                    PSTypename = "ResolvedSID"
                    NTAccount  = $resolved
                    Domain     = $domain
                    Username   = $username
                    SID        = $SID
                }
            }
        }
        Catch {
            Write-Warning "Failed to resolve $SID. $($_.Exception.InnerException.Message)"
        }
    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end

} #close Resolve-SID
resolve a sid with a PowerShell function

At the core, my function uses the one-line resolution code. I'm parsing the result to create a richer object. Although, I included a ToString parameter.

resolving sid as an account string

This makes it easier to use the result in your messaging or logging.

The other item of interest in the function is the parameter validation for the SID. I'm using a regular expression pattern to verify that the value looks like a SID.

SID parameter validation

The regular expression pattern should take into account built-in SIDs as well.

resolving sids via the PowerShell pipeline

By the way, my function writes a typed object to the pipeline so you could create a format ps1xml file.

The only issue I encountered was resolving the BUILTIN SID of S-1-5-32. This was the only valid SID I found that my code failed to resolve. Instead, I handle this is with a simple IF statement.

if ($SID -eq 'S-1-5-32') {
    #apparently you can't resolve the builtin account
    $resolved = "$env:COMPUTERNAME\BUILTIN"
}
else {
    $resolved = [System.Security.Principal.SecurityIdentifier]::new($sid).Translate([system.security.principal.NTAccount]).value
}

If there is any other error trying to resolve the SID, I'll handle it in the Catch block and write a warning.

failing to resolve a SID

I have no doubt there are other tools to resolve SIDs and my function is by no means the only PowerShell solution you'll find. I'd love to hear what you think.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

7 thoughts on “I SID You Not!”

  1. Pingback: I SID You Not! - The Lonely Administrator - Syndicated Blogs - IDERA Community
  2. Murat Yildirimoglu says:
    March 14, 2022 at 3:35 pm

    Nice article as usual.
    Instead of [System.Security.Principal.SecurityIdentifier]::new($sid).Translate([system.security.principal.NTAccount]).value
    it seems that we can use [System.Security.Principal.SecurityIdentifier]::new($sid).Translate([system.security.principal.NTAccount]) only.

    1. Jeffery Hicks says:
      March 14, 2022 at 3:41 pm

      Probably. PowerShell is pretty good at figuring out what you want. But I wanted to ensure the result was a simple. Although, I could also have used System.Security.Principal.SecurityIdentifier]::new($sid).Translate([system.security.principal.NTAccount]).toString() to achieve the same end result.

  3. Pingback: Working with SIDs in Powershell – Curated SQL
  4. Pingback: PowerShell SnippetRace 12/13-2022 | PowerShell Usergroup Austria
  5. kavya says:
    May 23, 2022 at 7:22 am

    Steps explained v clearly. However I keep running into the below error- The same script works well on a coworker’s system. Not sure what i’m missing here.
    Exception calling “Translate” with “1” argument(s): “Some or all identity references could not be translated.”
    At line:6 char:1
    + $name = ([System.Security.Principal.SecurityIdentifier] $nm.Name).Tra …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IdentityNotMappedException

    1. Jeffery Hicks says:
      May 23, 2022 at 9:53 am

      You can run into a problem if the SID belongs to a domain and you are in a workgroup, or vice versa.

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d