|
|
DirectorySearcher.PageSize Property
Last post 06-13-2007, 10:24 PM by joe. 18 replies.
-
05-21-2007, 7:02 PM |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
joe
-
-
-
Joined on 04-05-2006
-
Chicago, IL
-
Posts 2,866
-
-
|
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 |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
joe
-
-
-
Joined on 04-05-2006
-
Chicago, IL
-
Posts 2,866
-
-
|
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 |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
joe
-
-
-
Joined on 04-05-2006
-
Chicago, IL
-
Posts 2,866
-
-
|
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 |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
dunnry
-
-
-
Joined on 04-05-2006
-
Seattle, WA
-
Posts 682
-
-
|
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 MumblingsThe .NET Developer's Guide to Directory Services Programming
|
|
-
06-11-2007, 1:19 PM |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
dunnry
-
-
-
Joined on 04-05-2006
-
Seattle, WA
-
Posts 682
-
-
|
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 MumblingsThe .NET Developer's Guide to Directory Services Programming
|
|
-
06-11-2007, 10:35 PM |
-
joe
-
-
-
Joined on 04-05-2006
-
Chicago, IL
-
Posts 2,866
-
-
|
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 |
-
patrick
-
-
-
Joined on 04-17-2007
-
Seattle WA
-
Posts 32
-
-
|
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 |
-
joe
-
-
-
Joined on 04-05-2006
-
Chicago, IL
-
Posts 2,866
-
-
|
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
|
|