Oh Snap! Active Directory Attribute Recovery With PowerShell

The Problem

Have you ever had to repopulate a batch of corrupted attributes for a large set of Active Directory objects? (Think Exchange or Lync, for example.) The Active Directory Recycle Bin is great for recovering deleted objects, but it will not help with corrupted objects. Authoritative restore is the textbook option, but there is a better way. Yes, you can buy expensive third-party products to do this, or you can use the free features in the box for your own attribute-level recovery solution for Active Directory. This blog post will explain how.

The Scenario

How do objects in Active Directory get corrupted? Let me count the ways:

  • Change controls at 3PM during universal nap time… half-awake-barely-focused-click-OOPS!
  • Joe Jr. Admin thought the change in the console would only affect his local view of the data.
  • “What does this button do?”
  • Bad feed from HR provisioning system
  • One word:  proxyAddresses
  • Freak scripting accident
  • Use the comments below to fill in the blank with your attribute corruption story.

That’s right. And there’s a ton more. It happens to the best of us at one point or another in our career. Whether we are the one that pulled the trigger or not, we will be the one to clean up the mess.

Oh Snap!

Microsoft has a long and winding road of Active Directory innovation designed to help those of us fighting in the daily trenches of IT.  We have released a number of features to help with Active Directory recovery scenarios:

  • “Protect from accidental deletion”
  • Active Directory Recycle Bin
  • Active Directory Snapshots

Wait! Snapshots! I thought we were never ever ever supposed to take snapshots of AD?!  Regarding virtualization that is correct, or was correct, until Windows Server 2012 when we introduced VMGenID. But I’m talking about an entirely different type of snapshot.

Way back in Windows Server 2008 we introduced the ability to freeze frame (80’s reference for this post) the Active Directory database. Using the Volume Shadow Copy service we snapshot the AD database for future reference. Like every other feature on TechNet there is an involved manual process to create these snapshots and then use them later. That’s where PowerShell comes to the rescue.

Note: This feature has been around for years. I am not the first to blog about it, nor am I the first to use PowerShell with NTDSUTIL SNAPSHOT. However, I wanted to offer a complete, original attribute-level recovery solution using PowerShell for the benefit of the community.

I would like to give a quick shout-out to a PFE peer who gave me a couple tips while developing this code.  Thanks, Eric Jansen!

The Solution

Using PowerShell we can automate the entire AD snapshot and attribute recovery process. Here is a simplified outline of the commands involved:

  3. DSAMAIN.EXE -LDAPPort Port#
  4. Get-ADObject -Server DC1:Port#
  5. Set-ADObject -Server DC1
  6. Get-Process DSAMAIN | Kill

Those steps are carried out by the following PowerShell functions included in this release:

  • New-ADSnapshot – Creates a new snapshot using NTDSUTIL.
  • Mount-ADDatabase – Mounts the snapshot using NTDSUTIL and advertises it using DSAMAIN. Note that DSAMAIN will launch in its own window. DO NOT CLOSE IT. It will remain open until closed by Dismount-ADDatabase. Specify a port for the snapshot to use for LDAP. In the examples below I use 33389.
  • Show-ADSnapshot – Lists all snapshots on a domain controller, noting any currently mounted.
  • Dismount-ADDatabase – Kills the DSAMAIN process and dismounts the database using NTDSUTIL.
  • Remove-ADSnapshot – Removes old snapshots using NTDSUTIL. Parameters specify how many of the first/last snapshots to keep.
  • Repair-ADAttribute – The main function for recovering AD object attribute values from snapshots. Supports single and multi-value attributes. Can restore multiple attribute values for multiple objects simultaneously.
  • Repair-ADUserGroup – A specialized function addressing recovery of group memberships for users. This can also be accomplished using the Repair-ADAttribute function.

All functions are fully documented in help. You can use Get-Help -Full to view the details, syntax and examples of each function.

This gets even better when you add PowerShell remoting to the mix. From a Windows 7 or Windows 8 workstation you can run these commands locally on a domain controller using PowerShell remoting. All you need is a Windows Server 2008 R2 (or newer) domain controller with remoting enabled. These functions were designed to be backwards-compatible with PowerShell v2 (Windows 7 / Windows Server 2008 R2). The only exception is the Mount-ADDatabase -Filter parameter which requires PowerShell v3.  I specifically chose to release this as a function library script rather than a module. This makes the code more portable when targeting DCs over a remoting session as demonstrated below.

Example Code

The following code illustrates the basic functions:

# Running locally from a domain controller...            
# Dot source a reference to the function library            
. .\AD_Snapshot_Functions.ps1            
# Create a new snapshot and view it in the list            
Show-ADSnapshot | Out-GridView            
Show-ADSnapshot -WMI | Out-GridView            
# Mount the database            
Get-Help Mount-ADDatabase -Full            
Mount-ADDatabase -Last -LDAPPort 33389            
# Notice the snapshot list now shows which one is mounted            
Show-ADSnapshot | Out-GridView            
Show-ADSnapshot -WMI | Out-GridView            
# View a user in both copies of the database            
Get-ADUser Guest -Properties Description -Server localhost:33389            
Get-ADUser Guest -Properties Description -Server localhost            
# Repair a single attribute for a single account            
Get-ADUser Guest -Server localhost |             
    Repair-ADAttribute -Property Description -LDAPPort 33389            
# Repair multiple attributes for multiple users            
Get-ADUser -Filter {name -like "G*"} |             
    Repair-ADAttribute -Property Department,Description -LDAPPort 33389            
# Finish cleanly            

When you recover attributes I recommend that you use the -WhatIf switch as a test run before actually making any changes.

The output from Repair-ADAttribute contains the following properties for each attribute per object:

  • Action – Replaced, No Change, Not Found in Current (deleted since snapshot), Not Found in Snapshot (new since snapshot)
  • Property – Attribute name
  • ObjGUID – Active Directory object GUID
  • NewObject – Distinguished name path to the current object
  • OldObject – Distinguished name path to the snapshot object
  • NewValue – Attribute value of the current object prior to any changes
  • OldValue – Attribute value of the snapshot object
  • Moved – Is the distinguished name path different between both databases?

You can send this rich output to the console, Out-Gridview, CSV, etc. Here is an example of the console output:

Action    : Replaced
Property  : Department
ObjGUID   : 21e759e9-427e-4f07-aee3-cd95132d2f50
NewObject : CN=gusingh,OU=Sales,OU=Office,DC=wingtiptoys,DC=local
OldObject : CN=gusingh,OU=Sales,OU=Office,DC=wingtiptoys,DC=local
NewValue  : Engineering
OldValue  : Sales
Moved     : False

Here is an example using PowerShell remoting:

$cred = Get-Credential wingtiptoys\administrator            
$s = New-PSSession -ComputerName dca.wingtiptoys.local -Credential $cred            
Invoke-Command -Session $s -FilePath '.\AD_Snapshot_Functions.ps1'            
Invoke-Command -Session $s -ScriptBlock {Show-ADSnapshot}            
Invoke-Command -Session $s -ScriptBlock {Mount-ADDatabase -Last -LDAPPort 33389}            
Invoke-Command -Session $s -ScriptBlock {Get-ADUser Guest |             
        Repair-ADAttribute -Property Department,Description -LDAPPort 33389}            
Invoke-Command -Session $s -ScriptBlock {Dismount-ADDatabase}            
Remove-PSSession $s

There are many ways to conduct your remoting session. You can script out the entire activity to simplify this further.

You can even use a remoting session against multiple DCs simultaneously to perform your scheduled snapshots from a central location. This is the easiest way to schedule your snapshots.

# Blast a new snapshot and purge to all DCs            
# Scheduled task will need appropriate credentials            
$DCs = Get-ADDomainController -Filter * | Select-Object -ExpandProperty Hostname            
$s = New-PSSession -ComputerName $DCs            
Invoke-Command -Session $s -FilePath '.\AD_Snapshot_Functions.ps1'            
# Set ThrottleLimit to 1 to preserve the order of output returned            
Invoke-Command -Session $s -ScriptBlock `
    {"`n`n*********";hostname;New-ADSnapshot} -ThrottleLimit 1            
Invoke-Command -Session $s -ScriptBlock `
    {"`n`n*********";hostname;Remove-ADSnapshot -Keep 3 -Last} -ThrottleLimit 1            
Invoke-Command -Session $s -ScriptBlock `
    {"`n`n*********";hostname;Show-ADSnapshot} -ThrottleLimit 1            
Remove-PSSession $s            

How cool is that! Now take this sample code, add some logging, and tailor it to your environment. A full demo script is included with the download at the TechNet Script Center.

Public Service Announcement

This is the most important part of the entire article. Go do these things immediately to prepare for your own Active Directory recovery scenarios:

  • Enable the AD Recycle Bin.
  • Schedule AD snapshots and snapshot cleanup.
  • Practice with these PowerShell functions in your lab.
  • Tell your peers, friends, and grandmother to do likewise.

You cannot recover AD attributes unless you first have a snapshot. Well, you can, but that is a much longer process of AD authoritative restore. Save yourself some recovery time. Schedule your AD snapshots today.


The benefits of this solution are many:

  • Speedy recovery time.
  • Less disk space than full backups.
  • Can copy to another server to view.
  • View snapshots in LDP, ADUC, ADSIEDIT, or PowerShell.
  • No reboots required.
  • It’s free!

Here are a couple tips to keep in mind:

  • You must recover from a snapshot created PRIOR TO the corruption event.
  • The recovered attribute value is a new write, not a true recovery.
  • Snapshots are read-only.
  • Monitor disk space.
  • Use Enterprise Admin or Domain Admin credentials.
  • Snapshots are not a full recovery solution.
  • When mounting the database pick a port not in use.
  • Enable PowerShell remoting on DCs for ease of recovery.
  • You can only update “write-able” attributes.

You do not need to schedule snapshots on every domain controller in the company, but I would recommend at least one or two domain controllers per domain per physical site. This will give you more options in the event of a recovery scenario. I would also recommend a weekly interval at the longest. Daily might be a bit much depending on the size of your database.  Obviously I would schedule this for after hours.

Be the hero. Be ready. Schedule AD snapshots today.

Download the code and demo script from the TechNet Script Center here.

PS – I am really excited about this code. Everyone with Active Directory needs to prepare for attribute recovery. Please help me get the word out using the social links below. Thanks!


Active Directory Domain Services Database Mounting Tool (Snapshot Viewer or Snapshot Browser) Step-by-Step Guide – http://technet.microsoft.com/en-us/library/cc753609(WS.10).aspx

TechNet NTDSUTIL SNAPSHOT syntax – http://technet.microsoft.com/en-us/library/cc731620(WS.10).aspx


Feb 3, 2015 – Updated code to support AD database stored on drive other than C:.

Comments (23)

  1. Ed (DareDevil57) says:

    thanks so much.

  2. Anonymous says:

    Pingback from Interesting things that i see on the internet, may 2014. | 503 5.0.0 polite people say HELO

  3. Francois-Xavier Cat says:

    Awesome article Ashley, very useful stuff! and Great presentation at the Summit! It was great to meet you

  4. Anonymous says:

    I know this post is a little late, but I wanted to offer some helpful information that I picked up at the PowerShell Summit last month. This post is packed with links to keep you surfing high-value PowerShell content for days.

  5. Anonymous says:

    Pingback from SysAdmin Tools | Windows Vmware Topics

  6. matthew g says:

    great stuff. love the remove-adsnapshot.

  7. paul says:

    it would be cool to add the ACL sync as well, as it could be another recovery scenario. Great job

  8. Anonymous says:

    Welcome! Today’s post includes demo scripts and links from the Microsoft Virtual Academy event: Using PowerShell for Active Directory . We had a great time creating this for you, and I hope you will share it with anyone needing to ramp up their

  9. Anonymous says:

    Learn three essential steps for Windows PowerShell when upgrading from Windows Server 2003.

  10. JF says:

    Hi, I’m on W2k12R2, the Repair-AduserGroup command doesn’t work. I query successfuly the user’s group membership on the snapshot DB with get-aduser. Then I do a get-aduser on the localhost but when I pipe it to Repair-AduserGroup (I use the same syntax
    as in the examples) nothing happens, no error message, nothing. I tried -WhatIf , with or without -confirm:$False, nothing do it.

    The Repair-AdAttribute command is working fine by the way.

  11. Anonymous says:

    Excellent stuff here! Very solid and after thoroughly testing in lower life-cycles, we use this in our Prod environments! Thanks for the contribution here Ashley!

  12. Abdulhlone says:

    A great tool. Thank you very much!
    Just a little correction needed in the function Repair-ADUserGroup –
    If ($OldGroups -eq $null) {
    #$GroupsToRemove = $NewValue
    $GroupsToRemove = $NewGroups
    } ElseIf ($NewGroups -eq $null) {
    #$GroupsToAdd = $OldValue
    $GroupsToAdd = $OldGroups

  13. Anonymous says:

    This post is part four in the "PowerShell: SID Walker, Texas Ranger" series on documenting and remediating SID history in your AD forest. In today’s post we will look at the final step of remediating SID history: removing the SID history

  14. Tim Bolton says:

    Excellent article! Thank you Ashley!

  15. Chaz says:

    Excellent tool, just wondering if it’s indeed possible to repair the SIDHistory attribute, I’m running through all possible remediation plans for an up comming SIDHistory translation in my lab and have tried using these AD snapshots with the above PS repair function and I get the following:

    Set-ADObject : Access is denied
    At C:\Windows\System32\WindowsPowerShell\v1.0\AD_Snapshot_Functions.ps1:547 char:33
    + Set-ADObject -Identity $Identity -Add @{$Propert …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : PermissionDenied: (631d51d1-a905-4332-88b9-f3657753b7d0:ADObject) [Set-ADObject], UnauthorizedAccessEx
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.UnauthorizedAccessException,Microsoft.ActiveDirectory.Management.Commands

  16. Gaetan Meister says:

    Fantastic script. How would I implement it with EMS ?

    We’re modifying a few attributes to contact and group objects and get-mailcontact, get-distributiogroup will not work in that instance, so I wonder if I could use get-adobject in conjunction with the repair-ADattribute ? I haven’t tested it yet. thanks

  17. Byron Wright says:

    Just a quick note to point out that you need to be careful about the property name you are selecting when using Repair-ADAttribute. I may have found the only instance, but I was testing the process to repair the Office attribute of a user, and that attribute does not exist when using Get-ADObject (which is used by Repair-ADAttribute). The function reported “Not found in snapshot”.

    Instead I needed to use the PhysicalDeliveryOfficeName attribute. There may be other attributes also, I haven’t done a comprehensive review.

  18. Byron Wright says:

    One more quick note from testing. The -Filter parameter for the Mount-ADDatabase function requires minimum PowerShell v3 to support the -OutputMode parameter used for Out-Gridview.

    1. Byron Wright says:

      If anyone is still using PowerShell v2 only on their domain controllers, I’ve updated one line of the Mount-ADDatabase function to allow -Filter to work in PowerShell v2.


  19. Meera says:

    Hello I am not sure what i am doing wrong. I get below error

    PS C:\Users\Administrator> .\AD_Snapshot_Functions.ps1
    PS C:\Users\Administrator> New-ADSnapshot
    The term ‘New-ADSnapshot’ is not recognized as the name of a cmdlet, function,
    script file, or operable program. Check the spelling of the name, or if a path
    was included, verify that the path is correct and try again.
    At line:1 char:15
    + New-ADSnapshot <<<<
    + CategoryInfo : ObjectNotFound: (New-ADSnapshot:String) [], Comm
    + FullyQualifiedErrorId : CommandNotFoundException

    Any idea ?

    1. Meera says:

      I got it…What i was doing wrong…. 🙂