Ugh - Active Directory Powershell Cmdlets time out or takes Forever!

 

This happens to me more than you can imagine,  when performing simple searches against large Active Directory environments the query will sometimes fail by timing out. The irony is the same cmdlet may have completed successfully a number of times before it starts failing.   This blog wont cover how to troubleshoot this issue, or tell you how to modify ldap settings. The goal is to share a technique I started using with VBScript years ago and now doing it with PowerShell. 

Here we go, instead of searching for a user with a particular attribute in the entire domain, set a searchbase and searchscope on the cmdlet. 

Example:

 Get-ADuser -LDAPFilter "(&(Admincount=*))" -searchbase "OU=Users,OU=Charolette,OU=Standard Objects,OU=CHARLIE,DC=corp,DC=contoso,DC=ad" -SearchScope OneLevel

But wait, this returns just the users inside the OU that contains a value in the AdminCount attribute?  This is so much faster than searching for a user object in the entire forest due to there only being a subset of users in that location. However this doesn’t fully help, Going OU by OU does not save time if there is a need to enter in a new OU after it finishes.  This is how I go about looking in every OU in every domain of the forest.

Example:

 (get-adforest).domains | foreach{$_domain = $_ ;Get-ADOrganizationalUnit -filter * -server $_domain | foreach {Get-ADuser -LDAPFilter "(&(Admincount=*))" -properties admincount -searchbase $(($_).DistinguishedName) -SearchScope OneLevel -server $_domain}}

This usually starts returning results instantly. 

To break this script down (get-adforest).domains gets me a list of each domain in a forest.  I pipe the results and use a foreach loop to make sure to perform the action against  each domain, a domain variable is set and used to enumerate every OU from that domain. Each OU Object’s distinguishedname  is then piped to the get-aduser command’s –searchbase parameter  and the $domain variable is used in the server parameter.  This will ensure that the get-aduser command will know what domain controller to query to find a particular OU and its get it’s direct user objects.

Hopefully that made sense.

Now the problem with this is not every user object is stored in an OU some could be stored in a container.  There is no good way to get just the containers with the object type that is being searched for, but I found that setting the object class to gather all the ou’s and containers is actually really fast.

 (get-adforest).domains | foreach{$_domain = $_ ;Get-ADObject -ldapFilter "(|(objectclass=organizationalunit)(objectclass=container))" -server $_domain | foreach {Get-ADuser -LDAPFilter "(&(Admincount=*))" -properties admincount -searchbase $(($_).DistinguishedName) -SearchScope OneLevel -server $_domain}}

 

Give it a try and have a good day!!!

-Chad