As I wrote in a previous post, I began using the new DFS Replication database cloning technique to speed up initial sync. Thanks to Ned Pyle’s great How-To on the subject, I was able to tell exactly which events to look for in the event log to get an idea of progress: 2412
for the start of the process, 2416
for progress, 2404
for successful finish, and 2418
for an unsuccessful end (found that one out on my own, whoops!).
Since I clearly had a few hours to kill while the import happened, I wrote up a quick script to show the progress, with estimated time remaining.
Script Details
This is a quick-and-dirty powershell script with no fancy CmdletBinding or any parameters at all, and no comments, and barely any testing so use at your own risk, etc.
The basic idea is that it keeps checking the event log (I’m doing it every 5 seconds), looking for new progress events, and it uses Write-Progress
to display some pretty stats. When the event 2404
indicates a successful completion or 2418
indicates an error, it should end the script or raise an exception, respectively.
In the meantime, you’ll just see the progress:
The progress bar is only updated when a new event is logged, so you won’t see continuously changing numbers. It’s more of a thing you leave running in the background and check on every now and then.
Oh and it doesn’t have to be run on the machine doing the import, so it can be run from a management server or desktop client to keep tabs on the progress. Since it uses events in the event log on the destination computer, stopping and restarting the script will still give you consistent progress.
The Full Script
$importComputer = 'ComputerName'
$clonestart = Get-WinEvent -FilterHashtable @{LogName='DFS Replication';ID=2412} -ComputerName $importComputer -MaxEvents 1 -ErrorAction SilentlyContinue
$start = $null
if ($clonestart) {
$start = $clonestart.TimeCreated
} else {
throw "No clone event found."
}
$progtime = $start
for() {
$cloneend = Get-WinEvent -FilterHashtable @{LogName='DFS Replication';ID=2404} -ComputerName $importComputer -MaxEvents 1 -ErrorAction SilentlyContinue
if ($cloneend) {
if ($cloneend.TimeCreated -gt $start) {
# Clone import successfully finished.
Write-Progress -Activity 'Importing DFSr Database' -Completed
break
}
}
$cloneerr = Get-WinEvent -FilterHashtable @{LogName='DFS Replication';ID=2414} -ComputerName $importComputer -MaxEvents 1 -ErrorAction SilentlyContinue
if ($cloneerr) {
if ($cloneerr.TimeCreated -gt $start) {
throw "Clone import error:\n$cloneerr"
}
}
$cloneprog = Get-WinEvent -FilterHashtable @{LogName='DFS Replication';ID=2416} -ComputerName $importComputer -MaxEvents 1 -ErrorAction SilentlyContinue
if ($cloneprog) {
if ($cloneprog.TimeCreated -gt $progtime) {
$progtime = $cloneprog.TimeCreated
if ($cloneprog.Message -imatch '(?s)Processed:(\d+).*?Remaining:(\d+)') {
$processed = [Int64]::Parse($Matches[1])
$remaining = [Int64]::Parse($Matches[2])
$total = $processed + $remaining
$percentage = (($processed*100.0)/$total)
$elapsed = ($progtime - $start).TotalSeconds
$secrem = ($elapsed*(100.0/$percentage)) - $elapsed
$submessage = "$("{0:N0}" -f $processed) records of $("{0:N0}" -f $total) ($("{0:N0}" -f $remaining) remaining) - $("{0:N2}" -f $percentage)% :: Last Update: $progtime, $(($progtime - $start)) elapsed"
Write-Progress -Activity 'Importing DFSr Database' -Status $submessage -PercentComplete $percentage -SecondsRemaining $secrem
}
}
}
Start-Sleep -Seconds 5
}