This question is inspired by this similar question using the C# tag. If I have a Windows SID, and would like to convert it to a readable account name, how can I achieve this using PowerShell instead of C#?
Right now, I have the following code, which retrieves the group memberships for the currently logged on user account:
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$Identity.Groups;
The results of the Groups
property does not give me any account names, only SIDs. If I pipe the output from the Groups
property into PowerShell's Get-Member
cmdlet, I can see that the resulting objects are System.Security.Principal.SecurityIdentifier
objects. However, looking at the documentation (and Intellisense) for the Groups
property shows that it is returning an IdentityReferenceCollection
object.
How do I convert these SecurityIdentifier
objects into proper names?
One way of resolving SIDs to account names is using the Win32_SID
class:
PS C:\> $sid = 'S-1-5-18'
PS C:\> [wmi]"Win32_SID.SID='$sid'"
__GENUS : 2
__CLASS : Win32_SID
__SUPERCLASS :
__DYNASTY : Win32_SID
__RELPATH : Win32_SID.SID="S-1-5-18"
__PROPERTY_COUNT : 5
__DERIVATION : {}
__SERVER : CARBON
__NAMESPACE : root\cimv2
__PATH : \\CARBON\root\cimv2:Win32_SID.SID="S-1-5-18"
AccountName : SYSTEM
BinaryRepresentation : {1, 1, 0, 0...}
ReferencedDomainName : NT-AUTHORITY
SID : S-1-5-18
SidLength : 12
PSComputerName : CARBON
The solution is to use the Translate()
method of the SecurityIdentifier
class. The single parameter for this method is a reference to the .NET type that you would like to convert the SecurityIdentifier
to. If you examine this answer to the similar C# question, you will see that you can simply pass in a reference to the System.Security.Principal.NTAccount class.
The resulting code would look something like this:
$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent();
foreach ($Group in $Identity.Groups) {
$Group.Translate([System.Security.Principal.NTAccount]).Value;
}
Looks like you have the answer already - I wrote a wrapper a short while back that also searches a list of well known SIDs, if it helps. ConvertFrom-SID
A generic way you could pull this out would be as follows, where $sid holds a SID string:
$sid = '<SIDGoesHere>';
$objSID = New-Object -TypeName System.Security.Principal.SecurityIdentifier -ArgumentList $sid;
$name = $objSID.Translate([System.Security.Principal.NTAccount]).Value;
Cheers!