Restore OU-tree from AD Recycle Bin with PowerShell
[TL;DR: I’ve written a script to bulk restore objects from Active Directory Recycle Bin, it is available on TechNet Galleries]
Active Directory Recycle Bin
The Active Directory Recycle Bin is a nifty feature introduced with Windows Server 2008 R2 and makes it possible to undo an accidental deletion of an Active Directory object. This means that if the Active Directory Recycle Bin is enabled, all link-valued and non-link-valued attributes of a deleted object are preserved and the object can be restored in its entirety.
To enable Active Directory Recycle bin, the forest functional level has to be at least on Windows Server 2008 R2. Also note that enabling the Recycle Bin is an irreversible action. The recommended way of enabling the Recycle Bin is by using the PowerShell cmdlet Enable-ADOptionalFeature for example like this:
$Forest = (Get-ADForest).Name Enable-ADOptionalFeature -Identity 'Recycle Bin Feature' -Scope ForestOrConfigurationSet –Target $Forest
How the Recycle Bin works
First off, the amount of time an object will be recoverable is called deleted object lifetime and is by default set to 180 days. The container CN=Directory Service,CN=Windows NT, CN=Services, CN=Configuration, DC=ad,DC=simonw,DC=se has an attribute named msDS-deletedObjectLifetime which controls the deleted object lifetime.
To change this value using PowerShell I use the following code:
$DeletedObjectLifetime = 190 $RootDSE = Get-ADRootDSE $Configuration = $RootDSE.configurationNamingContext $Params = @{ Identity = “CN=Directory Service,CN=Windows NT,CN=Services,$Configuration” Partition = $Configuration Replace = @{'msDS-DeletedObjectLifetime' = $DeletedObjectLifetime} } Set-ADObject @Params
Now when someone deletes an object from Active Directory it is actually moved to the container CN=Deleted Objects,DC=ad,DC=simonw,DC=se and its attribute isDeleted is set to TRUE. This state is called logically deleted and lasts for a deleted object lifetime.
Restoring Single Objects
Once the recycle bin is enabled, a single deleted object can easily be restored by using the Active Directory Administrative Center by navigating to the container ‘Deleted Objects’, right clicking the object and choose ‘Restore’.
Or we could of course use PowerShell:
What I do here is to first find the user I want to restore by using Get-ADObject filtering on the attribute isDeleted to only search for deleted objects and the name being User1*. When I am sure that my query only returns the one user I want to restore I repeat the same command piping it to Restore-ADObject.
This is all great until someone accidentally deletes a whole OU structure.
If I want to restore an object whose last known parent doesn’t exist it becomes a bit of a hassle locating and restoring that parent before the itself object can be restored. And if a whole OU structure is deleted (yeah I know there should be protection against accidental deletions, but that’s a whole other story) restoring can be a pain.
This is where my friend Jimmy Andersson wrote a script which he demonstrated in a session in Åre in may 2014.
With his blessings I rewrote that script, implemented a few PowerShell best practices, error handling and extended the functionality a bit. The script supports two ways of restoring objects, by Identity or by LastKnownRDN.
Restoring any Deleted object within an OrganizationalUnit (by Identity)
If I want to restore any object that used to reside in the OU OU=Corporate,DC=ad,DC=simonw,DC=se simply run the script like this:
.Restore-ADTree.ps1 –Identity ‘OU=Corporate,DC=ad,DC=simonw,DC=se’ –Verbose
To also restore any object that used to reside in any live sub-OU I simply add the parameter –IncludeLiveChildren and if I want to output all restored objects I add the parameter –PassThru.
Restoring a deleted OU and all its child objects (by LastKownRDN)
Now if I accidently deleted one OU and I don’t want to restore every child object to the parent of that OU there is another way of running the script.
Lets for example say that I deleted the following OUs:
OU=Sales,OU=Corporate,DC=ad,DC=simonw,DC=se
OU=Market,OU=Corporate,DC=ad,DC=simonw,DC=se
The Market OU should stay deleted but I want to restore the Sales OU. The following line will perform exactly that:
Restore-ADTree.ps1 -lastKnownRDN Sales -Verbose
If I have more than one deleted object with a lastKnownRDN of ‘Sales’ I can add the parameter -lastKnownParent ‘OU=Corporate,DC=ad,DC=simonw,DC=se’ to only restore objects that used to reside within that OU and all it’s children.
Additional options and special cases
If an object is deleted and a new object is created with the same RDN and then also deleted, the script will always choose the oldest (first) deleted object.
To only restore objects deleted AFTER a certain time, use the parameter –TimeFilter.
Using the parameter –WhatIf or –Confirm when not entirely sure on what to restore.
The script in whole can be downloaded from Technet Galleries