Removing leaf objects from Active Directory

 

Not recently I had a customer whose migration , one way or another, was being blocked due to leaf objects existing under an AD User entry. They said they couldn't find any script online through Google or Bing that they could "borrow". I'm not really an Active Directory guy but I like scripting so I took a stab at it.

In these scripts the usual suspects you may want to modify include but aren't limited to:

  • Search Root
  • (LDAP)Filters in case you don't want to remove the leaf objects underneath all users
  • User Output

 

The Script using AD Cmdlets

 param
(
    $root = "ou=myTestOU,dc=contoso,dc=com"
)# Import the AD Module
Import-Module ActiveDirectory
# Get all users using a provided searchbase.
$users = Get-ADUser -Filter * -SearchBase $root
# Loop through the users
foreach($user in $users)
{
    # Find all AD objects one level below the user
    $objs = Get-ADObject -Filter * -SearchScope `
    oneLevel -SearchBase $user.DistinguishedName
    
    # Performance a recursive delete to remove those leaf objects
    if($objs)
    {
        Write-Host "Removing leaf objects..."        
        $objs | Remove-ADObject -Recursive
    } 
}

 

 

The Script using direct .NET Framework access

 param
(
    $root = "LDAP://ou=MyTestOU,dc=contoso,dc=com",
    $scope = "subtree",
    $LDAPFilter = "(&(objectcategory=User))"
)# Set up the DirectorySearcher object
$s = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$s.SearchRoot = [adsi]$root
$s.SearchScope = $scope
$s.Filter = $LDAPFilter
# Find all matches
$result = $s.FindAll()
# Enumerate through all matches
foreach ($item in $result)
{
    $entry = $item.GetDirectoryEntry()    
    # Enumerate through the children and delete them
    foreach($obj in $entry.children)
    {
        "Deleting $($obj.DistinguishedName)"
        $leaf = [adsi]"LDAP://$($obj.DistinguishedName)"
        $leaf.psbase.DeleteTree()
    }
}