Over the course of the last several articles, I have been demonstrating how to find Active Directory objects using the Active Directory Searcher Object from .NET and PowerShell. I have purposely kept my examples simple and constrained but today we are running free. I need to show you how to manage large environments.

I know that my domain has 6351 user accounts. Let’s see what I get with the searcher object.



1 2 3 $searcher = New-Object system . DirectoryServices . DirectorySearcher $searcher . filter = "(objectclass=user)" $all = $searcher . FindAll ( )



Total Users Found (Image Credit: Jeff Hicks)

Well, that cannot be right. Actually, it is. By default, the searcher object will only return the first 1000 matching objects. Heaven forbid that we ask a server to do any work! The solution is to modify the searcher’s PageSize property. The default value is 0. You can set it to a new value and PowerShell will return matching objects in pages or groups of that number.



1 2 3 $searcher . PageSize = 100 $all = $searcher . FindAll ( ) $all . count



I have experimented with different page sizes and cannot seem to find any value that is necessarily better than another. I tend to use 100 but you should experiment in your own test environment.

Regardless, $all now has 6447 objects! I have cleared the first hurdle and appear to be getting more than 1000 objects. However, I have even more than expected.

My searcher is defaulting to the domain root, so I know it is not missing anything. Using my Convert-ADSearchResult function from a previous article, I can group the results on the object type.

Grouping Results by Object Type (Image Credit: Jeff Hicks)

This is interesting, especially for those of you who are not up to speed on LDAP schemas. When we refer to a user account, this is also a Person. Likewise, computer accounts can be counted as Users. The solution is to refine my search filter.



1 2 $searcher . filter = "(&(objectcategory=person)(objectclass=user))" $all = $searcher . FindAll ( )



If you recall in a previous article, I showed you how to create a compound filter. Let’s check again.

Refined Search Results (Image Credit: Jeff Hicks)

If you are searching for users or other specifics in a large environment, you might need filters like this:



1 2 $searcher . filter = "(&(objectcategory=person)(objectclass=user)(name=mysampleuser3*))" $searcher . findall ( )



Limiting Search (Image Credit: Jeff Hicks)

Or keep extending your filter:



1 2 $searcher . filter = "(&(objectcategory=person)(objectclass=user)(name=a*)(title=tester))" $searcher . findall ( )



Using a Compound Search Filter (Image Credit: Jeff Hicks)

That filter may look complicated. I will admit, they can be tricky to write. Let’s look at a trick.

Open Active Directory Users and Computers. Right-click on Saved Queries and select New – Query.

New Active Directory Query (Image Credit: Jeff Hicks)

If you plan on saving the query, you can enter a name. Otherwise, click the Define Query button. Use the dialogue box to configure whatever query you need.

Defining a Custom Query (Image Credit: Jeff Hicks)

I am going to build a query to find all disabled accounts. Click OK. You should now see the LDAP query string.

Subscribe to Petri Newsletters Office 365 Insider Our Petri Office 365 Insider is dedicated to sharing detailed knowledge from top Office 365 experts. Delivered once a month to your inbox. All Newsletters Petri.com may use your contact information to provide updates, offers and resources that may be of interest to you. You can unsubscribe at any time. To learn more about how we manage your data, you can read our Privacy Policy and Terms of Service. !Already a Petri.com member? Login here for 1-click registration.

Getting the LDAP Query String (Image Credit: Jeff Hicks)

You can select that text and copy it to Clipboard. Use that as your new search filter.



1 2 3 $searcher = New-Object system . DirectoryServices . DirectorySearcher $searcher . filter = "(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))" $searcher . PageSize = 100



There is no way I could have figured out that query on my own.

Showing Disabled Accounts (Image Credit: Jeff Hicks)

Now, I could pipe $disabled to Where-Object and filter out things like Guest. That would be easier than trying to modify the filter. A better choice would be to restrict my search scope.

Limiting the Search (Image Credit: Jeff Hicks)

You could use the Saved Query wizard to get the filter syntax for your common search needs and create a set of PowerShell tools. In fact, I have given you a number of PowerShell functions that could serve as the starting point for your own toolbox. I might put together my own module when I have a little time. Although, I happened to check the PowerShell Gallery and found a very complete module called AdsiPS from fellow MVP Francois-Xavier Cat. He has assembled a complete toolkit that uses ADSI from the .NET Framework to manage Active Directory. This is very similar to what I have been demonstrating. None of it should require the RSAT Active Directory module. Run Install-Module AdsiPS to download and install it in your test network.

I hope you have found this series helpful. As always, comments welcome.