Accessing Replication Metadata using ADPowerShell
Metadata associated with Active Directory Replication is exposed in AD via many constructed attributes. Some of these metadata attributes come in pairs of binary blob & xml representation of the metadata element.
Constructed Replication XML Metadata Attribute |
Available on Objects |
Corresponding Binary Attribute |
msDS-ReplQueueStatistics |
Root DSE |
- |
msDS-ReplAllInboundNeighbors |
Root DSE |
- |
msDS-ReplAllOutboundNeighbors |
Root DSE |
- |
msDS-NCReplCursors |
NC Head |
replUpToDateVector |
msDS-NCReplInboundNeighbors |
NC Head |
repsFrom |
msDS-NCReplOutboundNeighbors |
NC Head |
repsTo |
msDS-ReplAttributeMetaData |
All Objects |
replPropertyMetaData |
msDS-ReplValueMetaData |
All Objects |
- |
For the Inspecting Deleted Objects before Restore blog post script, I had parsed the msDS-ReplAttributeMetaData attribute of the deleted objects to determine the actual deleted time of the objects. I had found the parsing so simple to do using ADPowerShell, that I decided to write about it in this separate post.
This post is focused on the msDS-ReplAttributeMetaData attribute … but the technique shown here can be used to parse all of the above listed XML format attributes …
Let’s start by a simple Get-ADObject call and requesting the msDS-ReplAttributeMetaData attribute.
Get-ADObject "DC=DUGILL,DC=DEMO" -Properties "msDS-ReplAttributeMetaData"
Let’s store the xml string value in a local variable so that we can play with it without cluttering the commandline. Now, the attribute name has a hyphen (‘-’) in it so we will need to help the powershell parser and put quotes around the attribute name.
$xmlAttribute = (Get-ADObject "DC=DUGILL,DC=DEMO" -Properties "msDS-ReplAttributeMetaData")."msDS-ReplAttributeMetaData"
Above we see that the xml text from the attribute is not a valid xml string, as it does not have a root tag. So let’s add a root tag to it.
$xmlAttribute = “<root>” + $xmlAttribute + “</root>”
Now that we’ve made our msDS-ReplAttributeMetaData attribute value a valid xml string, comes the turn of some PowerShell magic. PowerShell makes it really simple to convert XML string to an XML Document Object (a form which can be worked on programmatically in a simpler way …)
SO, let’s go ahead and cast the string into an XML Document object.
$xmlAttributeDocObject = [xml] $xmlAttribute # wow … it’s that simple
Ok not that simple … we hit a pretty nasty looking parsing error. The error is because the XML string contains some ASCII null characters (a bug in AD). So how do we get rid of these null charecters?
The hint is in the error which says the char has a hex value of 0x00 which is basically decimal 0. Can I use String.Replace function to get rid of these characters? As it turns out – I can …
String.Replace takes two arguments: first, the char or string to replace and second, the char or string to replace with. Note I’m using PowerShell casting again, to convert the hex value 0x00 to a char value. Replacing all occurrences of ascii nulls in the string with a space char (“ ”) …
$xmlAttribute = $xmlAttribute.Replace([char]0,” ”)
Now let’s try converting it into the XML Doc Object again … this time it works!!
$xmlAttributeDocObject = [XML]$xmlAttribute
Let’s inspect the xml doc object and admire the wonderful XML experience provided by PowerShell :)
And finally $xmlAttributeDocObject.root.DS_REPL_ATTR_META_DATA | ft #… viola!
BTW, this output had got me wondering if I had just typed repadmin /showmeta …
Focusing on selected interesting XML elements …
$xmlAttributeDocObject.root.DS_REPL_ATTR_META_DATA | ft pszAttributeName,ftimeLastOriginatingChange,pszLastOriginatingDsaDN
We see that the originating change time is in the Zulu time format and the originating dc’ NTDS Settings object DN is what is available … with some format transforms we can get to a better looking output
$ObjectMetadataTableFormatter = @()
$ObjectMetadataTableFormatter += @{Label="Attribute LDAP Name"; Expression={$_.pszAttributeName}}
$ObjectMetadataTableFormatter += @{Label="Originating DC"; Expression={(Get-ADObject $_.pszLastOriginatingDsaDN.Substring(17,$_.pszLastOriginatingDsaDN.length-17) -properties dnshostname).DNSHostName}}
$ObjectMetadataTableFormatter += @{Label="Originating Change Time"; Expression={[datetime]::parse($_.ftimeLastOriginatingChange)}}
$xmlAttributeDocObject.root.DS_REPL_ATTR_META_DATA | ft $ObjectMetadataTableFormatter
You may also use the attached script function (or add it into your function profile script). The function allows pipelining objects from other Get-AD cmdlets to fetch the object replication metadata …
enjoy!
Dushyant Gill
Program Manager - Microsoft
Comments
- Anonymous
October 31, 2011
So much better than using repadmin. Just the fact that you are getting objects makes life much better. I don't know why no one ever commented on this, trying to share some love here. - Anonymous
November 01, 2011
Great article! An easier way to get at this information is to use the GetReplicationMetaData() method on instance of a System.DirectorySercvices.ActiveDirectory.DomainController object. This post has a script example of how to do this and just requires a few lines of code - bsonposh.com/.../253