Skip to main content

What is an excellent way to check the Domain Controller health? Perhaps you want to add a new Domain Controller to an existing domain, and before doing that, you want to check the Active Directory health state. Let’s see how to health check Active Directory with an excellent PowerShell script.


Why you want to check Active Directory health

It’s good to check the Domain Controllers health if there are incidents, problems, or changes that you have to apply:

  • There is a problem with Active Directory
  • There are problems between Domain Controllers
  • Before/after a Windows Update on the Domain Controller
  • Before/after installing a new Domain Controller in the organization
  • Before/after a Domain Controller demote

Active Directory health check PowerShell script

The Get-ADHealth.ps1 PowerShell script will check the health of your AD environment and provide you with a report that you can use to identify and resolve any issues:

  1. Server
  2. Site
  3. OS Version
  4. Operation Master Roles
  5. DNS
  6. Ping
  7. Uptime (hrs)
  8. DIT Free Space (%)
  9. OS Free Space (%)
  10. DNS Service
  11. NTDS Service
  12. NetLogon Service
  13. DCDIAG: Advertising
  14. DCDIAG: Replications
  15. DCDIAG: FSMO KnowsOfRoleHolders
  16. DCDIAG: FSMO Check
  17. DCDIAG: Services
  18. Processing Time

Download Active Directory health check PowerShell script

Download and place Get-ADHealth.ps1 PowerShell script on the Domain Controller C:\scripts folder. If you don’t have a scripts folder, create one.

Ensure that the file is unblocked to prevent any errors when running the script. Read more in the article Not digitally signed error when running PowerShell script.

Another option is to copy and paste the below code into Notepad. Give it the name Get-ADHealth.ps1 and place it in the C:\scripts folder.

    Get-ADHealth.ps1 - Domain Controller Health Check Script.

    This script performs a list of common health checks to a specific domain, or the entire forest. The results are then compiled into a colour coded HTML report.

    The results are currently only output to HTML for email or as an HTML report file, or sent as an SMTP message with an HTML body.

    .PARAMETER DomainName
    Perform a health check on a specific Active Directory domain.

    .PARAMETER ReportFile
    Output the report details to a file in the current directory.

    .PARAMETER SendEmail
    Send the report via email. You have to configure the correct SMTP settings.

    .\Get-ADHealth.ps1 -ReportFile
    Checks all domains and all domain controllers in your current forest and creates a report.

    .\Get-ADHealth.ps1 -DomainName -ReportFile
    Checks all the domain controllers in the specified domain "" and creates a report.

    .\Get-ADHealth.ps1 -DomainName -SendEmail
    Checks all the domain controllers in the specified domain "" and sends the resulting report as an email message.


    Written by: ALI TAJRAN

    V1.00, 01/21/2023 - Initial version
    V1.10, 06/18/2023 - Added SMTP port to $smpsettings hashtable and date/time to $reportfilename

    [Parameter( Mandatory = $false)]

    [Parameter( Mandatory = $false)]
    [Parameter( Mandatory = $false)]

# Global Variables

$now = Get-Date
$date = $now.ToShortDateString()
[array]$allDomainControllers = @()
$reportime = Get-Date
$reportemailsubject = "Domain Controller Health Report"

$smtpsettings = @{
    To         = ''
    From       = ''
    Subject    = "$reportemailsubject - $now"
    SmtpServer = ""
    Port       = "25"

# Functions

# This function gets all the domains in the forest.
Function Get-AllDomains() {
    Write-Verbose "..running function Get-AllDomains"
    $allDomains = (Get-ADForest).Domains 
    return $allDomains

# This function gets all the domain controllers in a specified domain.
Function Get-AllDomainControllers ($DomainNameInput) {
    Write-Verbose "..running function Get-AllDomainControllers" 
    [array]$allDomainControllers = Get-ADDomainController -Filter * -Server $DomainNameInput
    return $allDomainControllers

# This function tests the name against DNS.
Function Get-DomainControllerNSLookup($DomainNameInput) {
    Write-Verbose "..running function Get-DomainControllerNSLookup" 
    try {
        $domainControllerNSLookupResult = Resolve-DnsName $DomainNameInput -Type A | select -ExpandProperty IPAddress

        $domainControllerNSLookupResult = 'Success'
    catch {
        $domainControllerNSLookupResult = 'Fail'
    return $domainControllerNSLookupResult

# This function tests the connectivity to the domain controller.
Function Get-DomainControllerPingStatus($DomainNameInput) {
    Write-Verbose "..running function Get-DomainControllerPingStatus" 
    If ((Test-Connection $DomainNameInput -Count 1 -quiet) -eq $True) {
        $domainControllerPingStatus = "Success"

    Else {
        $domainControllerPingStatus = 'Fail'
    return $domainControllerPingStatus

# This function tests the domain controller uptime.
Function Get-DomainControllerUpTime($DomainNameInput) {
    Write-Verbose "..running function Get-DomainControllerUpTime" 

    If ((Test-Connection $DomainNameInput -Count 1 -quiet) -eq $True) {
        try {
            $W32OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $DomainNameInput -ErrorAction SilentlyContinue
            $timespan = $W32OS.ConvertToDateTime($W32OS.LocalDateTime) - $W32OS.ConvertToDateTime($W32OS.LastBootUpTime)
            [int]$uptime = "{0:00}" -f $timespan.TotalHours
        catch [exception] {
            $uptime = 'WMI Failure'


    Else {
        $uptime = '0'
    return $uptime  

# This function checks the DIT file drive space.
Function Get-DITFileDriveSpace($DomainNameInput) {
    Write-Verbose "..running function Get-DITFileDriveSpace" 

    If ((Test-Connection $DomainNameInput -Count 1 -quiet) -eq $True) {
        try {
            $key = "SYSTEM\CurrentControlSet\Services\NTDS\Parameters"
            $valuename = "DSA Database file"
            $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $DomainNameInput)
            $regkey = $reg.opensubkey($key)
            $NTDSPath = $regkey.getvalue($valuename)
            $NTDSPathDrive = $NTDSPath.ToString().Substring(0, 2)
            $NTDSPathFilter = '"' + 'DeviceID=' + "'" + $NTDSPathDrive + "'" + '"'
            $NTDSDiskDrive = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $DomainNameInput -ErrorAction SilentlyContinue | ? { $_.DeviceID -eq $NTDSPathDrive }
            $NTDSPercentFree = [math]::Round($NTDSDiskDrive.FreeSpace / $NTDSDiskDrive.Size * 100)
        catch [exception] {
            $NTDSPercentFree = 'WMI Failure'

    Else {
        $NTDSPercentFree = '0'
    return $NTDSPercentFree 

# This function checks the DNS, NTDS and Netlogon services.
Function Get-DomainControllerServices($DomainNameInput) {
    Write-Verbose "..running function DomainControllerServices"
    $thisDomainControllerServicesTestResult = New-Object PSObject
    $thisDomainControllerServicesTestResult | Add-Member NoteProperty -name DNSService -Value $null
    $thisDomainControllerServicesTestResult | Add-Member NoteProperty -name NTDSService -Value $null
    $thisDomainControllerServicesTestResult | Add-Member NoteProperty -name NETLOGONService -Value $null

    If ((Test-Connection $DomainNameInput -Count 1 -quiet) -eq $True) {
        If ((Get-Service -ComputerName $DomainNameInput -Name DNS -ErrorAction SilentlyContinue).Status -eq 'Running') {
            $thisDomainControllerServicesTestResult.DNSService = 'Success'
        Else {
            $thisDomainControllerServicesTestResult.DNSService = 'Fail'
        If ((Get-Service -ComputerName $DomainNameInput -Name NTDS -ErrorAction SilentlyContinue).Status -eq 'Running') {
            $thisDomainControllerServicesTestResult.NTDSService = 'Success'
        Else {
            $thisDomainControllerServicesTestResult.NTDSService = 'Fail'
        If ((Get-Service -ComputerName $DomainNameInput -Name netlogon -ErrorAction SilentlyContinue).Status -eq 'Running') {
            $thisDomainControllerServicesTestResult.NETLOGONService = 'Success'
        Else {
            $thisDomainControllerServicesTestResult.NETLOGONService = 'Fail'

    Else {
        $thisDomainControllerServicesTestResult.DNSService = 'Fail'
        $thisDomainControllerServicesTestResult.NTDSService = 'Fail'
        $thisDomainControllerServicesTestResult.NETLOGONService = 'Fail'
    return $thisDomainControllerServicesTestResult

# This function runs the five DCDiag tests and saves them in a variable for later processing.
Function Get-DomainControllerDCDiagTestResults($DomainNameInput) {
    Write-Verbose "..running function Get-DomainControllerDCDiagTestResults"

    $DCDiagTestResults = New-Object Object
    If ((Test-Connection $DomainNameInput -Count 1 -quiet) -eq $True) {

        $DCDiagTest = (Dcdiag.exe /s:$DomainNameInput /test:services /test:FSMOCheck /test:KnowsOfRoleHolders /test:Advertising /test:Replications) -split ('[\r\n]')

        $DCDiagTestResults | Add-Member -Type NoteProperty -Name "ServerName" -Value $DomainNameInput
        $DCDiagTest | % {
            Switch -RegEx ($_) {
                "Starting" { $TestName = ($_ -Replace ".*Starting test: ").Trim() }
                "passed test|failed test" {
                    If ($_ -Match "passed test") {
                        $TestStatus = "Passed"
                        # $TestName
                        # $_
                    Else {
                        $TestStatus = "Failed"
                        # $TestName
                        # $_
            If ($TestName -ne $Null -And $TestStatus -ne $Null) {
                $DCDiagTestResults | Add-Member -Name $("$TestName".Trim()) -Value $TestStatus -Type NoteProperty -force
                $TestName = $Null; $TestStatus = $Null
        return $DCDiagTestResults

    Else {
        $DCDiagTestResults | Add-Member -Type NoteProperty -Name "ServerName" -Value $DomainNameInput
        $DCDiagTestResults | Add-Member -Name Replications -Value 'Failed' -Type NoteProperty -force 
        $DCDiagTestResults | Add-Member -Name Advertising -Value 'Failed' -Type NoteProperty -force 
        $DCDiagTestResults | Add-Member -Name KnowsOfRoleHolders -Value 'Failed' -Type NoteProperty -force
        $DCDiagTestResults | Add-Member -Name FSMOCheck -Value 'Failed' -Type NoteProperty -force
        $DCDiagTestResults | Add-Member -Name Services -Value 'Failed' -Type NoteProperty -force 
    return $DCDiagTestResults

# This function checks the server OS version.
Function Get-DomainControllerOSVersion ($DomainNameInput) {
    Write-Verbose "..running function Get-DomainControllerOSVersion"
    $W32OSVersion = (Get-WmiObject -Class Win32_OperatingSystem -ComputerName $DomainNameInput -ErrorAction SilentlyContinue).Caption
    return $W32OSVersion

# This function checks the free space on the OS drive
Function Get-DomainControllerOSDriveFreeSpace ($DomainNameInput) {
    Write-Verbose "..running function Get-DomainControllerOSDriveFreeSpace"

    If ((Test-Connection $DomainNameInput -Count 1 -quiet) -eq $True) {
        try {
            $thisOSDriveLetter = (Get-WmiObject Win32_OperatingSystem -ComputerName $DomainNameInput -ErrorAction SilentlyContinue).SystemDrive
            $thisOSPathFilter = '"' + 'DeviceID=' + "'" + $thisOSDriveLetter + "'" + '"'
            $thisOSDiskDrive = Get-WmiObject -Class Win32_LogicalDisk -ComputerName $DomainNameInput -ErrorAction SilentlyContinue | ? { $_.DeviceID -eq $thisOSDriveLetter }
            $thisOSPercentFree = [math]::Round($thisOSDiskDrive.FreeSpace / $thisOSDiskDrive.Size * 100)

        catch [exception] {
            $thisOSPercentFree = 'WMI Failure'
    return $thisOSPercentFree

# This function generates HTML code from the results of the above functions.
Function New-ServerHealthHTMLTableCell() {
    param( $lineitem )
    $htmltablecell = $null

    switch ($($reportline."$lineitem")) {
        $success { $htmltablecell = "<td class=""pass"">$($reportline."$lineitem")</td>" }
        "Success" { $htmltablecell = "<td class=""pass"">$($reportline."$lineitem")</td>" }
        "Passed" { $htmltablecell = "<td class=""pass"">$($reportline."$lineitem")</td>" }
        "Pass" { $htmltablecell = "<td class=""pass"">$($reportline."$lineitem")</td>" }
        "Warn" { $htmltablecell = "<td class=""warn"">$($reportline."$lineitem")</td>" }
        "Access Denied" { $htmltablecell = "<td class=""warn"">$($reportline."$lineitem")</td>" }
        "Fail" { $htmltablecell = "<td class=""fail"">$($reportline."$lineitem")</td>" }
        "Failed" { $htmltablecell = "<td class=""fail"">$($reportline."$lineitem")</td>" }
        "Could not test server uptime." { $htmltablecell = "<td class=""fail"">$($reportline."$lineitem")</td>" }
        "Could not test service health. " { $htmltablecell = "<td class=""warn"">$($reportline."$lineitem")</td>" }
        "Unknown" { $htmltablecell = "<td class=""warn"">$($reportline."$lineitem")</td>" }
        default { $htmltablecell = "<td>$($reportline."$lineitem")</td>" }
    return $htmltablecell

if (!($DomainName)) {
    Write-Host " domain specified, using all domains in forest" -ForegroundColor Yellow
    $allDomains = Get-AllDomains
    $reportFileName = 'forest_health_report_' + (Get-ADForest).name + '_' + (Get-Date -Format "yyyyMMdd_HHmmss") + '.html'

Else {
    Write-Host "..domain name specified on cmdline"
    $allDomains = $DomainName
    $reportFileName = 'dc_health_report_' + $DomainName + '_' + (Get-Date -Format "yyyyMMdd_HHmmss") + '.html'

foreach ($domain in $allDomains) {
    Write-Host "..testing domain" $domain -ForegroundColor Green
    [array]$allDomainControllers = Get-AllDomainControllers $domain
    $totalDCtoProcessCounter = $allDomainControllers.Count
    $totalDCProcessCount = $allDomainControllers.Count 

    foreach ($domainController in $allDomainControllers) {
        $stopWatch = [system.diagnostics.stopwatch]::StartNew()
        Write-Host "..testing domain controller" "(${totalDCtoProcessCounter} of ${totalDCProcessCount})" $domainController.HostName -ForegroundColor Cyan 
        $DCDiagTestResults = Get-DomainControllerDCDiagTestResults $domainController.HostName
        $thisDomainController = New-Object PSObject
        $thisDomainController | Add-Member NoteProperty -name Server -Value $null
        $thisDomainController | Add-Member NoteProperty -name Site -Value $null
        $thisDomainController | Add-Member NoteProperty -name "OS Version" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "Operation Master Roles" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DNS" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "Ping" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "Uptime (hrs)" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DIT Free Space (%)" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "OS Free Space (%)" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DNS Service" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "NTDS Service" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "NetLogon Service" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DCDIAG: Advertising" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DCDIAG: Replications" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DCDIAG: FSMO KnowsOfRoleHolders" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DCDIAG: FSMO Check" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "DCDIAG: Services" -Value $null
        $thisDomainController | Add-Member NoteProperty -name "Processing Time" -Value $null
        $OFS = "`r`n"
        $thisDomainController.Server = ($domainController.HostName).ToLower()
        $thisDomainController.Site = $domainController.Site
        $thisDomainController."OS Version" = (Get-DomainControllerOSVersion $domainController.hostname)
        $thisDomainController."Operation Master Roles" = $domainController.OperationMasterRoles
        $thisDomainController.DNS = Get-DomainControllerNSLookup $domainController.HostName
        $thisDomainController.Ping = Get-DomainControllerPingStatus $domainController.HostName
        $thisDomainController."Uptime (hrs)" = Get-DomainControllerUpTime $domainController.HostName
        $thisDomainController."DIT Free Space (%)" = Get-DITFileDriveSpace $domainController.HostName
        $thisDomainController."OS Free Space (%)" = Get-DomainControllerOSDriveFreeSpace $domainController.HostName
        $thisDomainController."DNS Service" = (Get-DomainControllerServices $domainController.HostName).DNSService
        $thisDomainController."NTDS Service" = (Get-DomainControllerServices $domainController.HostName).NTDSService
        $thisDomainController."NetLogon Service" = (Get-DomainControllerServices $domainController.HostName).NETLOGONService
        $thisDomainController."DCDIAG: Replications" = $DCDiagTestResults.Replications
        $thisDomainController."DCDIAG: Advertising" = $DCDiagTestResults.Advertising
        $thisDomainController."DCDIAG: FSMO KnowsOfRoleHolders" = $DCDiagTestResults.KnowsOfRoleHolders
        $thisDomainController."DCDIAG: FSMO Check" = $DCDiagTestResults.FSMOCheck
        $thisDomainController."DCDIAG: Services" = $DCDiagTestResults.Services
        $thisDomainController."Processing Time" = $stopWatch.Elapsed.Seconds
        [array]$allTestedDomainControllers += $thisDomainController
        $totalDCtoProcessCounter -- 


# Common HTML head and styles
$htmlhead = "<html>
                BODY{font-family: Arial; font-size: 8pt;}
                H1{font-size: 16px;}
                H2{font-size: 14px;}
                H3{font-size: 12px;}
                TABLE{border: 1px solid black; border-collapse: collapse; font-size: 8pt;}
                TH{border: 1px solid black; background: #dddddd; padding: 5px; color: #000000;}
                TD{border: 1px solid black; padding: 5px; }
                td.pass{background: #7FFF00;}
                td.warn{background: #FFE600;}
      {background: #FF0000; color: #ffffff;}
      {background: #85D4FF;}
                <h1 align=""left"">Domain Controller Health Check Report</h1>
                <h3 align=""left"">Generated: $reportime</h3>"
# Domain Controller Health Report Table Header
$htmltableheader = "<h3>Domain Controller Health Summary</h3>
                        <h3>Forest: $((Get-ADForest).Name)</h3>
                        <th>OS Version</th>
                        <th>Operation Master Roles</th>
                        <th>Uptime (hrs)</th>
                        <th>DIT Free Space (%)</th>
                        <th>OS Free Space (%)</th>
                        <th>DNS Service</th>
                        <th>NTDS Service</th>
                        <th>NetLogon Service</th>
                        <th>DCDIAG: Advertising</th>
                        <th>DCDIAG: Replications</th>
                        <th>DCDIAG: FSMO KnowsOfRoleHolders</th>
                        <th>DCDIAG: FSMO Check</th>
                        <th>DCDIAG: Services</th>
                        <th>Processing Time</th>

# Domain Controller Health Report Table
$serverhealthhtmltable = $serverhealthhtmltable + $htmltableheader

# This section will process through the $allTestedDomainControllers array object and create and colour the HTML table based on certain conditions.
foreach ($reportline in $allTestedDomainControllers) {
    if (Test-Path variable:fsmoRoleHTML) {
        Remove-Variable fsmoRoleHTML

    if (($reportline."Operation Master Roles") -gt 0) {
        foreach ($line in $reportline."Operation Master Roles") {
            if ($line.count -gt 0) {
                [array]$fsmoRoleHTML += $line.ToString() + '<br>'

    else {
        $fsmoRoleHTML += 'None<br>'

    $htmltablerow = "<tr>"
    $htmltablerow += "<td>$($reportline.server)</td>"
    $htmltablerow += "<td>$($</td>"
    $htmltablerow += "<td>$($reportline."OS Version")</td>"
    $htmltablerow += "<td>$($fsmoRoleHTML)</td>"
    $htmltablerow += (New-ServerHealthHTMLTableCell "DNS" )                  
    $htmltablerow += (New-ServerHealthHTMLTableCell "Ping")

    if ($($reportline."uptime (hrs)") -eq "WMI Failure") {
        $htmltablerow += "<td class=""warn"">Could not test server uptime.</td>"        
    elseif ($($reportline."Uptime (hrs)") -eq $string17) {
        $htmltablerow += "<td class=""warn"">$string17</td>"
    else {
        $hours = [int]$($reportline."Uptime (hrs)")
        if ($hours -le 24) {
            $htmltablerow += "<td class=""warn"">$hours</td>"
        else {
            $htmltablerow += "<td class=""pass"">$hours</td>"

    $space = $reportline."DIT Free Space (%)"
    if ($space -eq "WMI Failure") {
        $htmltablerow += "<td class=""warn"">Could not test server free space.</td>"        
    elseif ($space -le 30) {
        $htmltablerow += "<td class=""warn"">$space</td>"
    else {
        $htmltablerow += "<td class=""pass"">$space</td>"

    $osSpace = $reportline."OS Free Space (%)"
    if ($osSpace -eq "WMI Failure") {
        $htmltablerow += "<td class=""warn"">Could not test server free space.</td>"        
    elseif ($osSpace -le 30) {
        $htmltablerow += "<td class=""warn"">$osSpace</td>"
    else {
        $htmltablerow += "<td class=""pass"">$osSpace</td>"

    $htmltablerow += (New-ServerHealthHTMLTableCell "DNS Service")
    $htmltablerow += (New-ServerHealthHTMLTableCell "NTDS Service")
    $htmltablerow += (New-ServerHealthHTMLTableCell "NetLogon Service")
    $htmltablerow += (New-ServerHealthHTMLTableCell "DCDIAG: Advertising")
    $htmltablerow += (New-ServerHealthHTMLTableCell "DCDIAG: Replications")
    $htmltablerow += (New-ServerHealthHTMLTableCell "DCDIAG: FSMO KnowsOfRoleHolders")
    $htmltablerow += (New-ServerHealthHTMLTableCell "DCDIAG: FSMO Check")
    $htmltablerow += (New-ServerHealthHTMLTableCell "DCDIAG: Services")
    $averageProcessingTime = ($allTestedDomainControllers | measure -Property "Processing Time" -Average).Average
    if ($($reportline."Processing Time") -gt $averageProcessingTime) {
        $htmltablerow += "<td class=""warn"">$($reportline."Processing Time")</td>"        
    elseif ($($reportline."Processing Time") -le $averageProcessingTime) {
        $htmltablerow += "<td class=""pass"">$($reportline."Processing Time")</td>"

    [array]$serverhealthhtmltable = $serverhealthhtmltable + $htmltablerow

$serverhealthhtmltable = $serverhealthhtmltable + "</table></p>"

$htmltail = "* Windows 2003 Domain Controllers do not have the NTDS Service running. Failing this test is normal for that version of Windows.<br>
    * DNS test is performed using Resolve-DnsName. This cmdlet is only available from Windows 2012 onwards.

$htmlreport = $htmlhead + $serversummaryhtml + $dagsummaryhtml + $serverhealthhtmltable + $dagreportbody + $htmltail

if ($ReportFile) {
    $htmlreport | Out-File $reportFileName -Encoding UTF8

if ($SendEmail) {
    try {
        # Send email message
        Send-MailMessage @smtpsettings -Body $htmlreport -BodyAsHtml -Encoding ([System.Text.Encoding]::UTF8) -ErrorAction Stop
        Write-Host "Email sent successfully." -ForegroundColor Green
    catch {
        Write-Host "Failed to send email. Error: $_" -ForegroundColor Red

Create scheduled task

Suppose you want the Get-ADHealth.ps1 PowerShell script to automatically run and create the AD health report.

Configure SMTP relay

Do you want the Get-ADHealth.ps1 PowerShell script to send the report by email? Configure the SMTP settings in lines 66-70 in the PowerShell script. Without that, it is not able to send an email.

Read the below articles on how to configure an SMTP relay:

  • Exchange on-premises
  • Exchange Online

Create Active Directory health report

To generate an Active Directory health report, go through the below steps:

  1. Sign in to a Domain Controller
  2. Run PowerShell as administrator
  3. Change directory path to C:\scripts
  4. Run .\Get-ADHealth.ps1 -ReportFile
PS C:\> cd C:\scripts
PS C:\scripts> .\Get-ADHealth.ps1 -ReportFile

This is how it looks in our example.

The Get-ADHealth.ps1 PowerShell script will generate an HTML report file. The file is generated in the same directory of the script.

In this example, it’s the folder C:\scripts.

Active Directory health check PowerShell script check files

Open the health report.

The Domain Controllers DC01-2019 and DC02-2019 are reachable, and all tests are passed.

Active Directory health check PowerShell script report

Let’s shut down Domain Controller DC02-2019, run the script, and check the report status.

The health report will show a fail state on most tests, which is the correct behavior.

Active Directory health check PowerShell script report failed

That’s it!

Leave a Reply