Reputation: 1969
is there a way to search the Active Directory using UserPrincipal only having the SID? I have the SID in byte[] (previously queried with DirectorySearcher) and used a StringBuilder to convert it to "S-1-15-..." and "\01\05..".
I tried to handle it this way:
PrincipalContext pContext = new PrincipalContext(ContextType.Domain);
UserPrincipal pUser = new UserPrincipal(pContext);
pUser.Sid = stringBuilder.ToString();
PrincipalSearcher pSearcher = new PrincipalSearcher();
pSearcher.QueryFilter = pUser;
Console.WriteLine(pSearcher.FindOne().DistinguishedName.ToString());
Visual Studio tells me, that the Sid is write protected. Of course...
Thanks in advance & Cheers Alex
p.s.: I already tried to solve it the way described here: How can I convert from a SID to an account name in C#, but no success here.
Upvotes: 3
Views: 5484
Reputation: 265
Better late than never. Your question helped me along, so I thought I would try to add completeness to this answer for posterity. Note that my context was Local Machine, for which FindByIdentity
is too slow.
You were on the right trail. I found this answer particularly helpful to use LINQ to specify the search parameters in the collection returned by the PrincipalSearcher
. These queries did the trick for me to quickly find the accounts via SID:
private static GroupPrincipal GetGroup(string accountSid)
{
PrincipalContext oPrincipalContext = GetPrincipalContext();
GroupPrincipal oGroupPrincipal = new GroupPrincipal(oPrincipalContext);
return new PrincipalSearcher(oGroupPrincipal).FindAll().Cast<GroupPrincipal>()
.FirstOrDefault(x => x.Sid.Value.Equals(accountSid, StringComparison.OrdinalIgnoreCase));
}
private static UserPrincipal GetUser(string accountSid)
{
PrincipalContext oPrincipalContext = GetPrincipalContext();
UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext);
return new PrincipalSearcher(oUserPrincipal).FindAll().Cast<UserPrincipal>()
.FirstOrDefault(x => x.Sid.Value.Equals(accountSid, StringComparison.OrdinalIgnoreCase));
}
private static PrincipalContext GetPrincipalContext()
{
return new PrincipalContext(ContextType.Machine, Environment.MachineName);
}
For further details, see my post on this subject.
Upvotes: 5
Reputation: 898
You certainly can. I use the below method to find my users in an internal application called "Atlas". Please excuse the formatting.
using (var context = new PrincipalContext(ContextType.Domain, "DOMAIN_NAME_IMPORTANT"))
{
var userIdentity = UserPrincipal.FindByIdentity(context, "USER GUID GOES HERE"));
}
Upvotes: 7