views:

112

answers:

3

I am searching for existing logins using ADS Directory searcher findAll() method (as in following code). It appears the findall method returns only 1000 entries although there are more entries than that. How do I findAll() of every login ?

    IList<string> adslist = new List<string>();
    using (DirectoryEntry de = new DirectoryEntry("LDAP://armlink.com", null, null, AuthenticationTypes.Secure))
    using (DirectorySearcher ds = new DirectorySearcher(de, "(objectclass=user)", new string[] { "samaccountname" }))

        foreach (SearchResult sr in ds.FindAll())
        {
            string[] e = sr.Path.Split(new string[] { "LDAP://", "OU=", ",", "DC=", ".com", "/CN=" }, StringSplitOptions.RemoveEmptyEntries);
            ResultPropertyCollection pc = sr.Properties;
            adslist.Add(e[0] + "/" + pc["samaccountname"][0].ToString());
            //   Debug.WriteLine(adslist.Last());
        }
+3  A: 

This is due to a server-side limit. From the DirectorySearcher.SizeLimit documentation:

The maximum number of objects that the server returns in a search. The default value is zero, which means to use the server-determined default size limit of 1000 entries.

And:

If you set SizeLimit to a value that is larger than the server-determined default of 1000 entries, the server-determined default is used.

Basically from this, it looks like unless there's a way of changing the server-side default, you're going to be limited to 1000 entries. It's possible that specifying a PageSize will let you fetch a certain number at a time, with a total greater than 1000... not sure.

By the way, it looks like you should also have a using directive around the SearchResultCollection:

using (SearchResultCollection results = ds.FindAll())
{
    foreach (SearchResult sr in results) 
    {
        ...
    }
}
Jon Skeet
A possible workaround might be to break up the query into a few chunks, each under the limit.
Steven Sudit
@Steven: Yes. It depends on how easy that is to do in a reliable way.
Jon Skeet
Jon:Modified the code to using around the SearchResultCollection . Thanks
TonyP
+1  A: 

There are two ways around this limitation - see the MSDN docs on DirectorySearcher for details:

  • set the DirectorySearcher.SizeLimit property to some value you need - this will return that given number of entries in a single search; however, you cannot get more than the server limit (default: 1'000 entries) back in a single operation - however, that server limitation is a configurable option - you could set it higher, and then set your directory searcher's size limit higher - but the more entries you want to return at once, the longer your call will take!

  • set the DirectorySearcher.PageSize to some value, e.g. 250 or so, to do "paged searches", e.g. you get back 250 entries in a single operation, and if you iterate to the 251st entry, the directory searcher goes back (in a second, third, fourth call) to get another 250 entries. This is typically the better option since you get back that number of entries quickly, but you can keep searching for more entries as needed

The preferred way to handle situations where you need more than those 1000 entries is definitely paged searches - see the MSDN docs:

After the server has found the number of objects that are specified by the PageSize property, it will stop searching and return the results to the client. When the client requests more data, the server will restart the search where it left off.

marc_s
Thanks..Setting Page Size to 1001 retrieved all entries..
TonyP
@marc_s , Setting 1001 as the page size retrived all 3000+ entries..My code does not have a loop, just the page size..and it did (and does) retrieve all entries..!
TonyP
A: 

How many total entries did you have? was it more than 1001?

Thanks

PV Mankale
Well , around 12,000 if that satisfy you..(seriously) I can give you a better figure if you wish to ..
TonyP