Quickly Find and Move Stale Computers in AD

It is fairly common to see poor housekeeping in Active Directory environments, due to proper onboarding/decommissioning procedures not being established, not automated, or simply not followed. The good news is that Active Directory “Directory Services” role comes with a few very neat utilities that take the pain and wondering (and even scripting) out of the cleanup process. They are: dsadd, dsget, dsmod, dsmove, dsquery, and dsrm.

dsquery computer -inactive 4 -limit 2000 >c:\inactive4.txt

The command above will dump distinguished names of all computer objects that have not contacted Active Directory for more than 4 weeks, into a text file called inactive4.txt. -inactive can be manipulated to extend offline time “allowance”, which would be helpful in a traveling laptop use case.

Instead of redirecting output into a text file, you can pipe it to another command (such as “dsrm” that would delete matching objects from AD, or “dsmove” that can be used to move matching objects to another “stale” or “disabled” OU).

Same but in VB.NET

If you need a little extra firepower, or some custom decision making in selecting the right OU for the move of a particular computer object or sets of computer objects, you could do the same with VB.NET.

Private Sub MoveComputers()
Dim file As New StreamReader("C:\inactive4.txt")
Dim comp As DirectoryEntry
Dim destOU As New DirectoryEntry("LDAP://OU=Disabled,OU=Computers,OU=Canada,DC=adDOMAIN,DC=adTLD")
While Not file.EndOfStream
comp = New DirectoryEntry("LDAP://" & file.ReadLine)
comp.MoveTo(destOU)
Console.WriteLine("moved " & comp.Properties("Name").Value)
End While
End Sub

That’s really it (OK maybe not quite; depending on your scale, you may want to add error handling and clean up your variables at the end). With just one line of code you can feed your text file as an input into a VB.NET function – it does not get any simpler. This code reads the file that was created using dsquery above one line at a time, connects to the specified AD object using LDAP provider + DN, and moves it to the new parent OU (hardcoded). Modify as necessary.

What About DNS

If Active Directory is littered with stale computer objects, it may be indicative of a lack of proper housekeeping elsewhere. Check Active Directory DNS zone for evidence of A records that bear 1+ month old timestamps. If you find a few (or a few thousand) records with such timestamps, there’s junk in DNS that should be cleaned up as well.

DNS scavenging is the mechanism that is responsible for cleanup of DNS records that clients fail to de-register dynamically. Scavenging is disabled by default and is commonly overlooked; to function properly it needs to be enabled in two places, at the AD zone level as well as on at least one domain controller at the DNS server level. Refer for this excellent TechNet article for more information on DNS scavenging functionality and configuration.