如何从Active Directory查询用户信息?我有适用的代码,但它确实很慢.我正在使用C#.这是我目前使用的代码:
static void Main(string[] args) { SearchResultCollection sResults = null; try { //modify this line to include your domain name string path = "LDAP://EXTECH"; //init a directory entry DirectoryEntry dEntry = new DirectoryEntry(path); //init a directory searcher DirectorySearcher dSearcher = new DirectorySearcher(dEntry); //This line applies a filter to the search specifying a username to search for //modify this line to specify a user name. if you want to search for all //users who start with k - set SearchString to "k" dSearcher.Filter = "(&(objectClass=user))"; //perform search on active directory sResults = dSearcher.FindAll(); //loop through results of search foreach (SearchResult searchResult in sResults) { if (searchResult.Properties["CN"][0].ToString() == "Adit") { ////loop through the ad properties //foreach (string propertyKey in //searchResult.Properties["st"]) //{ //pull the collection of objects with this key name ResultPropertyValueCollection valueCollection = searchResult.Properties["manager"]; foreach (Object propertyValue in valueCollection) { //loop through the values that have a specific name //an example of a property that would have multiple //collections for the same name would be memberof //Console.WriteLine("Property Name: " + valueCollection..ToString()); Console.WriteLine("Property Value: " + (string)propertyValue.ToString()); //["sAMAccountName"][0].ToString(); } //} Console.WriteLine(" "); } } } catch (InvalidOperationException iOe) { // } catch (NotSupportedException nSe) { // } finally { // dispose of objects used if (sResults != null) sResults.Dispose(); } Console.ReadLine(); }
从AD获取用户信息的代码更快?
部件
using System.DirectoryServices.AccountManagement;
using (var pc = new PrincipalContext(ContextType.Domain, "MyDomainName"))
{
var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "MyDomainName\\" + userName);
}
命名空间
using System.DirectoryServices.AccountManagement;
using (var pc = new PrincipalContext(ContextType.Domain, "MyDomainName"))
{
var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "MyDomainName\\" + userName);
}
以下代码将为您提供所有用户信息.
using System.DirectoryServices.AccountManagement;
using (var pc = new PrincipalContext(ContextType.Domain, "MyDomainName"))
{
var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "MyDomainName\\" + userName);
}
您的代码速度慢的原因是您的LDAP查询检索域中的每个用户对象,即使您只对一个名为"Adit"的用户感兴趣:
dSearcher.Filter = "(&(objectClass=user))";
因此,要进行优化,您需要将LDAP查询范围缩小到您感兴趣的用户.尝试以下方法:
dSearcher.Filter = "(&(objectClass=user)(cn=Adit))";
另外,完成后不要忘记处理这些对象:
DirectoryEntry dEntry
DirectorySearcher dSearcher
好吧,如果你知道你的用户在AD层次结构中的位置(例如,很可能在"Users"容器中,如果它是一个小型网络),你也可以直接绑定到用户帐户,而不是搜索它.
DirectoryEntry deUser = new DirectoryEntry("LDAP://cn=John Doe,cn=Users,dc=yourdomain,dc=com"); if (deUser != null) { ... do something with your user }
如果你已经使用.NET 3.5,你甚至可以使用扩展的System.DirectorySrevices.AccountManagement命名空间和每个最常见的AD对象的强类型类:
// bind to your domain PrincipalContext pc = new PrincipalContext(ContextType.Domain, "LDAP://dc=yourdomain,dc=com"); // find the user by identity (or many other ways) UserPrincipal user = UserPrincipal.FindByIdentity(pc, "cn=John Doe");
System.DirectoryServices.AccountManagement上有很多信息 - 请查看Joe Kaplan和Ethan Wilansky关于MSDN的这篇优秀文章.
您可以将此代码简化为:
DirectorySearcher searcher = new DirectorySearcher(); searcher.Filter = "(&(objectCategory=user)(cn=steve.evans))"; SearchResultCollection results = searcher.FindAll(); if (results.Count == 1) { //do what you want to do } else if (results.Count == 0) { //user does not exist } else { //found more than one user //something is wrong }
如果您可以缩小用户的范围,可以将searcher.SearchRoot设置为您知道用户所在的特定OU.
您还应该使用objectCategory而不是objectClass,因为默认情况下会对objectCategory建立索引.
您还应该考虑搜索CN以外的属性.例如,搜索用户名(sAMAccountName)可能更有意义,因为它保证是唯一的.