Search code examples
c#active-directoryldapldap-query

LDAP search returns less objects than expected


I am attempting to pull every user from Active Directory. I am using this method currently:

        DirectorySearcher search = new DirectorySearcher();            
        search.Filter = "(objectClass=user)";
        foreach (SearchResult result in search.FindAll())
        {
            if(result.Properties["mail"].Count > 0 && result.Properties["displayName"].Count > 0)
            {
                emailAddresses.Add(new EmailDetails
                {
                    EmailAddress = result.Properties["mail"][0].ToString(),
                    EmailDisplayName = result.Properties["displayName"][0].ToString()
                });
            }
         }

This is only givnig me around 3/4 of the names I am expecting. It is for one leaving me out.... So I got curious and added a new filter to see if I could pull myself by changing the filter to this:

search.Filter = "(&(objectClass=user)(sn=za*))";

This did in fact pull me in correctly, I basically am forcing it to pull me in by setting the filter to search for every last name that starts with za. But why is the first search filter I am using not pulling all of the users in?


Solution

  • why is the first search filter I am using not pulling all of the users in?

    Most likely because SizeLimit kicks in at 1000 records. Set a PageSize to enable result paging.

    Doing .FindAll() with no filter to speak of and then filtering the results on the client is silly. Write a proper filter.

    var search = new DirectorySearcher();            
    search.Filter = "(&(objectClass=user)(mail=*)(displayName=*))";
    search.PageSize = 1000;  // see 1.
    
    using (var results = searcher.FindAll()) {  // see 2.
        foreach (var result in results)
        {
            emailAddresses.Add(new EmailDetails
            {
                EmailAddress = result.Properties["mail"][0].ToString(),
                EmailDisplayName = result.Properties["displayName"][0].ToString()
            });
        }
    }
    
    1. Small page size = faster results but more server round trips, larger page size = slower results but less server round trips. Pick a value that works for you.
    2. You must dispose the SearchResultCollection manually, see "Remarks" in the MSDN documentation of DirectorySearcher.FindAll(). A using block will dispose the object properly.