I just noticed that the return list for results is limited to 1000. I have more than 1000 groups in my domain (HUGE domain). How can I get more than 1000 records? Can I start at a later record? Can I cut it up into multiple searches?
Here is my query:
DirectoryEntry dirEnt = new DirectoryEntry("LDAP://dhuba1kwtn004");
string[] loadProps = new string[] { "cn", "samaccountname", "name", "distinguishedname" };
DirectorySearcher srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps);
var results = srch.FindAll();
I have tried to set srch.SizeLimit = 2000;, but that doesn’t seem to work. Any ideas?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You need to set DirectorySearcher.PageSize to a non-zero value to get all results.
BTW you should also dispose DirectorySearcher when you’re finished with it
using(var srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps))
{
srch.PageSize = 1000;
var results = srch.FindAll();
}
The API documentation isn’t very clear, but essentially:
- when you do a paged search, the SizeLimit is ignored, and all matching results are returned as you iterate through the results returned by FindAll. Results will be retrieved from the server a page at a time. I chose the value of 1000 above, but you can use a smaller value if preferred. The tradeoff is: using a small PageSize will return each page of results faster, but will require more frequent calls to the server when iterating over a large number of results.
- by default the search isn’t paged (PageSize = 0). In this case up to SizeLimit results is returned.
As Biri pointed out, it’s important to dispose the SearchResultCollection returned by FindAll, otherwise you may have a memory leak as described in the Remarks section of the MSDN documentation for DirectorySearcher.FindAll.
One way to help avoid this in .NET 2.0 or later is to write a wrapper method that automatically disposes the SearchResultCollection. This might look something like the following (or could be an extension method in .NET 3.5):
public IEnumerable<SearchResult> SafeFindAll(DirectorySearcher searcher)
{
using(SearchResultCollection results = searcher.FindAll())
{
foreach (SearchResult result in results)
{
yield return result;
}
} // SearchResultCollection will be disposed here
}
You could then use this as follows:
using(var srch = new DirectorySearcher(dirEnt, "(objectClass=Group)", loadProps))
{
srch.PageSize = 1000;
var results = SafeFindAll(srch);
}
Method 2
I tried to use given solution to achieve pagination but it doesnt work.
I set pageSize = 100; and i get all the items through searchResult.
dirSearcher = new DirectorySearcher(direntry);
dirSearcher.Filter = (“(|(objectClass=volume). (objectClass=user)(objectClass=printQueue)(objectClass=computer). (objectClass=organizationalUnit)(objectClass=Group))”);
dirSearcher.PageSize = 100;
dirSearcher.SearchScope = System.DirectoryServices.SearchScope.Subtree;
dirSearcher.ServerTimeLimit = new TimeSpan(1000);
//dirSearcher.VirtualListView = new DirectoryVirtualListView(0, 100, 1);
using (SearchResultCollection results = dirSearcher.FindAll())
{
foreach (SearchResult result in results)
{
DirectoryEntry ent = result.GetDirectoryEntry();
ADItem ProviderItem = Context.ConvertToItem(ent, true);
if (ProviderItem != null)
{
ProviderItem.IsPartialData = true;
ProviderItems.Add(ProviderItem);
}
}
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0