Active Directory Friday: Find empty Organizational Unit

As an Active Directory Administrator there are some moments, few and far in between where you might have a moment to yourself. In this article I will give you a short line of code so you can use this moment to find out if you have any empty Organizational Units in your domain. The definition of empty is an OU that does not contain any child objects. By this definition an OU containing another OU would not be considered empty. Because there is no LDAP filter for this we will take a look at how to do this using the Cmdlets and the [adsisearcher] type accelerator.

In the following example I will use Get-ADOrganizationalUnit in combination with an if-statement and Get-ADObject to gather empty OUs:

1
2
3
4
5
Get-ADOrganizationalUnit -Filter * | ForEach-Object {
	   if (-not (Get-ADObject -SearchBase $_ -SearchScope OneLevel -Filter * )) {
      		$_
   	}
}

So lets have a look at what this code does, the first portion is straight forward, gather all OUs using the Get-ADOrganizationalUnit cmdlet and pipe it into the ForEach-Object cmdlet. The if-statement is the interesting part here, I am using the Get-ADObject cmdlet to establish if this OU contains any child object, by setting the SearchBase to that OU and setting the SearchScope to OneLevel. Setting the SearchScope to OneLevel will only return direct child objects of the parent, the OU, without returning the OU itself. Because of this Get-ADObject will not return any objects if the OU is empty.

For more information about the SearchScope parameter and the possible arguments have a look at the following link: Specifying the Search Scope

Because you might not have the ActiveDirectory module loaded in your current PowerShell session it can be useful to know the [adsisearcher] alternative:

1
2
([adsisearcher]'(objectcategory=organizationalunit)').FindAll() | Where-Object {
   -not (-join $_.GetDirectoryEntry().psbase.children) }

This is a slightly different approach to illustrate a different method of gathering empty OUs, here we check the Children property part of the base object that is retrieved. The -join operator is used to ensure the -not does not evaluate the empty System.DirectoryServices.DirectoryEntries object as true.

Using the logic in this post it is also possible to filter for other specific objects contained in the OUs. For example display OUs that only have user objects, display OUs with both user and computer objects and so on.

For more information on this subject please refer to the following links:

Additional resources
Specifying the Search Scope
Get-ADObject
Get-ADOrganizationalUnit

Leave a Reply

Your email address will not be published.