Directory Services

Enumerating Members in a Large Group

This topic explains how range retrieval works and provides several code examples for using range retrieval to obtain the members of a group. The group object contains a property called member which contains multiple values in an array. Because group memberships can sometimes be quite large, this property may contain hundreds of values. Range retrieval is a process of obtaining a portion of the members at a time. For Windows Server 2003 family, the maximum number of values that can be retrieved from the server at one time is 1500. If you set the range retrieval to a value that is higher than the number of values in the set, the search fails. If you set the range to a small number, then you can degrade the performance of the search because it must return to the server for new results more often. For more information about range retrieval, see Enumerating Groups That Contain Many Members.

The following code example shows how to get members of a group using range retrieval. This sample retrieves entries 0-500, inclusively. The maximum entries for this result set are 5001.

[C#]
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);
}

You can also use range retrieval to retrieve a portion of the result set by starting and ending at a specified point within the result set. To do this, modify the {"member;Range=0-500"} statement. For example, to retrieve the third and fourth entries in the result set, you would use the statement {"member;Range=2-3"}. To retrieve all entries, starting with 502 to the end of the result set, you would use the statement {"member;Range=501-*"}.

The final code example shows how to use range retrieval to get all the members of the group when you do not know how many members are in the group. Because range retrieval does not work if you try to get more members than are in the result set, this code example tests for a failure and when it receives it, it changes the range statement to ("member;range={0}-*", rangeLow) to enumerate the final members in the set.

[C#]
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();
		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.
}