Check Active Directory Latency
The other day I had a need to see how long it took for an object to be replicated to all the Domain Controllers in my Environment.
Here is the script I came up with. It does the following:
- Finds all Domain Controllers in the Domain (using .NET)
- Creates a contact object in a specified OU (Default is users container for the Domain)
- Gets the start Time
- Loops and Checks each DC for the object.
- Once all DCs have the object it gets End Time
- Outputs the results
Some extra features
- re-writes screen using $host.UI.RawUI.CursorPosition. No scrolling text ![]()
- Outputs a custom object with Name and Time to Replicate (-table)
Parameters/Switches
-target: DC to create object on. (Default: it will find one for you)
-fqdn: Used to Find Domain Controllers (Default: Use current Domain)
-ou: DN of the path to create contact objects (Default Users Container)
-remove: If $true it removes the temp object (default is $true)
-table: switch that will return a table with the DC and Time it took to replicate (as output)
Here is the code:
$fqdn = (([ADSI]"").distinguishedname -replace "DC=","" -replace ",","."),
$ou = ("cn=users," + ([ADSI]"").distinguishedname),
$remove = $true,
[switch]$table
)
$context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$fqdn)
$dclist = [System.DirectoryServices.ActiveDirectory.DomainController]::findall($context)
if($table)
{
$DCTable = @()
$myobj = "" | select Name,Time
$myobj.Name = ("$target [SOURCE]").ToUpper()
$myobj.Time = 0.00
$DCTable += $myobj
}
$name = "rTest" + (Get-Date -f MMddyyHHmmss)
Write-Host "`n Creating Temp Contact Object [$name] on [$target]"
$contact = ([ADSI]"LDAP://$target/$ou").Create("contact","cn=$Name")
$contact.SetInfo()
$dn = $contact.distinguishedname
Write-Host " Temp Contact Object [$dn] Created! `n"
$start = Get-Date
$i = 0
Write-Host " Found [$($dclist.count)] Domain Controllers"
$cont = $true
While($cont)
{
$i++
$oldpos = $host.UI.RawUI.CursorPosition
Write-Host " =========== Check $i ===========" -fore white
start-Sleep 1
$replicated = $true
foreach($dc in $dclist)
{
if($target -match $dc.Name){continue}
$object = [ADSI]"LDAP://$($dc.Name)/$dn"
if($object.name)
{
Write-Host " - $($dc.Name.ToUpper()) Has Object [$dn]" (" "*5) -fore Green
if($table -and !($dctable | ?{$_.Name -match $dc.Name}))
{
$myobj = "" | Select-Object Name,Time
$myobj.Name = ($dc.Name).ToUpper()
$myobj.Time = ("{0:n2}" -f ((Get-Date)-$start).TotalSeconds)
$dctable += $myobj
}
}
else{Write-Host " ! $($dc.Name.ToUpper()) Missing Object [$dn]" -fore Red;$replicated = $false}
}
if($replicated){$cont = $false}else{$host.UI.RawUI.CursorPosition = $oldpos}
}
$end = Get-Date
$duration = "{0:n2}" -f ($end.Subtract($start).TotalSeconds)
Write-Host "`n Took $duration Seconds `n" -fore Yellow
if($remove)
{
Write-Host " Removing Test Object `n"
([ADSI]"LDAP://$target/$ou").Delete("contact","cn=$Name")
}
if($table){$dctable | Sort-Object Time | Format-Table -auto}
tshell :: Mar.11.2008 :: Active Directory, HowTo, Powershell, Scripting :: 9 Comments »


Very usefull, will hopefull get rid of all the replication worries.
Hi BSonPoSH
I just wanted to say a million thanks for this superb bit of code..!
It really is a very, very useful part of my AD toolkit now.
Again thanks so much for *sharing* this with the rest of us…
You rock..!
cheers
Bry
Thanks Bryan
Sorry for an ignorant question, but how do you actually run this?
No problem
Cut/paste into a file and just call it.
c:\scripts\Test-AD.ps1
Hey B…
This is a very nice piece of code. I have a couple usage questions if I may indulge you…
1. Can I set the scope to the entire forest? I have a parent and 2 child domains.
2. As the script ran, it found one of the two DC’s in the current scope. It successfully created the test contact on DC1, but I received an error from PS indicating that the object was not created on DC2. The count then got up to 400 and I believed it wasn’t going well, so I CTRL+C’d the script. Should I ignore the error? Should I wait longer for it to finish? (The object was created in AD, so the fact it wasn’t “created” on DC2 seems irrelevant.)
Again, I appreciate any help you can lend.
Thx in advance.
gb
Well good news bad news
Bad News
If you have more than ~30 DCs the script looses its affectiveness and there wasn’t much I could do about it. Also the current version only does Domain.
Good News:
I am working on Active Directory Replication Module [Powershell] which will do all of what your asking for.
I only have 2 dc’s in the current scope. How long should I let it run? Also, I get an error saying that the temp object was created on DC1, but not DC2. I can clearly see the object in the default users OU. Should I ignore that error?
Oh… that could be a bug or it could simply be just a replication schedule thing. If the DCs are in the same site or you have change notification enabled then it is clearly a bug else just wait