Examining Legacy AD Replication Metadata with PowerShell 2.0

I had a scenario last week where I was troubleshooting a Domain Replication issue.  Basically, for one reason or another, a DC had only an inwards replication connection but no outward replication connection to another DC.  It was found that the DC had not been replicating out for 5 months!  Due to this exceeding the tombstone lifetime and so forth, we decided we would force demote the DC out of the Forest, clean up behind it and re-promote it back in.  However, this DC had been operational for 5 months since the last replication and had no doubt made changes to objects that we would lose.  This could include password changes, among other things.  It could also include new objects being created that we would lose, so we need to do some analysis.

Checking for new objects on the troublesome DC is out of the scope of this post but I may post afterwards.  For the purposes of this post, I want to see what objects have been updated on the troublesome DC and when.  The quick and dirty method used is as follows:

The domain is running Windows 2003 Domain Controllers in a Windows 2000 Domain and Forest level.  Relying on RepAdmin.exe I was able to put out replication metadata

$ObjectImport = Get-Content c:\mylistofDNs.txt
$DCShort = "DC"
[Array]$ChangesList = @()
foreach ($Object in $ObjectImport)  {
    $Output = Repadmin /showobjmeta $dcFQDN $Object
    foreach ($i in $output)  {
        if ((($i -match $dcShort) -or ($i -match $dcGUID)) -and ($i -notmatch " cn"))  {
            [Array]$Change = @()
            $i.Split(" ") | foreach {if ($_ -ne "") {$Change += $_}}
        $ChangesList += $obj

$ChangesList | Export-Csv c:\myfile.csv -NoTypeInformation

So, what’s going on here?

  1. Line 1: $ObjectImport is importing the list of DN’s that I output from the troublesome DC using DSQuery
  2. Line 2-4: $dcFQDN and $dcShort are the identifiers of the DC that may show up in the metadata, these are what we are looking for (values have been changed in this post to remove environment information). We initialise $ChangesList variable to store the changes we find
  3. Line 5-6: We are retrieving the Metadata of each object in the list we imported using Repadmin and saving this into a variable.  Because RepAdmin outputs lines of text, the Variable is an array where each line is an element of the Array
  4. Line 7: We are going through each line of the text that was output (each element of the array) looking for the DC name. This means that the DC has authored a change to the object
  5. Line 8: When we find a change that does not include ” cn”, which would reference the CN attribute that every DC authors, we work with this further:
    1. Line 9-10: We create a new array called $Change and are splitting the the line we found everywhere there is a space (” “) or Null.  Where there is some text, we are adding this to the $Change variable we created
  6. Line 11: Having examined the output of RepAdmin before, we know that default column headers are output. The data we find as we go through the text line, pulling values into the $Change variable, we know will follow the same format.  So we are now able to create a custom object called $obj and reference the elements in $Change in the same order
  7. Line 22: We then add our new PowerShell Object to our $ChangesList and continue onto the next object till we are done
  8. Line 27: We output the $ChangesList to a CSV which gives us nice CSV output so we can see what attributes the DC authored on which objects and when.

What this allows us to do now is assess the impact of removing the DC from the Forest.  We can see if any accounts have changed passwords that will be lost, if there are any group membership changes that will be lost and so forth.  Using this information we can formulate a plan to fix group memberships on a working DC, contact users about password changes and generally plan for impact to minimise the unexpected. Planning for lost objects is a subject I will try to cover in another post.

So, that’s the script I used, it took a while to run as the Domain was quite large but it allowed us to assess and understand the impact of what we were doing. I violated a best practice or so with the script but it was useable nonetheless.

Categories: Active Directory, Powershell

Leave a Reply


WordPress.com Logo


Google photo


Twitter picture


Facebook photo


Connecting to %s

%d bloggers like this: