PowerShell: Remove-ADComputer v. Remove-ADObject

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
    + FullyQualifiedErrorId : ActiveDirectoryServer:8213,Microsoft.ActiveDirectory.Management.Commands.RemoveADCompute

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.

Author: Charlie Russel

A chemist by education, an electrician by trade, a UNIX sysadmin and Oracle DBA because he raised his hand when he should have known better, an IT Director and consultant by default, and a writer by choice, Charlie is the author of more than 2 dozen computer books on operating systems and enterprise environments, including Microsoft Windows Server 2008 Administrator's Companion(MS Press), Microsoft Windows Server 2003 Administrator's Companion(MS Press), Windows Small Business Server 2011 Administrator's Companion(MS Press), Windows Essential Business Server 2008(MS Press), Introducing Windows Server 2008 R2(MS Press), Microsoft Windows XP Resource Kit, 3rd Edition(MS Press), and Oracle DBA Scripting Quick Reference(Prentice-Hall PTR). He has also written numerous white papers and case studies on Microsoft.com, most recently around Windows HPC Server, and RDS Licensing.

4 thoughts on “PowerShell: Remove-ADComputer v. Remove-ADObject”

  1. I have been working on something like:
    $compObjects = get-adobject -Filter * -SearchBase $obj.DistinguishedName
    If ($compObjects.count -gt 1) {
    # Delete computer and leaf objects
    ForEach ($leaf in $compObjects) {
    remove-adobject $leaf -Confirm:$false
    Else {
    $obj | remove-adcomputer -Confirm:$False -Force
    To only use remove-adobject when necessay

    1. Interesting. (Though I note that you expected -Force to be an option just as I did. But it isn’t.) Certainly, that approach would work.

Leave a Reply

Your email address will not be published. Required fields are marked *