Bulk query AD Replication Metadata with Powershell

By | March 27, 2014

I had a requirement recently to try and find out where and when a whole lot of mailboxes were hidden from the GAL.  Yes, fingering some poor sucker for the blame is an immensely satisfying task, isn’t it?  I’ve found that an effective way to do this is to query the AD replication metadata for the attribute concerned (in this case ‘msexchhidefromaddresslists’).  The replication metadata will provide you with the date/time for when the attribute value was last changed as well as the name of the DC where the last change was made.  From there you can search the Security Event Log on the DC in question for the audit events corresponding to the change.  This of course assumes that you have Audit Directory Service Changes switched on.

Typically, I would use the excellent Repadmin.exe command line tool to query the replication metadata, e.g. –

Repadmin /showobjmeta MyDC1 “CN=MyUser,OU=User Accounts,DC=contoso,DC=com”

However, in this case someone had already reversed most of the changes (i.e. unhidden the mailboxes) and I needed to query a large number of objects to find some others that were still hidden, hoping that some of them would have a common data/time stamp.  For this the Repadmin.exe would work but would be hopelessly inefficient.  And what (I said to myself) is the best method for performing bulk operations such as this?  Yes, that’s right:  Powershell to the rescue!

After some Googling, I found an excellent code snippet from Powershell MVP Brandon shell that hooks into the underlying .Net class to expose the replication metadata.  His is the clever bit (that’s why he’s paid the big bucks) – I’ve basically just done the wrapper to perform a bulk query and output the results to a CSV file.  Here’s the script for your enjoyment.

 

#########################################################
#
# Name: BulkReportReplicationMetadata.ps1
# Author: Tony Murray
# Version: 2.0
# Date: 27/03/2014
# Comment: PowerShell 2.0 script to find change times
# for an individual AD attribute using replication metadata
# 
# Some bits borrowed from: Get-ADObjectREplicationMetadata.ps1
# Brandon Shell (www.bsonposh.com)
#
#########################################################

# import the AD module
ipmo ActiveDirectory

# Define variables
$domain = (get-addomain).dnsroot # Use the current AD domain
$property = "msexchhidefromaddresslists" # This is the AD attribute we are interested in
$outfile = "c:\csv\outfile.csv" # CSV output file

# Blow away the existing file if it exists
if (test-path $outfile) {remove-item $outfile}

# We will build our own CSV rather than work with export-csv
$header = "samaccountname,modified,dc"
Add-Content -Value $header -Path $outfile

$sb = "OU=Standard User Accounts,DC=contoso,DC=com" # Search base for where our mailbox users live
$fl = "(&(homemdb=*)(msexchhidefromaddresslists=TRUE))" # LDAP filter to find our users
$users = Get-ADUser -LDAPFilter $fl -searchbase $sb

# Loop through our list of users
foreach ($user in $users) {

    $objectDN = $user.distinguishedname # used for finding the replication metadata
    $name = $user.samaccountname # Just for info
    # Sets Context to Domain for System.DirectoryServices.ActiveDirectory.DomainController
    $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$domain)
    # .NET Class that returns a Domain Controller for Specified Context
    $dc = [System.DirectoryServices.ActiveDirectory.DomainController]::findOne($context)
    # GetReplicationMetadata returns metadata from the DC for the DN specified.
    $meta = $dc.GetReplicationMetadata($objectDN)
    # Get the last time the attribute value was changed
    $ctime = $meta | %{$_.$Property.LastOriginatingChangeTime}
    # Get the DC that the change was made on
    $dcon = $meta | %{$_.$Property.OriginatingServer}
    # Build the values to write to the output file
    $line =  "`"$name`",`"$ctime`",`"$dcon`""
    # Write the line to the output file
    Add-Content -Value $line -Path $outfile

} # end foreach

The shrewd amongst you would ask why I didn’t query the Exchange (2010 in this case) audit log for this information. The answer is that I did, but couldn’t find the relevant audit entries. The Exchange audit events are only captured if the Exchange tools (EMC/EMS/ECP) were used to perform the change. In my case the changes had been made in bulk, probably using the AD cmdlets.

2 thoughts on “Bulk query AD Replication Metadata with Powershell

  1. Robert K

    Unfortunately this method does not show meta data for attributes with LVR like members attribute of group objects.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.