Using the Active Directory Recycle Bin in Windows Server 2008 R2
In a previous article, we looked at enabling the Active Directory Recycle Bin feature. Once enabled, you can easily recover deleted objects. However, you can only recover objects that were deleted after you enabled the Recycle Bin feature. For everything else, you will need to use the “old school” procedures.
Using the Active Directory Recycle Bin with PowerShell
There is no graphical interface for recovering items from the recycle bin; you have to use Windows PowerShell, but it is not especially difficult. First, you need to load the Active Directory module.
PS C:\> Import-Module ActiveDirectory
Deleted items are stored in a super-hidden container:
PS C:\> get-addomain | select DeletedObjectsContainer DeletedObjectsContainer ----------------------- CN=Deleted Objects,DC=GLOBOMANTICS,DC=local
But you can’t simply open this container and drag objects out of it. In fact, there really isn’t any practical interface to this container, but that doesn’t really matter. When an object is deleted, it is moved to this container pretty much as is. For our purposes, Active Directory will add two key properties: IsDeleted and LastKnownParent. The former is a Boolean value that I trust is self-explanatory. The latter is the AD path to the object’s last know parent container. Because the object retains all of its last configured properties, when you restore it to its last location, it is more or less ready to go.
Say Goodbye to Traditional PC Lifecycle Management
Traditional IT tools, including Microsoft SCCM, Ghost Solution Suite, and KACE, often require considerable custom configurations by T3 technicians (an expensive and often elusive IT resource) to enable management of a hybrid onsite + remote workforce. In many cases, even with the best resources, organizations are finding that these on-premise tools simply cannot support remote endpoints consistently and reliably due to infrastructure limitations.
To find deleted objects, we can’t use the same cmdlet we’d use to find any other type of object, such as Get-ADUser. Instead we have to query for objects with
and use the
parameter. I’m assuming you know what it is you want to delete.
PS C:\> get-adobject -filter 'objectclass -eq "user" -AND IsDeleted -eq $True' -IncludeDeletedObjects -properties IsDeleted,LastKnownParent | Format-List Name,IsDeleted,LastKnownParent,DistinguishedName
This query is finding all objects that belong to the USER class and have been deleted. The Get-ADObject cmdlet acts like other Microsoft AD cmdlets in that you need to specify what other properties you want to see. You can see the results in Figure 1.
Figure 1 Enumerate Deleted User Accounts in the AD Recycle BinYou can see that the name has been modified with a deletion GUID, but not to worry. When we recover the item, we’ll get the original name.
To recover deleted objects, we’ll turn to the Restore-ADObject cmdlet. Personally, I find it easiest to pipe the results of Get-ADObject to this cmdlet. Otherwise you need to specify the object’s distinguishedname, which is a lot to type. Let’s restore Roy G. Biv to his original location.
PS C:\> get-adobject -filter 'name -like "Roy G. Biv*"' -IncludeDeletedObjects | Restore-ADObject –whatif What if: Performing operation "Restore" on Target "CN=Roy G. Biv\0ADEL:785f0f74-7dab-41c3-8bb5-37225682cc17,CN=Deleted Objects,DC=GLOBOMANTICS,DC=local".
Remember, the name has that extra stuff appended so I’m using the Like operator. The Match operator is not supported. I could also have used a property like SamAccountName or any other filter. Now that I have verified that my syntax is correct and I’m getting the object I expected, I can run the command again without –WhatIf. The Restore-ADObject cmdlet doesn’t write anything to the pipeline unless you use –Passthru. But I can tell the object was restored because I can retrieve it with Get-ADUser.
PS C:\> get-aduser -Identity "rgbiv" DistinguishedName : CN=Roy G. Biv,OU=IT,OU=Employees,DC=GLOBOMANTICS,DC=local Enabled : True GivenName : Roy Name : Roy G. Biv ObjectClass : user ObjectGUID : 785f0f74-7dab-41c3-8bb5-37225682cc17 SamAccountName : rgbiv SID : S-1-5-21-2552845031-2197025230-307725880-1130 Surname : Biv UserPrincipalName : [email protected]
By default, the object will be restored to its original location, ie the LastKnownParent property. But it is possible to direct the restore to a different location.
In my domain, the deleted user Santa Claus was originally in the domain root. The account really needs to be in the Sales OU. Here’s how:
PS C:\> get-adobject -filter 'name -like "Santa*"' -IncludeDeletedObjects | Restore-ADObject –TargetPath "OU=Sales,OU=Employees,DC=globomantics,DC=local" -passthru DistinguishedName Name ObjectClass ObjectGUID ----------------- ---- ----------- ---------- cn=Santa Claus,OU=Sal... Santa Claus user 61c00e8d-206a-4d5...
The value for –TargetPath is the container’s distinguishedname. It really is that simple. By the way, the object’s WhenChanged property will reflect the date and time the object was restored, at least until some other change is made to the object.
If you’d like to see what else you can do with PowerShell and AD, I hope you’ll track down a copy of my book, Managing Active Directory with Windows PowerShell: TFM 2nd Ed. (SAPIEN Press 2010).