如何从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获取用户信息会有什么更快的代码?
答案 0 :(得分:23)
您可以在System.DirectoryServices.AccountManagement
内致电UserPrincipal.FindByIdentity
:
using System.DirectoryServices.AccountManagement;
using (var pc = new PrincipalContext(ContextType.Domain, "MyDomainName"))
{
var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "MyDomainName\\" + userName);
}
答案 1 :(得分:17)
您的代码速度慢的原因是您的LDAP查询会检索您域中的每个用户对象,即使您只对一个名为“Adit”的用户感兴趣:
dSearcher.Filter = "(&(objectClass=user))";
因此,要进行优化,您需要将LDAP查询范围缩小到您感兴趣的用户。请尝试以下操作:
dSearcher.Filter = "(&(objectClass=user)(cn=Adit))";
此外,完成后不要忘记处理这些对象:
dEntry
dSearcher
答案 2 :(得分:13)
好吧,如果你知道你的用户在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上的这个优秀article。
答案 3 :(得分:7)
您可以将此代码简化为:
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)可能更有意义,因为它保证是唯一的。
答案 4 :(得分:1)
我不确定你的“缓慢”有多少是由于您正在查找具有特定属性值的条目所做的循环,但您可以通过更具体地使用过滤器来删除此循环。试试这个页面以获得一些指导... Search Filter Syntax