Find objects in LostAndFound ... for all partitions

I was onsite again today, and we were talking about the Lost and Found container in AD. You know, the one where you sometimes find objects without a clear reason of why they end up there. Before we delve into the PowerShell code, let me briefly explain what it's for.

Suppose you have two DCs, DC1 and DC2.

  1. You create a new user, called TEST2 in an organizational unit called myOU. You do this on DC1.
  2. At the same time you remove myOU on DC2.
  3. Replication happens. User TEST2 is replicated to DC2 where it encounters an impossible situation: there is no parent object!
  4. On DC2, AD moves TEST2 to the container CN=LostAndFound in the root of the domain partition, and sets the attribute lastKnownParent to ... the location of the last known parent.
  5. This new configuration gets replicated back to DC1, where myOU gets deleted as well, and the user moved to LostAndFound. At this point, everything is legal and consistent.

This happens as part of normal operations, and experienced admins know that they need to check for this. However, it is not so well known that all partitions have a LostAndFound container, although this should be obvious in hindsight. In a single domain forest you would have five partitions (normally): domain, configuration, DomainDNSZones, ForestDNSZones, and the Schema. Microsoft didn't bother to create a LostAndFound for the schema partition (why not, do you know?), but the others have the container.

For the occasion I wrote a quick script to look for objects in LostAndFound for all partitions in a single domain forest. This is it:

# Find objects in Lost&Found containers; limited to single-domain forest.
(Get-ADRootDSE).NamingContexts | ForEach-Object {
if ($_ -like "CN=Configuration,DC=*")
$lostandfoundcontainer = "cn=LostAndFoundConfig,$($_)"
} elseif ($_ -like "CN=Schema,CN=Configuration,DC=*") {
} else {
$lostandfoundcontainer = "cn=LostAndFound,$($_)"
Get-ADObject -Filter * -SearchBase $lostandfoundcontainer -SearchScope Subtree -Properties lastKnownParent |
Where-Object { $ -notlike "LostAndFound*" } |
Add-Member -MemberType NoteProperty -Name Partition -Value $_ -Force -PassThru

We connect to the RootDSE of a DC in the domain, and get the list of Naming Contexts (partitions). This gets piped into a loop where we first check for special cases. The configuration container has a specially named Lost&Found container, and the Schema has none. Once we have the full DN, we get all child objects including the lastKnownParent attribute that tells you where it came from. We discard the LostAndFound containers themselves, and finally we put the object back into the pipeline with the name of the partition added for easy viewing. This is what it looks like in my relatively clean lab:

What do you do with these objects once you have them? Most of the time, they are not in use and can be removed. Very rarely you will find one that is in active use. I once had a working computer account there. Checking the whenChanged attribute will usually tell you enough.