Active Directory failures rarely arrive without warning. Replication errors accumulate quietly for days before authentication stops working. DNS misconfiguration sits undetected until a DC promotion fails. SYSVOL backlogs grow in the background while Group Policy keeps applying from cache – until it doesn’t.
A structured active directory health check catches those signals before they become incidents. This active directory health check covers the full diagnostic surface: services, replication, DNS, SYSVOL, FSMO, time hierarchy, Kerberos, event logs, and the AD database. It’s organized by cadence so you run the right checks at the right frequency, not the same heavy scan every day.
- Run dcdiag /q /skip:systemlog and repadmin /replsummary after every change, not just on a schedule.
- Do not judge “largest delta” against a fixed 60-minute rule. Intra-site changes propagate in seconds via change notification; inter-site follows the site-link schedule (default 180 minutes).
- Verify the services each DC’s roles actually need are running, not a hard-coded list identical across every DC.
- On Windows Server 2025: wmic is disabled by default. Replace it with Get-CimInstance in any health scripts.
- Run the latest cumulative update on WS2025 DCs, and after a restart verify the active firewall profile and remote reachability, not just local green checks.
- The default Kerberos clock-skew tolerance is five minutes and is policy-configurable. Keep domain offsets far below it.
Several thresholds in this checklist (10% free space, plus or minus 2 minutes time drift, daily/weekly cadence) are conservative RackNotes operational alerting baselines, not Microsoft product limits. Adapt them to your site-link schedules, forest size, backup policy, storage growth, and business SLA. Where a number is a Microsoft default, it is called out as such with a source link.
What a Healthy Active Directory Environment Looks Like
Before running any commands in an active directory health check, it helps to know what you’re aiming for. A healthy AD environment has a specific, verifiable state, not a vague sense that things seem fine.
| Area | Healthy state |
|---|---|
| Services | Required services for each DC’s installed roles are running or start cleanly; no unexpected Disabled state |
| Replication | No errors in repadmin /showrepl * /errorsonly; last-success timestamps match the intra-site or inter-site schedule; no delta growing across repeated checks |
| SYSVOL | SYSVOL and NETLOGON reachable on every DC; DFSR state normal; pairwise backlog within baseline; no unresolved 2213 or 4012 |
| DNS | SRV records registered; authoritative internal DNS configured; dcdiag /test:DNS clean or documented; no stale A records for decommissioned DCs |
| Time | Forest-root PDC uses an approved authoritative source; other DCs follow the hierarchy; offsets well under the effective Kerberos tolerance |
| FSMO | All five role holders online, replicating, and reachable; all DCs agree on role placement |
| Kerberos | No persistent 0x25 clock-skew pattern in Event 4769; secure channel healthy on all DCs |
| Event logs | No current unresolved 1311, 1864, 2042 (Directory Service) or 5719, 5783 (System) correlated with present symptoms |
| dcdiag | dcdiag /e /c /q /skip:systemlog returns no unexplained failures |
| Recoverability | Recent valid system-state backup, documented restore procedure, adequate NTDS/log/SYSVOL free space, Recycle Bin enabled where approved |
Every check in this article maps to one of those rows. Note the last row: recoverability is separate from health. A forest can be perfectly healthy and still be one failed DC away from a painful recovery if backups are stale.
Before You Start
Required access: Domain Admins or delegated diagnostic permissions. Run commands from an elevated PowerShell or CMD prompt on a DC. For enterprise-wide dcdiag /e, run from a DC with network visibility to all sites.
Tools used in this active directory health check, all built into Windows Server or available via RSAT: dcdiag, repadmin, netdom, nltest, w32tm, and the ActiveDirectory PowerShell module (Get-ADReplicationFailure, Get-ADReplicationPartnerMetadata, requires RSAT AD DS Tools). The full repadmin and dcdiag references on Microsoft Learn cover every flag used below.
In Windows Server 2025 environments, operators have hit a case where a restarted DC comes back on the wrong firewall profile and becomes unreachable on the domain network, while local diagnostic tools still report green. Microsoft fixed this in KB5060842 and later cumulative updates. The lesson generalizes: on a recently restarted WS2025 DC, don’t trust local checks alone. Confirm the DC is on the latest cumulative update and verify the active network profile and remote LDAP/RPC/DNS/SMB reachability from another machine.
Check 1: Core Services
If core AD services are stopped, nothing else in this active directory health check matters until they’re back. But which services must run depends on the DC’s roles, not a fixed list applied identically to every DC.
$core = 'NTDS','Netlogon','KDC','ADWS','W32Time'
Get-Service $core | Select-Object Name, Status, StartType
# Role/topology-dependent - check where applicable:
# DNS (only on DCs running the DNS Server role)
# DFSR (for DFSR-replicated SYSVOL)
# Dnscache (DNS client resolver)Core AD services (NTDS, Netlogon, KDC, ADWS, W32Time) should be present on every DC. DNS is required only where the DC runs the DNS Server role. DFSR matters where SYSVOL uses DFSR rather than legacy FRS. Startup types can legitimately differ by OS build and trigger-start configuration, so verify against the DC’s intended service configuration rather than demanding an identical StartType everywhere.
| Service | What it does | What breaks when stopped |
|---|---|---|
| NTDS | Active Directory database engine | Everything – the DC stops functioning as a DC |
| Netlogon | Secure channel, SYSVOL/NETLOGON shares, SRV records | Domain authentication, Group Policy delivery |
| KDC | Kerberos ticket issuance | Kerberos authentication across the domain |
| ADWS | AD Web Services / PowerShell AD module | PowerShell AD cmdlets fail against that DC |
| W32Time | Time synchronization | Kerberos fails once skew exceeds tolerance |
| DNS (role-dependent) | Name resolution for clients and DCs | DC locator, domain joins, replication – on DCs that serve DNS |
| DFSR (topology-dependent) | SYSVOL replication between DCs | Group Policy content replication stops |
If DFSR is absent and SYSVOL still relies on FRS, you’re on legacy replication. Windows Server 2016 was the last release to support FRS for SYSVOL, so a domain still on FRS must migrate to DFSR before adding any newer domain controller.
Check 2: AD Replication
Replication is the most common source of AD failures and the first thing to confirm in any active directory health check, because everything else in AD depends on it. Run this first when something feels wrong.
repadmin /replsummary
repadmin /showrepl * /errorsonly
repadmin /queueHere is the correction most checklists get wrong: do not evaluate “largest delta” against a universal 60-minute rule. Within a site, AD uses change notification, roughly 15 seconds to the first partner and 3 seconds between subsequent partners, so intra-site changes normally propagate in seconds. Across sites, replication follows the configured site-link schedule, which defaults to 180 minutes (15 minutes is the shortest configurable interval); environments that explicitly enable inter-site change notification replicate sooner. A 45-minute delta may be perfectly normal on an inter-site link and abnormal for an actively changing intra-site partner. Interpret the value against your topology.
Investigate when: an error appears in errorsonly output; last-success time exceeds the expected schedule for that link; the delta keeps increasing across repeated checks; a partner or naming context stops advancing; or the queue does not drain over time. A persistent or growing queue – especially paired with errors or stale last-success timestamps – means the destination DC isn’t processing replication normally, which is how you tell “slow” from “broken.”
If errorsonly returns codes, the code drives the next step: 1722 (RPC unavailable, usually firewall or DNS), 8453 (access denied, permissions or secure channel), 8606/8614 (lingering objects or replication stalled past tombstone lifetime). For structured investigation, Get-ADReplicationFailure returns the same failures as objects:
Get-ADReplicationFailure -Target * -Scope Forest |
Sort-Object FailureCount -Descending |
Select-Object Server, Partner, FirstFailureTime, FailureCount, LastErrorFor deeper investigation of specific replication failures, see Active Directory Replication Not Working: How to Diagnose and Fix.
Check 3: SYSVOL and NETLOGON
SYSVOL and NETLOGON must be shared and reachable on every DC. When they’re not, Group Policy stops applying, sometimes silently, because clients use cached policy until it expires.
# Check reachability across all DCs, not just the local one
Get-ADDomainController -Filter * | ForEach-Object {
[pscustomobject]@{
DC = $_.HostName
SYSVOL = Test-Path "\\$($_.HostName)\SYSVOL"
NETLOGON = Test-Path "\\$($_.HostName)\NETLOGON"
}
}This confirms share reachability, not content equality. A share can be present while its Group Policy content is stale on that specific DC. To check whether SYSVOL members are actually synchronized, you need a pairwise backlog check, not a state snapshot:
# Backlog is directional - check both ways between each pair
Get-DfsrBacklog -GroupName "Domain System Volume" `
-FolderName "SYSVOL Share" `
-SourceComputerName DC01 `
-DestinationComputerName DC02 -VerboseImportant distinction: dfsrdiag replicationstate (and Get-DfsrState) shows what’s replicating right now and what’s queued next. It does not give a total pairwise backlog. For “are these members fully in sync,” use Get-DfsrBacklog / dfsrdiag backlog, a DFSR diagnostic report, or a propagation test. Two caveats on Get-DfsrBacklog: the object output lists at most the first 100 pending updates, so use the verbose total (or a structured wrapper) when you need the real count; and in a large domain, check the actual DFSR partner directions rather than running blind checks between every DC pair. Then review the DFS Replication event log:
$start = (Get-Date).AddDays(-7)
Get-WinEvent -FilterHashtable @{
LogName = 'DFS Replication'
StartTime = $start
} | Where-Object { $_.Id -in 2213,4012,5002,2214 } |
Select-Object TimeCreated, Id, Message | Format-ListEvent 2213 does not automatically mean a non-authoritative restore. It indicates DFSR detected a dirty shutdown and may have paused replication. Follow the event-specific recovery instruction, preserve the replicated data, resume DFSR, and confirm recovery via Event 2214. The event body historically shows a wmic resume command – but wmic is deprecated and disabled by default on Windows Server 2025, so use the CIM equivalent instead:
$volumeGuid = 'PUT-GUID-FROM-EVENT-2213-HERE'
$volume = Get-CimInstance -Namespace 'root\microsoftdfs' `
-ClassName DfsrVolumeConfig -Filter "VolumeGuid='$volumeGuid'"
Invoke-CimMethod -InputObject $volume -MethodName ResumeReplicationAfter resuming, confirm the method return value, confirm Events 2212/2214, and verify DFSR state and backlog. Only escalate to a D2/D4-style SYSVOL reinitialization if normal recovery fails or a documented procedure requires it.
Event 4012 is a content-freshness block, not merely a large backlog: a member was offline longer than MaxOfflineTimeInDays, and DFSR stopped replicating to prevent stale content from propagating. Identify which member holds authoritative SYSVOL content, review offline duration and topology, and only then use Microsoft’s documented authoritative/non-authoritative synchronization procedure. For detailed DFSR recovery, see SYSVOL Replication Issues in Active Directory: DFSR Troubleshooting.
Check 4: DNS
DNS and AD are tightly coupled, so DNS is a core part of any active directory health check. DNS is a common cause of replication error 1722, but RPC endpoint mapping, dynamic-port filtering, routing, service availability, and security controls are separate branches to check – don’t assume every 1722 is DNS. This part of the active directory health check covers the areas that actually fail in practice.
dcdiag /test:DNS /vThis runs several sub-tests and prints a summary table: columns Auth/Basc/Forw/Del/Dyn/RReg/Ext, one row per DC. Treat every FAIL as actionable. Treat a WARN as a documented exception only after reading the detailed sub-test output and confirming it matches the intended design (external resolution tests, for example, can fail by design in isolated networks). For full enterprise coverage, add /e.
nslookup -type=SRV _ldap._tcp.dc._msdcs.yourdomain.comIf SRV records are missing, force re-registration with nltest /dsregdns, then restart Netlogon. On DNS design: a DC must point at authoritative internal AD DNS. Pointing a DC at itself is supported and often recommended once replication is healthy – it is not automatically an error. The real risk is a DC relying only on a stale or isolated local copy, which creates a DNS island. During promotion and troubleshooting, verify both local and partner DNS paths rather than assuming self-reference is the fault. For full DNS troubleshooting, see Active Directory DNS Problems: SRV Records, Zones, and Resolution Failures.
Check 5: Time Synchronization
Time is where an active directory health check catches Kerberos problems before users do. Time drift is where an active directory health check catches Kerberos failures before users report them. The default Kerberos maximum clock-skew tolerance is five minutes, and it’s configurable by policy. Exceeding the effective value causes authentication failures between the affected client, service, and KDC – it does not necessarily break the entire domain at once. Keep domain offsets far below the limit rather than treating five minutes as a safe operating point.
w32tm /query /status
w32tm /monitor /domain:yourdomain.com
w32tm /query /configurationKey fields in the status output: Source (should be the forest-root PDC emulator’s approved external source, or the hierarchy above the local DC), Last Successful Sync Time, and Poll Interval. A Source of Local CMOS Clock means W32Time lost contact with its time source and needs attention. On the forest-root PDC emulator, verify Type = NTP with an approved external server; on other DCs, Type should be NT5DS following the domain hierarchy. A plus or minus 2-minute spread between DCs is a conservative internal alert threshold, not a Microsoft limit – it just keeps you well clear of the five-minute Kerberos ceiling. For recovery procedures, see Active Directory Time Synchronization: Fix PDC Emulator, W32Time, and Kerberos Clock Skew.
Check 6: FSMO Role Holders
Every active directory health check must confirm all five FSMO roles are held by reachable, functional DCs. The consequences of an outage are role-specific and often delayed, not immediate.
netdom query fsmo
dcdiag /test:KnowsOfRoleHolders /e /v
# Resolve and reach each role holder specifically:
Get-ADForest | Select-Object SchemaMaster, DomainNamingMaster
Get-ADDomain | Select-Object PDCEmulator, RIDMaster, InfrastructureMasterA missing RID Master blocks new RID-pool allocation, but DCs keep creating security principals while their local RID pools last, so account creation does not stop the instant the role holder goes offline. A missing PDC Emulator affects authoritative time, urgent password-change propagation, lockout coordination, and several administrative operations – but existing authentication and cached state continue. The Schema Master is only needed for schema changes. Resolve the actual holders with Get-ADForest and Get-ADDomain, then reach each one specifically – netdom query fsmo lists placement but doesn’t confirm each holder is responding. Run KnowsOfRoleHolders with /e to compare knowledge across all DCs; if they disagree on role placement, replication is broken between them. (nltest /dsgetdc tests DC Locator, not FSMO-holder availability – it belongs in the general reachability checks, not here.) For transfer, seize, and role-holder failure procedures, see FSMO Roles Active Directory: What They Do and How to Manage Them.
Check 7: Kerberos and Secure Channel
Services and event logs can look normal while Kerberos or the secure channel is broken, so no active directory health check is complete without checking them directly. These checks catch failures that don’t surface in service state.
nltest /sc_verify:yourdomain.comDo not use Test-ComputerSecureChannel on a domain controller. Microsoft documents false-positive results on DCs; the cmdlet is meant for domain member computers. Use nltest or netdom on a DC, and correlate the result with Netlogon events, replication status, DNS resolution, and actual authentication symptoms. A genuinely broken secure channel causes sporadic authentication failures and 8453 access-denied replication errors, usually from a computer-account password out of sync.
$start = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4769
StartTime = $start
} -ErrorAction Stop | ForEach-Object {
$xml = [xml]$_.ToXml()
$data = @{}
foreach ($item in $xml.Event.EventData.Data) { $data[$item.Name] = $item.'#text' }
if ($data.Status -eq '0x25') {
[pscustomobject]@{
TimeCreated = $_.TimeCreated
AccountName = $data.TargetUserName
ServiceName = $data.ServiceName
ClientAddress = $data.IpAddress
}
}
}Event 4769 with failure code 0x25 is a clock-skew failure (KRB_AP_ERR_SKEW). A persistent flood points at broken time sync – check the PDC emulator hierarchy first. Parse the named Status field from the event XML rather than a fixed property index: Microsoft has changed 4769’s field order across cumulative updates, so index-based parsing (Properties[6]) is brittle. This query requires Kerberos service-ticket auditing to be enabled and can be high-volume. A handful of isolated 0x25 events is not the same signal as a sustained pattern.
Check 8: Event Logs
Event logs surface slow-developing problems that commands in an active directory health check don’t expose, like a DC drifting toward tombstone lifetime. Always query with a time window – an old, already-resolved event should not mark the environment unhealthy forever.
$start = (Get-Date).AddDays(-1)
Get-WinEvent -FilterHashtable @{
LogName = 'Directory Service'
Id = 1311,1864,2042
StartTime = $start
} -ErrorAction SilentlyContinue |
Select-Object TimeCreated, Id, Message | Format-List| Event ID | Source | Meaning | Action |
|---|---|---|---|
| 1311 | NTDS KCC | KCC can’t build a replication spanning tree – a path is broken | Investigate the unreachable DC or site link |
| 1864 | NTDS Replication | One or more partitions haven’t replicated within expected ranges – read the body for the affected NC and age | Correlate with current replication metadata |
| 2042 | NTDS Replication | A partner exceeded the forest’s effective tombstone lifetime – lingering-object protection engaged | Urgent – replication blocked for that partner |
| 5719 | NETLOGON | Couldn’t locate a DC – often at startup before the network is ready | Investigate only if persistent or symptom-correlated |
| 5783 | NETLOGON | Secure channel to a DC is broken | Run nltest /sc_verify and correlate |
| 40960 | LSASRV | Kerberos/negotiate failure – time skew or KDC unreachable | Check W32Time hierarchy and KDC service |
Two caveats. Event 5719 is frequently transient at boot: a single startup instance followed by a successful secure-channel setup is usually noise, so investigate only persistent or symptom-correlated occurrences. And Events 1864/2042 reference the tombstone lifetime, which you should read from the directory rather than assume – see the database section below. A partner past the effective tombstone lifetime is blocked from replicating by default because the divergence risk is too high for AD to reconcile safely.
Check 9: dcdiag – Full Diagnostic Pass
dcdiag is the broadest single-command active directory health check on Windows Server. Run it at least weekly and after any structural change (DC promotion/demotion, site-link changes, schema updates).
dcdiag /e /c /q /skip:systemlog /f:dcdiag-output.txtThe SystemLog test fails constantly in production because of unrelated OS events – Windows Update, driver messages, anything that logged an error in the last hour. Skip it for routine scans and review the System log separately when investigating a specific incident. After any DC promotion, run the focused set that confirms the new DC advertises, has replicated, and has healthy SYSVOL before clients use it:
dcdiag /test:Advertising /test:Replications /test:SysVolCheck /test:DFSREvent /test:DNS /vA clean dcdiag is necessary but not sufficient. It tests configuration and state across roughly 20 areas, but it doesn’t check disk space, backup recency, GPO content correctness, absolute time accuracy, or security posture. For a complete test-by-test explanation and error-code breakdown, see DCDIAG Explained: How to Read and Interpret Domain Controller Diagnostics.
Check 10: AD Database and Recoverability
The AD database is the part of the active directory health check that rarely fails, but when NTDS.dit does fail the recovery path is painful. These checks take a couple of minutes and are worth running quarterly.
$ntdsPath = (Get-ItemProperty "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters")."DSA Database file"
$drive = Split-Path $ntdsPath -Qualifier
Get-PSDrive $drive.TrimEnd(':') | Select-Object Name, Used, FreeThe NTDS volume needs free space for defrag and log growth. Flag any volume below roughly 10% free (a RackNotes operational threshold – adjust to your database/log growth rate and recovery needs), and check the NTDS path, log path, SYSVOL volume, and backup staging space separately rather than assuming they share a disk. NTDS.dit grows and never shrinks automatically; AD runs online defragmentation as part of garbage collection every 12 hours by default, reclaiming space internally for reuse without reducing the file size, while offline defrag with ntdsutil reduces file size but requires stopping AD DS – a maintenance-window operation you should only do if the file is significantly oversized for your object count.
Now the tombstone and backup correction. The default tombstone lifetime for forests created on modern Windows Server versions is 180 days, but older forests can still carry 60 days, and upgrading a DC’s OS does not change an existing forest’s value. Never infer it from the OS – read it from the directory:
$root = Get-ADRootDSE
$ds = Get-ADObject -Identity "CN=Directory Service,CN=Windows NT,CN=Services,$($root.ConfigurationNamingContext)" `
-Properties tombstoneLifetime
# Unset attribute means AD uses the internal 60-day default
$effectiveTSL = if ($null -eq $ds.tombstoneLifetime) { 60 } else { [int]$ds.tombstoneLifetime }
$effectiveTSLBackup guidance follows from that value: keep at least one valid system-state backup per domain well within the actual tombstone lifetime. Microsoft’s guidance is to investigate when backup age exceeds half the TSL, but “once every 180 days” is not a recovery strategy. The real question is: if a DC failed right now, how old would your backup be? Most shops target daily or weekly system-state backups on at least one DC per domain, plus a documented restore procedure and the AD Recycle Bin enabled where approved. Recycle Bin is strongly recommended for recoverability, not a health requirement – a forest without it can still be operationally healthy.
Minimal Triage Script
This is a fast active directory health check triage script, not a complete health report. It surfaces the few things worth checking in seconds during a quick active directory health check when something feels off – service state, replication failures as objects, SYSVOL reachability, and recent Directory Service errors within a time window. It deliberately does not claim to validate DNS SRV records, pairwise SYSVOL backlog, time offsets, FSMO reachability, Kerberos, backups, or the database. For those, use the checks above, and for a full HTML report use a purpose-built tool (see below).
#Requires -Modules ActiveDirectory
# AD triage - run elevated on a DC. Structured output, not a verdict.
# Core services are checked on the LOCAL DC; SYSVOL reachability spans all DCs.
$results = [System.Collections.Generic.List[object]]::new()
function Add-Result($area, $state, $detail) {
$results.Add([pscustomobject]@{ Area=$area; State=$state; Detail=$detail })
}
# 1. Core services on the local DC
foreach ($svc in 'NTDS','Netlogon','KDC','ADWS','W32Time') {
$s = Get-Service $svc -ErrorAction SilentlyContinue
if (-not $s) { Add-Result 'Services' 'Unknown' "$svc not found" }
elseif ($s.Status -ne 'Running') { Add-Result 'Services' 'Failed' "$svc is $($s.Status)" }
else { Add-Result 'Services' 'Healthy' "$svc running" }
}
# 2. Replication - objects, with a catch so a failed query never reads as Healthy
try {
$replFail = Get-ADReplicationFailure -Target * -Scope Forest -ErrorAction Stop
if ($replFail) {
foreach ($f in $replFail) { Add-Result 'Replication' 'Failed' "$($f.Server) -> $($f.Partner): $($f.LastError)" }
} else {
Add-Result 'Replication' 'Healthy' 'No current replication failures returned'
}
} catch {
Add-Result 'Replication' 'Unknown' "Query failed: $($_.Exception.Message)"
}
# 3. SYSVOL/NETLOGON reachability across all DCs
try {
foreach ($dc in (Get-ADDomainController -Filter * -ErrorAction Stop)) {
foreach ($share in 'SYSVOL','NETLOGON') {
if (Test-Path "\\$($dc.HostName)\$share") { Add-Result 'SYSVOL' 'Healthy' "$($dc.HostName) $share reachable" }
else { Add-Result 'SYSVOL' 'Failed' "$($dc.HostName) $share unreachable" }
}
}
} catch {
Add-Result 'SYSVOL' 'Unknown' "DC enumeration failed: $($_.Exception.Message)"
}
# 4. Recent Directory Service errors on the local DC - time-windowed
$start = (Get-Date).AddDays(-1)
try {
$events = Get-WinEvent -FilterHashtable @{ LogName='Directory Service'; Id=1311,1864,2042; StartTime=$start } -ErrorAction Stop
foreach ($e in $events) { Add-Result 'Events' 'Warning' "Event $($e.Id) at $($e.TimeCreated)" }
} catch [Exception] {
if ($_.Exception.Message -match 'No events were found') {
Add-Result 'Events' 'Healthy' 'No 1311/1864/2042 in last 24h (local DC)'
} else {
Add-Result 'Events' 'Unknown' "Event query failed: $($_.Exception.Message)"
}
}
# Structured output - pipe to Format-Table, Export-Csv, or ConvertTo-Json
$results | Sort-Object Area, StateWhy this is safer than the usual checklist script: it never classifies informational repadmin text as an error, it wraps each query in try/catch so a failed lookup returns Unknown instead of a false Healthy, it checks SYSVOL reachability across all DCs (core services and the event query are local to the DC it runs on), it windows event queries so an old resolved event doesn’t read as a current failure, and it emits objects with explicit Healthy/Warning/Failed/Unknown states instead of colored console strings you can’t pipe anywhere. Commands in this article are local to the DC they run on unless stated otherwise – run event queries on every DC, or centralize through Windows Event Forwarding/SIEM, since a clean local log doesn’t describe the whole forest.
In Windows Server 2025 environments, any inherited health script that still calls wmic will fail. WMIC is disabled by default on WS2025, so a community script written before mid-2025 either errors out or silently skips its WMI checks – leaving you with a green report that never actually ran those tests. Review any third-party script for wmic before trusting it on a WS2025 DC, and replace WMIC calls with Get-CimInstance.
For a full PowerShell-based report with HTML output, ADxRay by Claudio Merola and ALI TAJRAN’s Get-ADHealth.ps1 are widely used in SMB environments and cover areas a minimal script doesn’t reach (security posture, object inventory, schema version). Both are externally maintained – review the source code, update history, required privileges, and output/data handling before running any community script with Domain Admin rights.
Common Active Directory Health Check Mistakes
These are the patterns that cause operators to miss real problems or waste time on non-problems during an active directory health check.
Checking only one DC. Replication failures are asymmetric – a problem between DC01 and DC03 won’t show up if you only run diagnostics on DC01 and DC02. Always use the asterisk (repadmin /showrepl *) and dcdiag /e to cover the whole forest.
Treating a 45-minute delta as a failure. This is the single most common misread. Intra-site changes propagate in seconds via change notification; the KCC builds and maintains topology but does not impose a 60-minute wait on normal intra-site changes. A 45-minute delta may be expected on an inter-site link and unusual for an active intra-site partner. Compare against topology and repeated observations, not a fixed number.
Assuming DNS is healthy because name resolution works. Client-facing resolution can work fine while SRV registration is broken, dynamic updates are disabled, or stale DC records cause RPC failures between DCs. Run dcdiag /test:DNS /v regardless.
Trusting event logs alone without running repadmin. The Directory Service log tells you something went wrong; it often won’t tell you which partner, which naming context, or the exact code. repadmin /showrepl * /errorsonly gives the specific failure. The event log is a signal to look, not a complete diagnosis.
Running dcdiag without /skip:systemlog and treating every failure as AD-related. The SystemLog test fires on anything in the System log in the last hour. In production it almost always “fails,” producing output with ten apparent failures where nine are noise. Use /skip:systemlog for routine scans.
Windows Server 2025 – Active Directory Health Check Changes
If any DC in your environment runs Windows Server 2025, these changes affect your existing active directory health check procedures now.
WMIC disabled by default. Any legacy script using wmic fails silently or with an error. Replace with Get-CimInstance. This includes popular community scripts and some monitoring agents not yet updated.
VBScript deprecated. VBS-based AD monitoring wrappers need migrating to PowerShell. VBScript became a Feature-on-Demand in WS2025 and is slated for removal in a future release.
PowerShell 2.0 engine removed (September 2025 update and later). Any tool depending specifically on the PS 2.0 engine stops working on updated WS2025 systems.
Credential Guard enabled by default. It protects domain credentials but can break legacy authentication protocols and older NTLM-based monitoring agents. Verify monitoring-agent compatibility before promoting WS2025 DCs into production.
New functional level and 32k database pages. Windows Server 2025 introduces a new functional level that enables an optional 32k database page size – the first ESE page-size change since Windows 2000. It’s forest-wide, requires all DCs on WS2025 first, is enabled explicitly, and is irreversible once turned on. Don’t enable it under time pressure.
Cumulative-update currency. Rather than pinning to one KB forever, keep WS2025 DCs on the latest cumulative update and check the Windows Server 2025 release-health page. The firewall-profile reachability issue described earlier was fixed in KB5060842 and later; verify OS build and CU status, then confirm the active network profile after a restart:
Get-ComputerInfo | Select-Object WindowsProductName, OsBuildNumber
Get-NetConnectionProfileActive Directory Health Check – Cadence Reference
Use this as an operational template for the active directory health check. The goal is the right check at the right frequency, not the same full scan every day. Microsoft’s replication troubleshooting documentation covers the underlying topology and scheduling model behind these intervals.
Daily (automate where possible)
| Check | Command | Healthy signal |
|---|---|---|
| Core services | Get-Service NTDS,Netlogon,KDC,ADWS,W32Time (+ role services) | All running |
| Replication errors | repadmin /replsummary | No errors; deltas match the schedule for each link |
| Critical events | Directory Service log, 1311/1864/2042, last 24h | None in the window |
| DC reachability | nltest /dsgetdc:domain /force | Returns a DC without error |
After every change
| Check | Command | What to verify |
|---|---|---|
| Replication errors | repadmin /showrepl * /errorsonly | No failure entries returned |
| dcdiag core tests | dcdiag /test:Advertising /test:Replications /test:SysVolCheck /test:DNS /v | All PASSED |
| SYSVOL shares | Reachability across affected DCs | SYSVOL and NETLOGON present |
| FSMO knowledge | dcdiag /test:KnowsOfRoleHolders /e | All DCs agree on role holders |
Weekly
| Check | Command | What to verify |
|---|---|---|
| Full replication detail | repadmin /showrepl * /errorsonly | No failure entries returned |
| DFSR backlog | Get-DfsrBacklog (pairwise, both directions) | Within environment baseline |
| DNS test suite | dcdiag /test:DNS /v /e | All PASS, or WARN with a documented cause |
| dcdiag full pass | dcdiag /e /c /q /skip:systemlog /f:dcdiag-weekly.txt | No unexplained failures |
| Time hierarchy | w32tm /monitor /domain:yourdomain.com | Offsets well under the Kerberos ceiling |
| Secure channel | nltest /sc_verify:domain | Secure channel valid |
Quarterly
| Check | Command / action | What to verify |
|---|---|---|
| NTDS/log/SYSVOL free space | Check each volume separately | Adequate free space for growth and defrag |
| Backup recency | Check the actual backup platform | Valid system-state backup well within TSL |
| Tombstone lifetime | Query tombstoneLifetime from the directory | Known value; backup age well within it |
| AD Recycle Bin | Get-ADOptionalFeature “Recycle Bin Feature” – check EnabledScopes.Count | Enabled (scopes present) where approved |
| Trust health | Per trust: nltest /sc_verify:trusted.domain or netdom trust … /verify | Each trust verified (enumeration alone is not verification) |
| FSMO placement | netdom query fsmo | Roles distributed per design |
FAQ
How often should I perform an Active Directory health check?
Replication and service state: daily, ideally automated. A full active directory health check covering DNS, SYSVOL, time, FSMO, and dcdiag: weekly and after every structural change. Database, backup recency, tombstone lifetime, and trust health: quarterly. The cadence tables above map each command to its frequency.
What is the most important Active Directory health check?
Replication. Everything else – DNS records, Group Policy, Kerberos, SYSVOL – depends on it. A clean repadmin /showrepl * /errorsonly is one of the strongest signals that AD DS replication has no reported partner failures right now – though it’s not proof the entire environment is healthy. Fix replication errors before chasing anything else.
Can dcdiag detect all Active Directory problems?
No. dcdiag tests configuration and state across about 20 areas, but it doesn’t check disk space, backup recency, GPO content correctness, absolute time accuracy, or security posture. A clean dcdiag is necessary, not sufficient. See DCDIAG Explained for exactly what it does and doesn’t cover.
How do I know if SYSVOL replication is healthy?
Three signals together: SYSVOL and NETLOGON reachable on every DC; a pairwise Get-DfsrBacklog check (both directions) within your baseline; and no unresolved 2213 or 4012 in the DFS Replication log. Note that dfsrdiag replicationstate shows current activity, not total backlog – it’s not a substitute for the backlog check. SYSVOL can be shared while Group Policy content is stale on a specific DC, which is exactly what the backlog check catches.
What causes Active Directory replication failures?
Investigation priority, not a statistical ranking: DNS misconfiguration so DCs can’t resolve each other (error 1722), firewall blocking the RPC endpoint mapper on TCP 135 or the dynamic port range (also 1722), and permissions or secure-channel problems (error 8453). Longer-standing failures past the tombstone lifetime produce 8606 or 8614 and need more involved recovery. Start with repadmin /showrepl * /errorsonly to get the code, then follow it to the cause.
Is the default tombstone lifetime 60 or 180 days?
For forests created on modern Windows Server versions, 180 days. Older forests can still carry 60 days, and upgrading a DC’s OS doesn’t change the existing forest value. There’s a subtlety: if the tombstoneLifetime attribute is unset (common in legacy forests), AD falls back to an internal 60-day default rather than reporting a value, so the query has to handle null. Don’t assume it from the OS – read it from the Directory Service object in the configuration partition.
Final Thoughts
A structured active directory health check isn’t diagnostic housekeeping. Replication errors left unchecked for weeks become lingering-object problems. DNS misconfigurations that seem minor surface as replication failures on the next DC promotion. SYSVOL backlogs no one monitors leave some users on stale Group Policy long after the problem started.
The cadence tables turn the active directory health check into a routine built to catch those patterns early: daily automated checks on services and replication take seconds, the weekly dcdiag pass catches slow-developing failures, and the quarterly checks cover the rarely-failing-but-painful areas. The single most valuable habit is interpreting signals against your own topology and schedule rather than against fixed numbers copied from a checklist – that’s the difference between a health check that reflects reality and one that just prints green.
When something does fail, these cover the remediation side for each area: Active Directory Replication Not Working, SYSVOL Replication Issues (DFSR), Active Directory DNS Problems, Active Directory Time Synchronization, FSMO Roles, Group Policy in Active Directory, and DCDIAG Explained.
Last technically reviewed: July 2026.
Active Directory Series
16 articles — Windows Server 2025 · Forest & Domain · FSMO · GPO · Replication · DNS · Backup & Recovery