I have the user's SID as byte[]
within windowsPrincipal.getIdentity().getSid()
.
How can I get an Active Directory entry (DirectoryEntry) from the SID?
Given a user's SID, how can I get the AD DirectoryEntry?
Asked Answered
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()));
}
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.
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
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
© 2022 - 2024 — McMap. All rights reserved.
"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? – Fayum