How to Check Active Directory Health with PowerShell: Automated Multi-DC Report

Active Directory is the backbone of many IT environments, but managing multiple domain controllers and ensuring their health can be time-consuming. PowerShell makes it easier by allowing you to automate health checks, compare multiple DCs, and even send reports via email.

In this post, we’ll cover:

  • Why AD health checks are important
  • Key tests to run across multiple DCs
  • A PowerShell script to automate the process
  • Sending the results via email

Why AD Health Checks Matter

A healthy AD ensures:

  • Reliable authentication for users and computers
  • Consistent replication between DCs
  • Proper DNS functionality
  • Detection of errors before they impact production

Common AD issues include: replication failures, lingering objects, DNS problems, or service failures. Regular health checks can prevent downtime and security issues.


Key Active Directory Tests

When running an AD health check, consider these tests:

  1. Domain Controller Connectivity – Can each DC be reached?
  2. Replication Status – Are all DCs replicating changes correctly?
  3. FSMO Role Availability – Are all Flexible Single Master Operations roles online?
  4. Event Logs – Look for critical AD-related errors or warnings.
  5. DNS Health – Are SRV records and forwarders functioning properly?
  6. Active Directory Sites & Services – Check replication links between multiple DCs.
  7. Time Synchronization – AD requires time to be synchronized across DCs.

PowerShell Script to Check AD Health Across Multiple DCs

Here’s a robust PowerShell script to automate AD health checks, including multiple DCs, and send the report via email.

# -----------------------------
# Active Directory Health Check
# -----------------------------

# Email settings
$smtpServer = "smtp.yourdomain.com"
$from = "[email protected]"
$to = "[email protected]"
$subject = "Active Directory Health Report"
$body = ""

# Get all domain controllers
$DCs = Get-ADDomainController -Filter *

$body += "Active Directory Health Report - $(Get-Date)`n"
$body += "=========================================`n`n"

foreach ($DC in $DCs) {
    $body += "Domain Controller: $($DC.Name)`n"
    $body += "---------------------------------`n"

    # Test connectivity
    if (Test-Connection -ComputerName $DC.HostName -Count 2 -Quiet) {
        $body += "Ping Test: Success`n"
    } else {
        $body += "Ping Test: Failed`n"
    }

    # Check replication
    $repStatus = Get-ADReplicationPartnerMetadata -Target $DC.HostName -Scope Domain |
                 Select-Object Server, LastReplicationSuccess
    foreach ($rep in $repStatus) {
        $body += "Replication with $($rep.Server): Last Success $($rep.LastReplicationSuccess)`n"
    }

    # Check FSMO roles on this DC
    $fsmoRoles = (Get-ADDomain).FSMORoleOwner
    foreach ($role in $fsmoRoles) {
        $body += "FSMO Role Owner: $role`n"
    }

    # Check AD event logs for errors in last 24 hours
    $errors = Get-WinEvent -ComputerName $DC.HostName -FilterHashtable @{
        LogName='Directory Service'
        Level=2
        StartTime=(Get-Date).AddDays(-1)
    }
    if ($errors.Count -gt 0) {
        $body += "AD Errors in Event Log: $($errors.Count)`n"
    } else {
        $body += "AD Errors in Event Log: None`n"
    }

    # DNS SRV check
    $dnsTest = Resolve-DnsName -Name "_ldap._tcp.$($DC.Domain)" -Type SRV -ErrorAction SilentlyContinue
    if ($dnsTest) {
        $body += "DNS SRV Records: OK`n"
    } else {
        $body += "DNS SRV Records: Missing or Failed`n"
    }

    # Time sync check
    $timeDiff = (Get-Date) - (Get-WmiObject Win32_OperatingSystem -ComputerName $DC.HostName).LocalDateTime
    $body += "Time Difference with Local: $([math]::Round($timeDiff.TotalSeconds,2)) seconds`n"

    $body += "`n"
}

# Send report via email
Send-MailMessage -SmtpServer $smtpServer -From $from -To $to -Subject $subject -Body $body

Write-Host "AD Health Check completed. Report sent to $to"

How This Script Works

  1. Fetch all Domain ControllersGet-ADDomainController
  2. Ping Test – Ensures DC is reachable
  3. Replication Check – Uses Get-ADReplicationPartnerMetadata
  4. FSMO Role Check – Ensures roles are available
  5. Event Log Scan – Checks for critical AD errors in the last 24 hours
  6. DNS SRV Test – Ensures LDAP service records are accessible
  7. Time Sync Check – Detects time differences that may cause replication issues
  8. Email Report – Sends a consolidated report to the admin team

Tips for Production Use

  • Schedule the script with Task Scheduler to run daily or weekly.
  • Store the report in a central share for historical comparison.
  • Extend the script to include OU health, group policy checks, or AD-integrated DNS audits.
  • Adjust email formatting for HTML reports if needed.

Conclusion

Monitoring AD health across multiple DCs is essential for preventing downtime and ensuring smooth operations. With PowerShell and a simple AI-assisted approach to generate scripts and improvements, you can automate health checks, reduce manual effort, and get actionable insights quickly.

Leave a Reply

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