Im using the following code to get a bunch of information about employees from specific departments and returning a list from AD...
Whilst it works, it appears to be quite slow, is a there more efficient way of getting various user details from AD?
public static List<Employee> GetEmployeeListForDepartment(string departpment)
{
using (HostingEnvironment.Impersonate())
{
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domain);
GroupPrincipal gp = GroupPrincipal.FindByIdentity(ctx, departpment);
PrincipalSearchResult<Principal> members = gp.GetMembers();
List<Employee> employees = new List<Employee>();
foreach (var member in members)
{
var emp = CreateEmployee(member);
employees.Add(emp);
}
return employees.OrderBy(x => x.FirstName).ToList();
}
}
private static Employee CreateEmployee(Principal member)
{
if (member != null)
{
DirectoryEntry de = (member.GetUnderlyingObject() as DirectoryEntry);
if (de != null)
{
string mobile = de.Properties.Contains("mobile") ? de.Properties["mobile"][0].ToString() : "";
string title = de.Properties.Contains("description") ? de.Properties["description"][0].ToString() : "";
//ETC ETC...
return new Employee { etc.. };
}
}
return new Employee();
}
Your problem is that you are using System.DirectoryServices.AccountManagement... While I hate saying it, it's sadly the truth. The way AccountManagement works under the hood is that it runs a seperate LDAP query to retrieve each item seperately. So when you iterate through members it's making a seperate call back through LDAP for each member. What you want to do instead is run an LDAP query using System.DirectoryServices.DirectorySearcher.
My assumption is that department is a group, based on how you are using it. Here is how I would do it. (my code is in VB.Net... sorry). Make sure to get the fully qualified DN for your group, or look it up in advance and plug it into the query.
Dim results = LDAPQuery("(memberOf=CN=Fully,OU=Qualified,DC=Group,DC=Distinguished,DC=Name)", New String() {"mobile", "description"})
Dim emps = (from c as System.DirectoryServices.SearchResult in results _
Select New Employee() {.Name = c.Properties("description"), .Mobile = c.Properties("mobile")}).ToList()
Public Function LDAPQuery(ByVal query As String, ByVal attributes As String()) As SearchResultCollection
'create directory searcher from CurrentADContext (no special security available)
Dim ds As New DirectorySearcher(System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().GetDirectoryEntry())
ds.PageSize = 1000
'set filter string
ds.Filter = query
'specify properties to retrieve
ds.PropertiesToLoad.AddRange(attributes)
'get results
Dim results As SearchResultCollection = ds.FindAll()
Return results
End Function
You should be able to use the Active Directory API directly.
Most of it is available under 'System.DirectoryServices'
I don't have any code to hand to do exactly what you need, but I do have an article on my Blog from about a year back, that shows how to create local user accounts in AD, all of which uses the same assemblies as needed to get user information.
http://shawtyds.wordpress.com/2010/12/08/a-little-bit-of-ldap-here-there/
NOTE: AD however by it's very nature is slow, so there's a good chance you might not be able to get any faster if you have a large directory.