I am writing an application that needs to get a list of users from a specified domain. I can get the users now, but it is way to slow how can I do this faster especially on larger domains?
using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain))
{
UserPrincipal userPrincipal = new UserPrincipal(pc);
PrincipalSearcher search = new PrincipalSearcher(userPrincipal);
PrincipalSearchResult<Principal> results = search.FindAll();
foreach (var principals in results.Partition(20))
{
IDictionary<string, string> users = new Dictionary<string, string>(20);
foreach (UserPrincipal principal in principals.Cast<UserPrincipal>())
{
users.Add(principal.SamAccountName, principal.DisplayName);
}
yield return users;
}
}
Basically in the outer foreach loop I am getting an IEnumerable of IEnumerable>. I did that so I could try to incrementally load a few at a time and display them to the user while the rest are still loading, but once I hit that inner loop I get a several minute hang.
I am trying to get the users name in domain\\username format as well which I haven't figured out how to do either.
Try this. It should work faster.
using System.DirectoryServices;
string[] RetProps = new string[] { "SamAccountName", "DisplayName" };
//IDictionary<string, string> users = new Dictionary<string, string>();
List<string[]> users = new List<string[]>();
foreach (SearchResult User in GetAllUsers("YourDomain", RetProps))
{
DirectoryEntry DE = User.GetDirectoryEntry();
try
{
users.Add(new string[]{DE.Properties["SamAccountName"][0].ToString(), DE.Properties["DisplayName"][0].ToString()});
}
catch
{
}
}
internal static SearchResultCollection GetAllUsers(string DomainName, string[] Properties)
{
DirectoryEntry DE = new DirectoryEntry("LDAP://" + DomainName);
string Filter = "(&(objectCategory=organizationalPerson)(objectClass=User))";
DirectorySearcher DS = new DirectorySearcher(DE);
DS.PageSize = 10000;
DS.SizeLimit = 10000;
DS.SearchScope = SearchScope.Subtree;
DS.PropertiesToLoad.AddRange(Properties); DS.Filter = Filter;
SearchResultCollection RetObjects = DS.FindAll();
return RetObjects;
}
}
}
This is pretty fast. I got 14k results in a couple of seconds. If you need to update the ui, you could use an eventhandler and a different thread.
string groupName = "Domain Users";
string domainName = "domain";
var results = new List<string>();
using (var pc = new PrincipalContext(ContextType.Domain, domainName))
{
using (var grp = GroupPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, groupName))
{
if (grp != null)
foreach (var p in grp.GetMembers(false))
{
results.Add(p.DisplayName);
}
}
Assert.IsTrue(results.Count > 0);
}
dc is the domain cntroller how for example "company.com"
public static ArrayList GetAllActiveDirectoryUsersByDisplayName(string dc)
{
ArrayList list = new ArrayList();
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, dc);
UserPrincipal u = new UserPrincipal(ctx);
PrincipalSearcher ps = new PrincipalSearcher(u);
PrincipalSearchResult<Principal> results = ps.FindAll();
foreach (UserPrincipal usr in results)
{
list.Add(usr.Name);
}
list.Sort();
return list;
}
in your endfront you can do this:
ArrayList list = GetAllActiveDirectoryUsersByDisplayName("company.com");
foreach (string x in list)
{
Console.WriteLine(x);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.