Working with Windows Virtual Desktop and Azure VMs at the moment so I needed to be able to identify local machine users by SID so wrote the following cmdlet to conveniently query for the a user in a specific domain, defaulting to the current user if no parameters are specified.

GetUserSid.ps1


[CmdletBinding()]            
Param(            
    [Alias("User","UserName","Identity")]            
    [string]$UserAccount = $env:USERNAME,            
    [string]$Domain = $env:USERDOMAIN            
)            

$User = [System.Security.Principal.NTAccount]::new($Domain, $UserAccount)            
$Ident = $User.Translate([System.Security.Principal.SecurityIdentifier])            

New-Object –TypeName PSObject –Prop ( @{
    UserName = $UserAccount            
    Domain = $Domain            
    SID = $Ident.Value
})            

Another way of doing this to get more complete information is to instantiate a WindowsIdentity object using [System.Security.Principal.WindowsIdentity]::GetCurrent(). As well as SID, user name, this object includes the groups they are members of, the identity claims, and information about the authentication type.

Conversely, given a user Sid (say from Get-ADUser), we can reconstruct the user like this:

GetUserFromSid.ps1


[CmdletBinding()]            
Param(            
    [string]$Sid      
)            

$SecurityIdent = New-Object System.Security.Principal.SecurityIdentifier $Sid

$User = $SecurityIdent.Translate( [System.Security.Principal.NTAccount]) 

$UserAccount = $User.Value
$Domain = ''

If ($UserAccount.Contains('\')) {
    $Chunks = $User.Value.Split('\')
    $Domain = $Chunks[0]
    $UserAccount = $Chunks[1]
}


New-Object –TypeName PSObject –Prop ( @{
    UserName = $UserAccount            
    Domain = $Domain            
    SID = $Sid
})