10

我发现如何从活动目录中获取用户列表?

当我只有几个用户时很有帮助,但我在 AD 中有这么多用户,所以当我运行查询时

if ((String)(entry.Properties["sn"].Value) == "lname"
     && (String)(entry.Properties["givenName"].Value) == "fname")
{
    return entry.Properties["samAccountName"].Value.ToString();
}

完成时间太长了。

如何按名字和姓氏搜索一个特定的用户登录 ID?

4

4 回答 4

12

由于您使用的是 .NET 4,因此您应该查看System.DirectoryServices.AccountManagement(S.DS.AM) 命名空间。在这里阅读所有相关信息:

基本上,您可以定义域上下文并在 AD 中轻松找到用户和/或组:

// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find a user - by e.g. his "samAccountName", or the Windows user name or something
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName");

if(user != null)
{
   // do something here....     
   string samAccountName = user.SamAccountName;
}

如果找不到用户名指定的用户,还可以使用新的搜索功能:

// define a "query-by-example" principal - here, we search for a UserPrincipal 
// and with the first name (GivenName) and a last name (Surname) 
UserPrincipal qbeUser = new UserPrincipal(ctx);
qbeUser.GivenName = firstName;
qbeUser.Surname = lastName;

// create your principal searcher passing in the QBE principal    
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);

// find all matches
foreach(var found in srch.FindAll())
{
    // do whatever here - "found" is of type "Principal" - it could be user, group, computer.....          
}

新的 S.DS.AM 使得在 AD 中与用户和组一起玩变得非常容易!并且仅仅找到一个用户也应该相对较快。

于 2012-04-20T15:53:08.437 回答
4

您应该使用 AD 服务器进行过滤。通过提供 LDAP 语法过滤器来做到这一点。此外,使用以下propertiesToLoad参数仅指定您需要的属性FindAll

    public static SearchResultCollection FindByName(
        string domain, string firstName, string lastName, string[] properties) {
        var rootEntry = new DirectoryEntry("LDAP://" + domain);
        var filter = string.Format("(&(sn={0})(givenName={1}))", lastName, firstName);
        var searcher = new DirectorySearcher(rootEntry, filter, properties);
        return searcher.FindAll();
    }

    // Using the method:
    var result = FindByName("mydomain", "Robert", "Smith", new[] { "samAccountName" })[0];
    string uName = (string)result.Properties["samAccountName"][0];
于 2012-04-20T16:03:04.180 回答
1

您需要将QueryFilter属性设置为searcher,然后调用searcher.FindOne()而不是searcher.FindAll()。查询过滤器可以设置为UserPrincipal对象,您可以在其中设置要搜索的字段。

Microsoft 在Query By Example页面上有一个很好的例子,尽管他们的例子希望找到几个匹配给定条件的对象。

链接问题对您的要求的特别字面调整将是

using (var context = new PrincipalContext(ContextType.Domain, "mydomain.com"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context) { GivenName = "fname", Surname = "lname" }))
    {
            foreach (var result in searcher.FindAll())
            {
                DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
                return de.Properties["samAccountName"].Value.ToString();
            }
    }
}
于 2012-04-20T15:42:30.860 回答
0

如果entryIEnumerable集合的一部分,您可以执行以下操作:

var entries = {do your population of the collection here}

var entry = entries.Where(e=>e.Properties["sn"].Value.ToString() == "lname"
    && e=>.Properties["givenName"].Value.ToString() == "fname")
    .FirstOrDefault();
于 2012-04-20T15:43:50.977 回答