Directory Programming .NET

Active Directory and ADAM programming support for .NET developers
Welcome to Directory Programming .NET Sign in | Join | Help
in Search

DirectorySearcher.PageSize Property

Last post 06-13-2007, 10:24 PM by joe. 18 replies.
Page 1 of 2 (19 items)   1 2 Next >
Sort Posts: Previous Next
  •  05-21-2007, 7:02 PM 1068

    DirectorySearcher.PageSize Property

    Hi,

    So I'm wading through the PageSize threads in this forum and am understanding the issue of NOT setting this property. Essentially, if you DON'T set this property to something other than zero, you will not get > 1K results (unless the AD server admin has set MaxPageSize to something bigger, as was the case for me on my company's intranet).

    My question is if you are expecting to get >1000 results in your query, what is a good default PageSize to use? 1K?

    -Patrick

  •  05-21-2007, 8:00 PM 1069 in reply to 1068

    Re: DirectorySearcher.PageSize Property

    You tend to use your network resources most effectively when you use larger page size (=maxPageSize), so that's generally what you want to do.  In some cases if you have a very expensive query that takes a long time to return any results, using a smaller page size can help avoid timeouts, but that usually isn't a problem.
  •  05-21-2007, 8:41 PM 1070 in reply to 1069

    Re: DirectorySearcher.PageSize Property

    Thanks,

    I went back to your book and I am seeing the explanation for setting PageSize. I think for our application, 1K would be appropriate. However, I'm not sure I will be able to set the PageSize property.

    Interestingly, when I set PageSize=1K (or anything other than zero), I no longer find the DomainDNS objects I once could?! That is all I changed is adding PageSize=1000 and suddenly those objects are not found. Is there some issue or relationship with domainDNS that PageSize exposes? I'm lost on that.

    -Patrick

  •  05-22-2007, 12:49 AM 1072 in reply to 1070

    Re: DirectorySearcher.PageSize Property

    In looking into this a bit further I see that Paged Searching disables the ReferralChasing.Subordinate option (page 162 of the Book). Disabling the ReferralChasing.Subordinate option is what is causing searches for domainDNS objects to break. Unfortunately I am using the ReferralChasing.All option, which includes ReferralChasing.Subordinate, all over the place. For that reason I don't think I will be able to use Paged Searching. Is there a way around this caveat? Is changing the MaxPageSize on the server an unthinkable workaround?

    -Patrick

  •  05-22-2007, 10:08 AM 1074 in reply to 1072

    Re: DirectorySearcher.PageSize Property

    Can you search the global catalog instead?  If you need to find domainDNS objects in multiple different partitions, that seems like it would be a better way to go than to rely on referral chasing to get to multiple different partitions.

  •  05-23-2007, 10:02 AM 1079 in reply to 1074

    Re: DirectorySearcher.PageSize Property

    Thanks I gave GC: a try. Unless I use both the LDAP provider, and ReferralChasing.All, I cannot find these domainDNS objects in my company's AD. GC with or without ReferralChasing, or with/without PageSize does not work. In theory I know the difference between LDAP and GC providers, but in practice, I see odd differences like these that I cannot account for.

    -Patrick

  •  05-23-2007, 11:28 AM 1080 in reply to 1079

    Re: DirectorySearcher.PageSize Property

    I think you may be doing the GC search incorrectly.  With the GC, you normally do a subtree search with a null base DN.  For example, do a search with a root like:

    "GC://"

    and filter of

    (objectClass=domainDNS)

    should find all of the domainDNS objects in the forest.

     

    DirectoryEntry root = new DirectoryEntry("GC://");
    DirectorySearcher s = new DirectorySearcher(root);
    s.Filter = "objectClass=domainDNS";
    s.PropertiesToLoad.Add("name");

    SearchResultCollection src = s.FindAll();
    foreach (SearchResult res in src)
    {

        Console.WriteLine(res.Properties["name"][0]);

    }

    That worked for me.  If you need to, you can put the forest DNS name in the DE constructor and supply credentials if needed.

    There are definitely things you can't find in the GC as not all attributes are replicated, but it is usually the best way of doing searches across the whole forest.

    The other way to do this type of thing without referral chasing is with the special phantom root control, but ADSI doesn't expose this, so neither does S.DS.  You have to drop down into SDS.Protocols to use it.

  •  06-06-2007, 6:50 PM 1136 in reply to 1080

    Re: DirectorySearcher.PageSize Property

    Actually if I just use GC:// I end up with the 0x80005000 Unknown Error. For some reason I need the DC or the domain appended to the GC://.

    But, I think I found a nifty approach around that issue. This approach allows me to use the GC and therefore avoid Referral Chasing as you pointed out above. Using GC allows me to use the PageSize property on DirectorySearcher, to get around the 1000 object limitation. I got this idea from the reference in the book to the BeaverTail AD Browser. That code gave me the idea (except he's not using the GC, he's using LDAP).

    string rootDnc = null;

    using (DirectoryEntry rootDSE = new DirectoryEntry(LDAP://rootDSE))

    {

        rootDnc = (string)rootDSE.Properties["rootDomainNamingContext"].Value;

    }

    string adspath = "GC://" + rootDnc;

    using (DirectoryEntry entry = new DirectoryEntry(adspath))

    {

        using (DirectorySearcher ds = new DirectorySearcher(entry))

       {

            ds.Filter = "(objectClass=domainDNS)";

            ds.PageSize = 1000;

            SearchResultCollection src = ds.FindAll();

            foreach (SearchResult sr in src)

            {

                string name = sr.Properties["name"][0].ToString();

                Console.WriteLine("Name = " + name);

            }

        }

    }

  •  06-08-2007, 1:15 PM 1143 in reply to 1136

    Re: DirectorySearcher.PageSize Property

    Listing 5.1 might help here.  Just note that the book actually forgets to dispose one of the DirectoryEntry objects, but I have fixed it here below:

    public void GlobalCatalogSearch()
    {

        DirectoryEntry gc = new DirectoryEntry("GC:");

        DirectoryEntry _root = null;

        using (gc)
        {
            //there is only 1 child under "GC:"
            foreach (DirectoryEntry root in gc.Children)
            {
                _root = root;
                break;
            }
        }

        //note the filter must be searching
        //  for a GC replicated attribute!
        string filter = "(objectClass=domainDNS)";

        using (_root)
        {
            DirectorySearcher ds = new DirectorySearcher(
                _root,
                filter,
                null,
                SearchScope.Subtree
                );

            using (SearchResultCollection src = ds.FindAll())
            {
                foreach (SearchResult sr in src)
                {
                    Console.WriteLine("{0}", sr.Path);
                }
            }
        }
    }


    This one works for me...

    Ryan Dunn
    Extemporaneous Mumblings
    The .NET Developer's Guide to Directory Services Programming
  •  06-11-2007, 1:19 PM 1163 in reply to 1143

    Re: DirectorySearcher.PageSize Property

    Ah yes, your 5.1 example does work for me as well. Tell me is this way the preferred or better way to find the Search Root? Does DirectoryEntry actually use the rootDSE underneath, and does essentially what I'm doing up above example 5.1?

    -Patrick

  •  06-11-2007, 4:58 PM 1164 in reply to 1163

    Re: DirectorySearcher.PageSize Property

    Hmm... so after a little more testing with your 5.1 example I do see some differences. Using RootDSE I get back a serverless AdsPath with DNs. Used with the GC it looks like:

    GC://dc=corp,dc=net

    With the 5.1 example I get a path of

    GC://corp.net

    Using both of these in a subsequent search for 'domain' objects using SearchScope of OneLevel, with the 5.1 example I get back nothing! With the rootDSE Path, with DNs, I get back domain objects, as expected.

    At this point it seems like my RootDSE example up above would be the more comprehensive and stable search root to use.

    I am not altogether sure why the 5.1 example doesn't give good results. Perhaps a DNS issue and it would be better to have DNs in the path instead? Thoughts?

  •  06-11-2007, 6:32 PM 1166 in reply to 1164

    Re: DirectorySearcher.PageSize Property

    The difference is the subtree search versus the onelevel search.  Whereas the string concatenation method has already specified the partition to search, the GC children enumeration has only specified what is essentially the server portion of the binding string, so it sits above the partitions.

    Your method is probably going to be a little more efficient because it will not search the other partitions.  I forget, can you use the ActiveDirectory namespace, or are you stuck on 1.1?  A better method yet might be to use the Forest class to enumerate all the domains.  It is pretty easy to do.

    I am always a little wary of using string concatenation anywhere and I try to avoid it when possible because of formatting problems that can occur.  My gut tells me you are probably going to be fine using your string concat method, however, so it might be worth the small risk.
    Ryan Dunn
    Extemporaneous Mumblings
    The .NET Developer's Guide to Directory Services Programming
  •  06-11-2007, 10:35 PM 1167 in reply to 1164

    Re: DirectorySearcher.PageSize Property

    Why are you doing a one level search there?  When you use a path like this:

    GC://corp.net

    That should essentially use a null search base and search across the entire forest, regardless of the NC names.  This is useful in forests with a disjoint namespace.  However, you would do a subtree search that way.

    GC://corp.net/DC=corp,DC=net

    This path would just provide a domain hint to the GC provider to ensure that it actually finds a GC in the specified forest, but would limit the search scope to objects under that NC.  If that is the forest root domain and all other domains are children of that, then it should work, but you'd still probably want a subtree query.

    Note also that there is a nifty feature in Windows LDAP called a "phanton root" query that basically lets you search across multiple different partitions at once without using the GC.  Unfortunately, it isn't (yet) exposed by SDS, so you have to resort to the SDS.Protocols API.

  •  06-12-2007, 2:26 PM 1172 in reply to 1167

    Re: DirectorySearcher.PageSize Property

    Thanks guys,

    I would prefer NOT using a string concat, like you said. I don't know if it would work in ALL cases for a given customer and would prefer NOT doing that. I am NOT tied to 1.1, I can use 2.0 SDS.AD. I played around with the Forest.GetCurrentForest().FindGlobalCatalog(). That actually works great, but same thing, I cannot use the SearchScope.OneLevel. I end up getting zero results. Matter of fact, that OneLevel flag only seems to work in very limited cases, like the one I use above with string concat. This is bothersome to me because I would like to search OneLevel deep for other objects besides just 'domain' objects (domainDNS, OUs, etc).

    Yes I DO see that Sublevels will give me back all objects, but then I get more objects than I need. I really just want objects OneLevel down. I notice that using the Forest.GetCurrentForest().RootDomain gives me back an LDAP path that DOES in fact find objects at OneLevel OK, but there again is a problem because I have to specify ReferralChasing.All, which won't work with Paged Searches!? Damned if you do, damned if you don't it seems. What would either of you recommend?

     

  •  06-12-2007, 6:11 PM 1174 in reply to 1172

    Re: DirectorySearcher.PageSize Property

    I think the problem is that the domainDNS objects are not necessarily "one level down" from the perspective of the GC.  To be honest, I don't know what one should expect to get from doing a one level search on the GC with a null base DN, as I'm not sure what are considered immediate children of the "GC root".  The RootDomain should give you a DN for the forest root which should then have the immediate child domains.

    Honestly, I'm not sure what I'd recommend here.  This would be a good question for Joe Richards.  :)

Page 1 of 2 (19 items)   1 2 Next >
View as RSS news feed in XML