5

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?

Community
  • 1
  • 1

3 Answers3

8

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
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
7

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;
}
Community
  • 1
  • 1
3

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!

Cookie Monster
  • 1,741
  • 1
  • 19
  • 24
  • Just documenting on SO :) –  Mar 11 '14 at 17:26
  • Links can be helpful as supplemental information, but link-only answers are strongly discouraged [for these reasons](http://meta.stackexchange.com/a/8259/228805). You should include the code in your answer (adding the link is okay), otherwise this is really more of a comment than an answer. In its current form your post stands a good chance of being automatically flagged for the Low Quality Posts review queue and deleted. – Adi Inbar Mar 11 '14 at 18:51
  • @CookieMonster: Just wanted to give you a heads up that even though your `New-Object` syntax will technically work, it's deceiving because it looks like C# code, which PowerShell is definitely not. I made an edit to spell things out more clearly in PowerShell syntax. –  Mar 12 '14 at 17:33