大きなグループ内のメンバの列挙

このトピックでは、範囲取得の機能について説明し、範囲取得を使用してグループのメンバを取得するためのコード例をいくつか示します。adschema グループ オブジェクトには、1 つの配列に複数の値が格納されている、メンバと呼ばれるプロパティが含まれます。adschema のグループ オブジェクトまたはメンバ属性の詳細については、MSDN ライブラリ (https://go.microsoft.com/fwlink/?LinkID=27252) でグループまたはメンバに関するトピックを参照してください。

グループ メンバシップは非常に大きくなることがあるため、このプロパティには、何百もの値が含まれる場合があります。範囲取得とは、複数のメンバの一部を、一度に取得するプロセスです。Windows Server 2003 の場合、サーバーから一度に取得できる値の最大数は 1,500 です。範囲取得をセット内の値の数より大きい値に設定すると、検索は失敗します。範囲を小さい数に設定すると、新しい結果について頻繁にサーバーに返す必要があるため、検索のパフォーマンスが低下することがあります。範囲取得の詳細については、「多くのメンバを含むグループの列挙」を参照してください。

範囲取得を使用してグループのメンバを取得する方法を次のコード例に示します。この例では、0 から 500 までのエントリを取得します。この結果セットに対する最大エントリ数は、501 です。

DirectoryEntry group = new DirectoryEntry("LDAP://CN=Sales,DC=Fabrikam,DC=COM");
DirectorySearcher groupMember = new DirectorySearcher
    (group,"(objectClass=*)",new string[]{"member;Range=0-500"},SearchScope.Base);
SearchResult result = groupMember.FindOne();
// Each entry contains a property name and the path (ADsPath).
// The following code returns the property name from the PropertyCollection. 
String propName=String.Empty;
foreach(string s in result.Properties.PropertyNames)
{
    if ( s.ToLower() != "adspath")
    {
      propName = s;
      break;
    }
}
foreach(string member in result.Properties[propName])
{
     Console.WriteLine(member);
}

範囲取得を使用すると、結果セット内で開始点と終了点を指定することによって、結果セットの一部を取得することもできます。これを実行するには、{"member;Range=0-500"} ステートメントを変更します。たとえば、結果セット内の 3 番目と 4 番目のエントリを取得するには、ステートメント {"member;Range=2-3"} を使用します。すべてのエントリを取得するには、502 で始まり結果セットの最後で終わる、ステートメント {"member;Range=501-*"} を使用します。

最後のコード例では、グループ内のメンバ数が不明な場合に、範囲取得を使用してグループのすべてのメンバを取得する方法を示します。結果セット内のメンバよりも多くのメンバを取得しようとすると、範囲取得が機能しなくなるため、このコード例では、失敗するかどうかをテストし、失敗を受け入れると、セット内の最後のメンバを列挙するように、range ステートメントを ("member;range={0}-*", rangeLow) に変更します。

try
{
    DirectoryEntry entry = new DirectoryEntry("LDAP://CN=My Distribution List,OU=Distribution Lists,DC=Fabrikam,DC=com");
    DirectorySearcher searcher = new DirectorySearcher(entry);
    searcher.Filter = "(objectClass=*)";

    uint rangeStep = 1000;
    uint rangeLow = 0;
    uint rangeHigh = rangeLow + (rangeStep - 1);
    bool lastQuery = false;
    bool quitLoop = false;

    do
    {
        string attributeWithRange;
        if(!lastQuery)
        {
            attributeWithRange = String.Format("member;range={0}-{1}", rangeLow, rangeHigh);
        }
        else
        {
            attributeWithRange = String.Format("member;range={0}-*", rangeLow);
        }           
        searcher.PropertiesToLoad.Clear();
        searcher.PropertiesToLoad.Add(attributeWithRange);
        SearchResult results = searcher.FindOne();
        searcher.Dispose();
        foreach(string res in results.Properties.PropertyNames)
        {
            System.Diagnostics.Debug.WriteLine(res.ToString());
        }
        if(results.Properties.Contains(attributeWithRange))
        {
            foreach(object obj in results.Properties[attributeWithRange])
            {
                Console.WriteLine(obj.GetType());
                if(obj.GetType().Equals(typeof(System.String)))
                {
                }
                else if (obj.GetType().Equals(typeof(System.Int32)))
                {
                }
                Console.WriteLine(obj.ToString());
            }
            if(lastQuery)
            {
                quitLoop = true;
            }
        }
        else
        {
            lastQuery = true;
        }
        if(!lastQuery)
        {
            rangeLow = rangeHigh + 1;
            rangeHigh = rangeLow + (rangeStep - 1);
        }
    }
    while(!quitLoop);
}
catch(Exception ex)
{
    // Handle exception ex.
}

関連項目

リファレンス

System.DirectoryServices

概念

グループ管理

Send comments about this topic to Microsoft.

Copyright © 2007 by Microsoft Corporation. All rights reserved.