I have the user's SID as byte[]
within windowsPrincipal.getIdentity().getSid()
.
How can I get an Active Directory entry (DirectoryEntry) from the SID?
Asked
Active
Viewed 1.6k times
9
4 Answers
11
Use the SecurityIdentifier class to convert the sid from byte[] format to string and then bind directly to the object:
DirectoryEntry OpenEntry(byte[] sidAsBytes)
{
var sid = new SecurityIdentifier(sidAsBytes, 0);
return new DirectoryEntry(string.Format("LDAP://<SID={0}>", sid.ToString()));
}

Mathew Leger
- 1,613
- 17
- 22
4
I found this example in c#
// SID must be in Security Descriptor Description Language (SDDL) format
// The PrincipalSearcher can help you here too (result.Sid.ToString())
public void FindByIdentitySid()
{
UserPrincipal user = UserPrincipal.FindByIdentity(
adPrincipalContext,
IdentityType.Sid,
"S-1-5-21-2422933499-3002364838-2613214872-12917");
Console.WriteLine(user.DistinguishedName);
}
Converted to VB.NET:
' SID must be in Security Descriptor Description Language (SDDL) format
' The PrincipalSearcher can help you here too (result.Sid.ToString())
Public Sub FindByIdentitySid()
Dim user As UserPrincipal = UserPrincipal.FindByIdentity(adPrincipalContext, IdentityType.Sid, "S-1-5-21-2422933499-3002364838-2613214872-12917")
Console.WriteLine(user.DistinguishedName)
End Sub
Obviously you can then:
dim de as new DirectoryEntry("LDAP://" & user.DistinguishedName)
To get the SID = S-1-5-21-* (sorry VB.NET)
' Convert ObjectSID to a String
' http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/57452aab-4b68-4444-aefa-136b387dd06e
Dim ADpropSid As Byte()
ADpropSid = de.Properties("objectSid").Item(0)
' in my test the byte field looks like this : 01 02 00 00 00 00.......37 02 00 00
Dim SID As New System.Security.Principal.SecurityIdentifier(ADpropSid, 0)
I haven't tested the C# or used the converted version yet myself, but have used the above to return the SID in SDDL format.

Nick Giles
- 562
- 1
- 6
- 15
-
wow you and i have different definitions of "obvious". Why can you do a query on `"LDAP://" & user.DistinguishedName` like that? Don't you need to specify hostname etc? Does that require you are on the same machine that has active directory access? – Nicholas DiPiazza Apr 19 '18 at 16:24
2
The easiest way I've found is using LDAP binding. Similar to what Nick Giles said. More info at MSDN
''' <summary>
''' Gets the DirectoryEntry identified by this SecurityIdentifier.
''' </summary>
''' <param name="id">The SecurityIdentifier (SID).</param>
<System.Runtime.CompilerServices.Extension()> _
Public Function GetDirectoryEntry(ByVal id As SecurityIdentifier) As DirectoryEntry
Const sidBindingFormat As String = "LDAP://AOT/<SID={0}>"
Return New DirectoryEntry(String.Format(sidBindingFormat, id.Value))
End Function

j.i.h.
- 815
- 8
- 29
1
This can also be done in PowerShell, as long as you have .Net 3.5 or 4.0 available (see https://gist.github.com/882528 if you don't by default)
add-type -assemblyname system.directoryservices.accountmanagement
$adPrincipalContext =
New-Object System.DirectoryServices.AccountManagement.PrincipalContext(
[System.DirectoryServices.AccountManagement.ContextType]::Domain)
$user = [system.directoryservices.accountmanagement.userprincipal]::findbyidentity(
$adPrincipalContext
, [System.DirectoryServices.AccountManagement.IdentityType]::Sid
, "S-1-5-21-2422933499-3002364838-2613214872-12917")
$user.DisplayName
$user.DistinguishedName

LeBleu
- 1,101
- 3
- 17
- 28