Purpose

Every AD replication issue turns into the same routine — repadmin /showrepl, dfsrdiag replicationstate, dfsrmig /GetMigrationState, GPO version compares, event log spelunking, share checks. Different console for each, output that doesn’t line up, and half of them run only on a DC.

Test-VBReplicationHealth.ps1 replaces that dance with a single script that runs every one of those checks and returns one colour-coded report — plus a structured object you can pipe or export.

[i] Tested on: Windows Server 2019, 2022, PowerShell 5.1 and 7.4 [i] Requires: Domain user with read access to AD + SYSVOL. Runs from a DC, a management box with RSAT, or any domain-joined server.

What it checks

SectionWhat runs
DC inventoryDNS resolution + ping for every DC in the domain
Server inventoryAll OperatingSystem -like '*Server*' computer objects, online state, OS version
SYSVOL replication mode4-tier detection — dfsrmig.exe → AD LDAP (msDFSR-Enabled) → service state → registry. Surfaces which method answered
AD replicationGet-ADReplicationPartnerMetadata for every source→destination pair. Age of last success, consecutive failures, partner type
DFSR / FRS detaildfsrdiag.exe replicationstate /verbose (authoritative) with WMI DfsrConnectionInfo fallback. Parses replication state per RG/RF/partner
Event log checkDFS Replication and File Replication Service logs, level 2+3, split into last 24h (counts toward score) and 24h–7d (informational)
SYSVOL consistencyReads GPT.ini version from every DC’s SYSVOL and diffs. Flags both policy-count mismatches and version drift
NETLOGON / SYSVOL sharesTest-Path \\DC\NETLOGON and \\DC\SYSVOL per DC — the ones that always break before replication does
FSMO rolesSchema, Domain Naming, PDC, RID, Infrastructure — plus ping test on each holder
Overall scorePercentage, rated EXCELLENT / GOOD / FAIR / CRITICAL, plus a bulleted “items requiring attention” block

The whole thing runs in under a minute on a domain with a handful of DCs.

Why one report matters

Troubleshooting AD replication is usually not one broken thing — it’s one broken thing plus five things that look wrong because you’re only seeing them for the first time. A stale DC. A SYSVOL access denied. An event 4012 from three days ago. A missing GPO on one DC.

Running seven separate tools in seven different formats makes it easy to miss which of those actually matters right now. One report, one format, one health score — the noise stays in the log, the real issue stands out in red.

Design notes worth calling out

  • Data / display splitGet-* functions return objects, Write-* functions render them. Same data feeds the console table, the returned PSCustomObject, and the -ExportCsv output.
  • 4-tier SYSVOL mode detection — most scripts only check the service or the registry. Both lie during a migration. Starting with dfsrmig.exe /GetMigrationState is the only reliable answer on Server 2008+; the other three tiers are fallbacks for when it isn’t available.
  • AD LDAP query searches the whole domain tree, not OU=Domain Controllers — that OU path is not reliable on every domain. Every DC I’ve hit that has a customised OU structure trips scripts that hard-code the path.
  • Event log split into two windows — last 24h counts toward the health score, 24h–7d shows as informational. Old errors shouldn’t drag today’s score down, but you still want to see them.
  • SYSVOL policy-count mismatch is flagged separately from version drift — a DC missing a policy entirely is a different failure mode than a stale version, and it deserves its own line.

Run it

Grab the script from GitHub — it’s in my PowershellScripts repo:

# Direct run
.\Test-VBReplicationHealth2.ps1

# The script auto-invokes Test-VBReplicationHealth at the bottom.
# Dot-source it if you want to call the function with parameters:
. .\Test-VBReplicationHealth2.ps1
Test-VBReplicationHealth -WarningThresholdHours 4 -ExportCsv
Test-VBReplicationHealth -QuickMode   # skips DFSR detail + event log

Parameters:

ParameterPurpose
-WarningThresholdHoursAD replication age (hours) before a partner flips to Warning. Default 2.
-QuickModeSkips DFSR/FRS detail and event log. Useful for a fast heartbeat check.
-ExportCsvDumps all connection results to CSV. Path default: $env:TEMP\ReplicationReport_<timestamp>.csv
-ExportPathOverride the CSV path.

The function also returns a PSCustomObject with HealthPct, Status, ReplMode, SysvolConsistent, Summary counts, and the full Results array — so you can pipe it into a monitoring tool, a report, or a Slack webhook.

Verify

Success looks like this at the end:

SUMMARY
-------
  Overall Health  : 100% (EXCELLENT)
  Replication Mode: DFSR (via dfsrmig.exe)
  SYSVOL Sync     : Consistent
  AD Replication  : 6 OK  0 WARN  0 FAIL
  DFSR/FRS        : 12 OK  0 WARN  0 FAIL
  Completed in    : 18.4s on DC01

Anything less than EXCELLENT prints an [!] Items requiring attention: block with the exact source→destination pair, the status, and the underlying error or state — so the next command you type is targeted, not a fishing trip.

References

🤝 Connect with Me

Found this useful? I write about PowerShell, Windows infrastructure, and enterprise automation.