Get-EmptyOUs.ps1


Description

Purpose

Retrieves and optionally removes empty Active Directory Organizational Units (OUs).

Detailed Description

The Get-EmptyOUs function retrieves all organizational units (OUs) in Active Directory and checks if they are empty. It can optionally remove the empty OUs if specified.

Back to Top

Usage

Example 1

Get-EmptyOUs -RemoveOUs $false

Retrieves and lists the distinguished names (DNs) of the empty OUs without removing them.

Example 2

Get-EmptyOUs -RemoveOUs $true -OUsToKeep "OU=TestOU,DC=example,DC=com"

Retrieves and removes the empty OUs, excluding the OU with the specified distinguished name.

Back to Top

Notes

This function requires the Active Directory module to be installed. It should be run with appropriate permissions to manage OUs in Active Directory.

Back to Top


Script

<#
.SYNOPSIS
Retrieves and optionally removes empty Active Directory Organizational Units (OUs).

.DESCRIPTION
The Get-EmptyOUs function retrieves all organizational units (OUs) in Active Directory and checks if they are empty. It can optionally remove the empty OUs if specified.

.PARAMETER RemoveOUs
Indicates whether to remove the empty OUs. If $true, empty OUs will be removed. If $false, only a list of empty OUs will be returned.

.PARAMETER OUsToKeep
An array of distinguished names (DNs) of OUs to exclude from removal, even if they are empty.

.EXAMPLE
Get-EmptyOUs -RemoveOUs $false
Retrieves and lists the distinguished names (DNs) of the empty OUs without removing them.

.EXAMPLE
Get-EmptyOUs -RemoveOUs $true -OUsToKeep "OU=TestOU,DC=example,DC=com"
Retrieves and removes the empty OUs, excluding the OU with the specified distinguished name.

.NOTES
This function requires the Active Directory module to be installed. It should be run with appropriate permissions to manage OUs in Active Directory.
#>
function Get-EmptyOUs {
    
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $false)]
        [bool]$RemoveOUs = $false,
        [Parameter(Mandatory = $false)]
        [string[]]$OUsToKeep = @()
    )


    function Get-AdOrganizationalUnits {
        Get-ADObject -Filter "ObjectClass -eq 'organizationalUnit'" | Where-Object { $_.DistinguishedName -notlike '*LostAndFound*' }
    }
    
    function Get-EmptyAdOrganizationalUnits($ad_ous) {
        $aOuDns = @()
        foreach ($o in $ad_ous) {
            $sDn = $o.DistinguishedName
            if ($sDn -like '*OU=*') {
                $sOuDn = $sDn.Substring($sDn.IndexOf('OU='))
                $aOuDns += $sOuDn
            }
        }
    
        $a0CountOus = $aOuDns | Group-Object | Where-Object { $_.Count -eq 1 } | ForEach-Object { $_.Name }
        return $a0CountOus
    }
    
    function IsAdOrganizationalUnitEmpty($ou_dn) {
        $child_objects = Get-ADObject -Filter "ObjectClass -ne 'organizationalUnit'" -SearchBase $ou_dn -SearchScope OneLevel -Properties ObjectClass
        $child_ous = Get-ADObject -Filter "ObjectClass -eq 'organizationalUnit'" -SearchBase $ou_dn -SearchScope OneLevel -Properties ObjectClass
        return ($child_objects.Count -eq 0 -and $child_ous.Count -eq 0)
    }
    
    function RemoveAdOrganizationalUnit($ou_dn) {
        Set-ADOrganizationalUnit -Identity $ou_dn -ProtectedFromAccidentalDeletion $false -confirm:$false
        Remove-AdOrganizationalUnit -Identity $ou_dn -confirm:$false
    }

    $ad_ous = Get-AdOrganizationalUnits
    $a0CountOus = Get-EmptyAdOrganizationalUnits $ad_ous
    $empty_ous = 0
    $ous_removed = 0
    foreach ($sOu in $a0CountOus) {
        if (IsAdOrganizationalUnitEmpty $sOu) {
            $ou_dn = (Get-AdObject -Filter { DistinguishedName -eq $sOu }).DistinguishedName
            if ($OUsToKeep -notcontains $ou_dn) {
                if ($RemoveOUs) {
                    RemoveAdOrganizationalUnit $ou_dn
                    $ous_removed++
                }
                else {
                    Write-Output $ou_dn
                }
                $empty_ous++
            }
        }
    }

    if ($empty_ous -gt 0) {
        Write-Output '-------------------'
        Write-Output "Total Empty OUs Removed: $ous_removed"
        Write-Output "Total Empty OUs: $empty_ous"
    }
    else {
        Write-Output 'No empty OUs found.'
    }
}

Back to Top

Download

Please feel free to copy parts of the script or if you would like to download the entire script, simply click the download button. You can download the complete repository in a zip file by clicking the Download link in the menu bar on the left hand side of the page.


Report Issues

You can report an issue or contribute to this site on GitHub. Simply click the button below and add any relevant notes. I will attempt to respond to all issues as soon as possible.

Issue


Back to Top