2

以下のコードを実行してすべてのグループ、サブグループ、および関連するユーザーを取得すると、いくつかのレコードを取得した後に奇妙なエラーが発生します:90000のグループ/サブグループと250000のユーザーを取得することを期待しています

エラー:

System.Runtime.InteropServices.COMExceptionがキャッチされましたメッセージ=サーバーが動作していません

 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);
    }
}

何か案が?

4

2 に答える 2

2

DirectorySearcher.PageSizeを設定して、ページ化された結果セットを実行できるようです。これにより、通常、サーバー側の制限を超えることができます。

私はまだ既知のLDAPツール(私はApache Studioが好きです)を試し、それが機能するかどうかを確認します。(directory.apache.org/studio)

于 2013-02-07T12:00:04.003 に答える
1

このエラーはさまざまな意味を持ちますが、実際に何が原因であるかをよりよく理解するために、マシンとLDAPサーバー間のTCPトラフィックを[Wireshark][1]することを強くお勧めします。

サーチャーの実行中に接続がタイムアウトした場合、そのエラーがスローされる直前に、マシンから[RST、ACK]が表示されます。これは逆の場合もあり、サーチャーが終了する前にターゲットLDAPサーバーが接続を強制的に閉じます。

また、AccountManagement名前空間が提供するものではなく、下位レベルのDirectoryServices名前空間で使用可能なオブジェクトとクラスを使用することをお勧めします。

私は本当にこの種のもののためにLdapConnectionオブジェクトとDirectorySearcherオブジェクトを掘り下げます。どちらも非常に柔軟性があります。

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

PageSizeをjeemsterが推奨するように設定し、PageTimeLimit:

var directoryEntry = new DirectoryEntry(("LDAP://" + ldapUrl), usrname, password);

var directorySearcher = new DirectorySearcher(directoryEntry)
{
    SearchScope = SearchScope.Subtree,
    ServerPageTimeLimit = TimeSpan.FromSeconds(100000),
    PageSize = 500000       
};

ここで見つけたものを教えてください。

于 2013-02-14T23:17:48.143 に答える