Sunday, 16 September 2018
Getting groups (including nested) for AD user - AccountManagement vs DirectorySearcher vs WindowsIdentity
Testing to see what is fastest to get all groups (i.e. include nested groups, not just top level groups) => WindowsIdentity appears to easily be the fastest, followed by directorysearcher and then accountManagement.
Over 50 tests:
WindowsIdentity average of .3 seconds
DirectorySearcher average of 1.2 seconds
AccountManagement average of 2.3 seconds
Suspect there is a reason why not to use WindowsIdentity because it is so much faster, but not sure what its restrictions are yet.
class Program
{
static AccountManagementService ams = new AccountManagementService();
static DirectorySearcherService dss = new DirectorySearcherService();
static WindowsIdentityService wis = new WindowsIdentityService();
static void Main(string[] args)
{
var userId = ConfigurationManager.AppSettings["UsernameToFind"];
var iterations = 50;
var amsTimeTaken = new List<long>();
var dssTimeTaken = new List<long>();
var wisTimeTaken = new List<long>();
for (var i = 0; i < iterations; i++)
{
amsTimeTaken.Add(CallAms(userId));
dssTimeTaken.Add(CallDss(userId));
wisTimeTaken.Add(CallWis(userId));
Console.WriteLine($"iteration {i} done");
}
Console.WriteLine($"AMS average is {(amsTimeTaken.Sum() / iterations)}");
Console.WriteLine($"DSS average is {(dssTimeTaken.Sum() / iterations)}");
Console.WriteLine($"WIS average is {(wisTimeTaken.Sum() / iterations)}");
Console.ReadKey();
}
static long CallAms(string userId)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
ams.Lookup(userId);
watch.Stop();
return watch.ElapsedMilliseconds;
}
static long CallDss(string userId)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
dss.Lookup(userId);
watch.Stop();
return watch.ElapsedMilliseconds;
}
static long CallWis(string userId)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
wis.Lookup(userId);
watch.Stop();
return watch.ElapsedMilliseconds;
}
}
public class WindowsIdentityService
{
public List<string> Lookup(string userName)
{
List<string> result = new List<string>();
WindowsIdentity wi = new WindowsIdentity(userName);
foreach (IdentityReference group in wi.Groups)
{
try
{
result.Add(group.Translate(typeof(NTAccount)).ToString().Replace("HIQ\\",""));
}
catch (Exception ex) { }
}
return result;
}
}
public class AccountManagementService
{
string _domain = ConfigurationManager.AppSettings["AmsDomain"];
public List<string> Lookup(string userId)
{
var output = new List<string>();
using (var ctx = new PrincipalContext(ContextType.Domain, _domain))
{
using (var user = UserPrincipal.FindByIdentity(ctx, userId))
{
if (user != null)
{
output = user.GetAuthorizationGroups() //this returns a collection of principal objects
.Select(x => x.SamAccountName)
.ToList();
}
}
}
return output;
}
}
public class DirectorySearcherService
{
public List<string> Lookup(string userId)
{
List<string> userNestedMembership = new List<string>();
DirectoryEntry domainConnection = new DirectoryEntry();
domainConnection.Path = ConfigurationManager.AppSettings["DssDomainPath"];
DirectorySearcher samSearcher = new DirectorySearcher();
samSearcher.SearchRoot = domainConnection;
samSearcher.Filter = "(samAccountName=" + userId + ")";
samSearcher.PropertiesToLoad.Add("displayName");
SearchResult samResult = samSearcher.FindOne();
if (samResult != null)
{
DirectoryEntry theUser = samResult.GetDirectoryEntry();
theUser.RefreshCache(new string[] { "tokenGroups" });
foreach (byte[] resultBytes in theUser.Properties["tokenGroups"])
{
System.Security.Principal.SecurityIdentifier mySID = new System.Security.Principal.SecurityIdentifier(resultBytes, 0);
DirectorySearcher sidSearcher = new DirectorySearcher();
sidSearcher.SearchRoot = domainConnection;
sidSearcher.Filter = "(objectSid=" + mySID.Value + ")";
sidSearcher.PropertiesToLoad.Add("distinguishedName");
sidSearcher.PropertiesToLoad.Add("name");
SearchResult sidResult = sidSearcher.FindOne();
if (sidResult != null)
{
userNestedMembership.Add((string)sidResult.Properties["name"][0]);
}
}
}
else
{
Console.WriteLine("The user doesn't exist");
}
return userNestedMembership;
}
}
Subscribe to:
Posts (Atom)