So what I have going on is I have over 1500 users in a specific AD group, and when I pull them down I'm limited to as who I get. I saw this article on MSDN (http://msdn.microsoft.com/en-us/library/ms180907%28v=vs.80%29.aspx) however it performs a FindOne()
, doing this takes the app over 10 minutes to pull down the users. With ResultsCollection
I'm able to open the app in 30 seconds.
When it goes to process
string Last_Name = userResults.Properties["sn"][0].ToString();
it comes back with the error:
Index was out of range. Must be non-negative and less than the size of the collection.\\r\\nParameter name: index"}
I figured this had the problem of not finding the results however, the ResultsCollection
contains all 1000 entries. Any help is appreciated. Thanks!
As a note: The surname is not empty for these users, the issue is resultCollection
is only returning 1 property and that's adpath
DirectoryEntry dEntryhighlevel = new DirectoryEntry("LDAP://OU=Clients,OU=x,DC=h,DC=nt");
DirectorySearcher dSeacher = new DirectorySearcher(dEntryhighlevel);
dSeacher.Filter = "(&(objectClass=user)(memberof=CN=Users,,OU=Clients,OU=x,DC=h,DC=nt))";
uint rangeStep = 1000;
uint rangeLow = 1;
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);
}
dSeacher.PropertiesToLoad.Clear();
dSeacher.PropertiesToLoad.Add(attributeWithRange);
SearchResultCollection resultCollection = dSeacher.FindAll();
foreach (SearchResult userResults in resultCollection)
{
string Last_Name = userResults.Properties["sn"][0].ToString();
string First_Name = userResults.Properties["givenname"][0].ToString();
string userName = userResults.Properties["samAccountName"][0].ToString();
string Email_Address = userResults.Properties["mail"][0].ToString();
OriginalList.Add(Last_Name + "|" + First_Name + "|" + userName + "|" + Email_Address);
if (userResults.Properties.Contains(attributeWithRange))
{
foreach (object obj in userResults.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);
It appears that if you add one PropertiesToLoad that it will no longer load any other properties. As such you have to specify all properties you want to load, in my case.
dSeacher.PropertiesToLoad.Clear();
dSeacher.PropertiesToLoad.Add(attributeWithRange);
dSeacher.PropertiesToLoad.Add("givenname");
dSeacher.PropertiesToLoad.Add("sn");
dSeacher.PropertiesToLoad.Add("samAccountName");
dSeacher.PropertiesToLoad.Add("mail");
I wouldn't go down this path. It is easier (and less error prone) to read membership via a base search against the group than it is to do large subtree searches like this.
As you observed,when you try and read the member attribute on a large group, you'll only get 1500 values per read. The way to get all off the members of the group is via a capability typically called "ranged retrieval." I provided the link to info on this here: Always getting 1500 member of distribution list using PowerShell
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.