Remove-adcomputer : the directory service can perform the requested operation only on a leaf object

I was performing server account clean up in AD an received the following error when running the Remove-ADComputer PowerShell cmdlet.

The directory service can perform the requested operation only on a leaf object

Remove-adcomputer : the directory service can perform the requested operation only on a leaf object
 


 It turns out, this server was not a leaf object.  Since it had child objects the Remove-ADObject cmdlet must be used to remove it from the domain. 


Running the following command removed the server from the domain:

get-adcomputer -identity servername | remove-adobject -recursive

Remove-adcomputer : the directory service can perform the requested operation only on a leaf object


Hello! I've recently joined a new organization who was not cleaning up their AD environment. I've implemented a script to move/disable devices older than 90 days and delete devices older than 210 days. I successfully deleted roughly 4200 devices but am stuck with about 180 that will not delete. Long story short, it looks like devices with child objects will not delete. Computer objects without a child object delete without issue. Some details:

-Using a service account with the correct permissions

-Manually running via Powershell produces the errors

-Running with highest privileges as a scheduled task produces the errors

-Running ADAC as the same service account DOES ALLOW ME TO DELETE IT WITH NO ERRORS

-Using Effective Access I can verify that the service account has permissions to delete child objects on both the Computer object and child object.

-Prevent from Accidental Deletion is NOT checked on either the Computer object or the Child Object

Commands I've tried:

This is in theory easy, just import the ActiveDirectory module:

Import-Module ActiveDirectory

and then remove the computer:

Remove-ADComputer -Identity "computername"

Except that sometimes it fails with:

Remove-ADComputer : The directory service can perform the requested operation only on a leaf object At line:1 char:1 + Remove-ADComputer -Identity computername + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~     + CategoryInfo          : NotSpecified: (CN=computername,O...rcmtech,DC=co,DC=uk:ADComputer) [Remove-ADComputer], ADException     + FullyQualifiedErrorId : The directory service can perform the requested operation only on a leaf object,Microsoft.ActiveDirectory.Management.Commands.RemoveADComputer

But yet other times it works fine. It turns out that a computer account is not always a “leaf” in Active Directory – it can be a container and have child objects within it. I’d been adding Windows Server 2012 virtual machines to my Active Directory, they were Hyper-V VMs created using System Center Virtual Machine Manager 2012 SP1 beta. The Hyper-V hosts I am using are also Server 2012.

Looking at the VMs in ADSI Edit showed that they had a “Windows Virtual Machine” object within them:

ADSI Edit  Default naming context [dc01.rcmtech.co.uk]   DC=internal,DC=rcmtech,DC=co,DC=uk    OU=Servers     CN=computername      CN=Windows Virtual Machine

Thus the only way to delete these is to use Remove-ADObject with the -Recursive option, which deletes the object plus any child objects. Unlike Remove-ADComputer which accepts a computer name as the -Identity option, you have to pass in a computer object to Remove-ADObject:

$ComputerToDelete = Get-ADComputer -Identity "computername" Remove-ADObject -Identity $ComputerToDelete -Recursive

Whilst we’re on the subject, I also found that Get-ADComputer seems to ignore the -ErrorAction SilentlyContinue option (which stops it putting a red error on screen during ps1 script execution). It also doesn’t behave the same way as some other cmdlets I was using when it doesn’t find a computer. Thus, the code block I’m using to look for a computer in AD and delete it if it exists, with no errors on screen if it does not exist, is as follows:

$advm = "" try{     $advm = Get-ADComputer -Identity $NewVMName } catch {     Write-Host "No existing AD account found" } if ($advm -ne ""){     Write-Host "Remove existing AD account..."     $x = Remove-ADObject -Identity $advm -Recursive }

Not perfect, but does the job.

This entry was posted in PowerShell, Scripting, Windows and tagged active directory, leaf object, powershell, remove-adcomputer, remove-adobject, scvmm, virtual machine manager, vmm, windows. Bookmark the permalink.

So, as I mentioned the other day, we needed to do some major cleanup of defunct and orphaned computer accounts. Most computers that hadn’t been logged in to in the last year needed to go. And there were a LOT of them! Certainly more than anyone wanted to try to do in the GUI. So, having found them, it was time to remove them, using:

$oneyear = (Get-Date).AddDays(-365) Get-ADComputer -Filter {(LastLogonDate -lt $oneyear ) -AND ` ((Name -like "ws-*") -OR (Name -like "Desktop*") -OR (Name -like "XP-*"))}

-Properties LastLogonDate | Remove-ADComputer -Confirm:$False -Verbose

And I started watching the deletions go by on the screen. Honestly, a fairly scary moment. Especially when I started to see some errors scroll by..

VERBOSE: Performing the operation "Remove" on target "CN=WS-DCOVENTRY-02,OU=\#Workstations,DC=Contoso,DC=com". VERBOSE: Performing the operation "Remove" on target "CN=WS-VTAWARE-02,CN=Computers,DC=Contoso,DC=com". VERBOSE: Performing the operation "Remove" on target "CN=WS-VIMALG-02,CN=Computers,DC=Contoso,DC=com". VERBOSE: Performing the operation "Remove" on target "CN=WS-FHEMMATI-02,OU=\#Workstations,DC=Contoso,DC=com". VERBOSE: Performing the operation "Remove" on target "CN=WS-BGL-ECOM,CN=Computers,DC=Contoso,DC=com". Remove-ADComputer : The directory service can perform the requested operation only on a leaf object At line:1 char:228 + ... LogonDate | Remove-ADComputer + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (CN=WS-BGL-ECOM,...C=Contoso,DC=com:ADComputer) [Remove-ADComputer], ADExce ption + FullyQualifiedErrorId : ActiveDirectoryServer:8213,Microsoft.ActiveDirectory.Management.Commands.RemoveADCompute r

I ended up with about 15% of the computer accounts refusing to be removed with Remove-ADComputer. So I checked the man pages for Remove-ADComputer, and there were no additional parameters that would overcome it. Well, phooie!

OK, so time to haul out the seriously powerful tool, Remove-ADObject -Recursive. A word of warning here — you can do some serious damage with this command.  First, I verified the cause of the failures — the offending computer accounts had subsidiary objects that they probably shouldn’t ever have had. OK, all that was before my time, but none of them were any longer relevant. So, now, my command needed to morph due to the somewhat more annoying syntax of Remove-ADObject. I couldn’t just pipe the results of Get-ADComputer to it, I needed to return a list of objects and walk through them with a ForEach loop, like this:

$oneyear = (Get-Date).AddDays(-365)
$adFilter = {(LastLogonDate -lt $oneyear ) -AND ((Name -like "ws-*") -OR (Name -like "Desktop*") -OR (Name -like "XP-*"))}

ForEach ($Computer in (Get-ADComputer -Filter $adFilter -Properties LastLogonDate)) { Remove-ADObject $Computer -Recursive -Confirm:$False -Verbose

}

And there go the last of the orphaned accounts! Notice, by the way, the use of a variable to hold the filtering criteria. This is a useful trick if you’re iterating through a bunch of filters, or dealing with a fairly long and complicated one. You need to edit the variable with each iteration, but the actual command stays the same. Plus, IMHO, it makes the whole thing more readable.

If you come across this error when using Powershell to delete an object, it is most likely because the object has child objects associated with it.  The most obvious example is computer objects that have print queue, service connection point, RRAS or various other types of child objects.  The workaround is to determine the child object (to see if it might be required) and then to delete the objects recursively as shown below.

In this example we have a computer object named “Foo”.  If we try and delete it using the Powershell AD cmdlet Remove-ADComputer we see the “leaf object: error.

Remove-adcomputer : the directory service can perform the requested operation only on a leaf object

We can then use some other Powershell goodness to determine the type of child object that we have.  In this case a service connection point object.

Remove-adcomputer : the directory service can perform the requested operation only on a leaf object

Once we’re happy that deleting the child object won’t cause any other issues, we can use the Remove-ADObject cmdlet together with the –Recursive switch to delete both the computer and the service connection point objects.

Remove-adcomputer : the directory service can perform the requested operation only on a leaf object