使用System.DirectoryServices.AccountManagement,我收到奇怪的错误

本文关键字:错误 System DirectoryServices AccountManagement 使用 | 更新日期: 2023-09-27 17:56:31

当我运行下面的代码来检索所有组、子组和相关用户时,我在检索一些记录后出现一个奇怪的错误:我期望检索 90000 个组/子组和 250000 个用户

错误:

System.Runtime.InteropServices.COMException 被捕获 Message=The 服务器无法运行

 public static List<Group>getUsers()
{
    // create the "context" in which to operate - your domain here, 
    // as the old-style NetBIOS domain, and the container where to operate in
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "lin.proximus.com");
    // define a "prototype" - an example of what you're searching for
    // Here: just a simple GroupPrincipal - you want all groups
    GroupPrincipal prototype = new GroupPrincipal(ctx);
    // define a PrincipalSearcher to find those principals that match your prototype
    PrincipalSearcher searcher = new PrincipalSearcher(prototype);
    // define a list of strings to hold the group names        
    List<Group> groupNames = new List<Group>();
    int counter = 0;
    // iterate over the result of the .FindAll() call
    foreach (var gp in searcher.FindAll())
    {
        // cast result to GroupPrincipal
        GroupPrincipal groupPrincipal = gp as GroupPrincipal;
        // if everything - grab the group's name and put it into the list
        if (groupPrincipal == null) continue;
        Group group = new Group();
        group.Name = groupPrincipal.Name;
        group.Description = groupPrincipal.Description;
        AddSubGroups(groupPrincipal, ref group);
        AddMemebers(groupPrincipal, ref group);
        counter++;
        groupNames.Add(group);
        Console.WriteLine(counter);
        if (counter > 10000)
            return groupNames;
    }
    return groupNames;
}
private static void AddSubGroups(GroupPrincipal gp,ref Group gr)
{
    gr.SubCounts = 0;
    if (gp.GetGroups().Count() <= 0) return;
    gr.SubCounts = gp.GetGroups().Count();
    gr.SubGroups = new List<string>();
    foreach (var principal in gp.GetGroups())
    {
        gr.SubGroups.Add(principal.Name);
    }
}
private static void AddMemebers(GroupPrincipal gp, ref Group gr)
{
    if (gp.GetMembers().Count() <= 0) return;
    gr.Users = new List<string>();
    foreach (Principal principal in gp.GetMembers())
    {
        gr.Users.Add(principal.Name);
    }
}

知道吗?

使用System.DirectoryServices.AccountManagement,我收到奇怪的错误

看起来你可以设置 DirectorySearcher.PageSize 并执行分页结果集。这通常允许您超越服务器端限制。

我仍然会尝试一个已知的LDAP工具(我喜欢Apache Studio),看看它是否有效。(directory.apache.org/studio)

这个错误可能意味着很多事情,但我强烈建议[Wireshark'ing][1]你的机器和ldap服务器之间的TCP流量,以便更好地了解实际导致它的原因。

如果在搜索器运行时连接超时,则会在引发错误之前从计算机中看到 [RST, ACK]。这也可能相反,目标 ldap 服务器在搜索者完成之前强制关闭您的连接。

此外,我建议使用较低级别的 DirectoryServices 命名空间中可用的对象和类,而不是 AccountManagement 命名空间必须提供的对象和类。

我真的为这种事情挖掘了LdapConnection和DirectorySearcher对象,它们都具有很大的灵活性:

LdapConnection ldapConnection = new LdapConnection("lin.proximus.com:389");
ldapConnection.Timeout = 100000;

按照 jeemster 的建议设置 PageSize,以及 PageTimeLimit:

var directoryEntry = new DirectoryEntry(("LDAP://" + ldapUrl), usrname, password);
var directorySearcher = new DirectorySearcher(directoryEntry)
{
    SearchScope = SearchScope.Subtree,
    ServerPageTimeLimit = TimeSpan.FromSeconds(100000),
    PageSize = 500000       
};

让我知道你在这里发现了什么。

相关文章: