3

下面的代码有两个目标

1) 获取属于特定 AD 组的用户列表
2) 获取属于该组的所有用户的电子邮件/姓氏/名字

如果有更好的方法来完成这两者,请告诉我。

我能够获得完整的 DN,但我不确定如何从完整的 DN 中获取剩余数据,或者如果有更好的方法来提取此信息,请告诉我。以下是我正在使用的代码,但出现错误:

The value provided for adsObject does not implement IADs.

当我尝试使用完整的 DN 执行 DirectorySearcher 时。

HashSet<string> User_Collection = new HashSet<string>();

SearchResultCollection sResults = null;
DirectoryEntry dEntryhighlevel = new DirectoryEntry("LDAP://CN=Global_Users,OU=Astrix,OU=Clients,OU=Channel,DC=astro,DC=net");
foreach (object dn in dEntryhighlevel.Properties["member"])
{
    DirectoryEntry dEntry = new DirectoryEntry(dn);
    Console.WriteLine(dn);
    DirectorySearcher dSearcher = new DirectorySearcher(dEntry);
    //filter just user objects
    dSearcher.SearchScope = SearchScope.Base;
    //dSearcher.Filter = "(&(objectClass=user)(dn="+dn+")";
    dSearcher.PageSize = 1000;
    sResults = dSearcher.FindAll();
    foreach (SearchResult sResult in sResults)
    {
        string Last_Name = sResult.Properties["sn"][0].ToString();
        string First_Name = sResult.Properties["givenname"][0].ToString();
        string Email_Address = sResult.Properties["mail"][0].ToString();
        User_Collection.Add(Last_Name + "|" + First_Name + "|" + Email_Address);
    }

速度很重要,是的,我知道我没有按照设计使用 HashSet。

4

2 回答 2

1

我总是使用System.DirectoryServices.AccountManagement.

您将看到的第一件事是:“在可用时使用快速并发绑定 (FSB) 功能可以提高连接速度。连接缓存会减少使用的端口数量。” 话虽如此,我没有针对速度测试你的代码,你必须自己做,但这是微软的新库。

这是我的代码示例:

// Create the context for the principal object. 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
                                            "fabrikam",
                                            "DC=fabrikam,DC=com");

// Create an in-memory user object to use as the query example.
GroupPrincipal u = new GroupPrincipal(ctx) {DisplayName = "Your Group Name Here"};

// Set properties on the user principal object.

// Create a PrincipalSearcher object to perform the search.
PrincipalSearcher ps = new PrincipalSearcher {QueryFilter = u};

// Tell the PrincipalSearcher what to search for.

// Run the query. The query locates users 
// that match the supplied user principal object. 
PrincipalSearchResult<Principal> results = ps.FindAll();

foreach (UserPrincipal principal in ((GroupPrincipal)results.FirstOrDefault()).Members)
{
    string email = principal.EmailAddress;
    string name = principal.Name;
    string surname = principal.Surname;
}
于 2012-06-15T18:52:30.007 回答
0

看起来您正在 AD 中某个组的组成员身份...(从上面的成员参考中猜测)

无论如何,您需要决定要寻找哪种 API。您现在使用的级别较低(尽管您可以根据需要降低 :))。更高级别是一个选项,因为之前的答案没有解决。

进一步修改代码(并帮助提高性能,正如您提到的那样,它对您很重要):

  • 使用与组成员搜索本身相同的连接(即没有额外的连接/绑定)
  • 进行基本搜索,其中基本 DN 是用户 DN,搜索过滤器是 (objectclass=*),并且属性只是您关心的属性(没有 *)
  • 您可以删除页面大小。分页是一种在组(又名页面)中请求许多对象的方法,但基本搜索仅返回 1 个对象,因此它实际上并没有做任何事情。
  • 基本搜索结果计数应始终为 1。

还要记住跨域问题。确保您使用 2 域森林测试您的代码,其中 domain1 中的一组类型域 local 在其中包含来自域 2 的成员。这将产生一些额外的工作来获取更多属性,因为您需要连接到另一个中的 DC域(如果您关心的少数属性都在 GC 部分属性集中,则为 GC...)

还要注意安全。如果您对域中的某些用户无权访问这些属性,那么代码会做什么?上面的代码会以令人讨厌的方式失败。:) 你可能想更优雅地处理这个......

希望这可以帮助。〜埃里克

于 2012-06-15T19:42:52.297 回答