当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 使用 PowerShell 脚本进行 Active Directory 运行状况检查

作者:精品下载站 日期:2024-12-14 18:41:46 浏览:13 分类:玩电脑

使用 PowerShell 脚本进行 Active Directory 运行状况检查


检查域控制器运行状况的好方法是什么?也许您想要向现有域添加新的域控制器,在执行此操作之前,您需要检查 Active Directory 运行状况。让我们看看如何使用优秀的 PowerShell 脚本对 Active Directory 进行健康检查。

为什么要检查 Active Directory 运行状况

如果出现事件、问题或必须应用的更改,最好检查域控制器的运行状况:

  • Active Directory 有问题

  • 域控制器之间存在问题

  • 在域控制器上进行 Windows 更新之前/之后

  • 在组织中安装新域控制器之前/之后

  • 域控制器降级之前/之后

Active Directory 运行状况检查 PowerShell 脚本

Get-ADHealth.ps1 PowerShell 脚本将检查 AD 环境的运行状况,并为您提供可用于识别和解决任何问题的报告:

  1. 服务器

  2. 地点

  3. 操作系统版本

  4. 操作大师角色

  5. 域名系统

  6. 正常运行时间(小时)

  7. DIT 可用空间 (%)

  8. 操作系统可用空间 (%)

  9. 域名解析服务

  10. NTDS服务

  11. 网络登录服务

  12. DCDIAG:广告

  13. DCDIAG:复制

  14. DCDIAG:FSMO KnowsOfRoleHolder

  15. DCDIAG:FSMO 检查

  16. DCDIAG:服务

  17. 处理时间

下载 Active Directory 运行状况检查 PowerShell 脚本

下载 Get-ADHealth.ps1 PowerShell 脚本并将其放置在域控制器 C:\scripts 文件夹中。如果您没有脚本文件夹,请创建一个。

确保该文件未被阻止,以防止运行脚本时出现任何错误。请阅读文章运行 PowerShell 脚本时出现未数字签名错误来了解更多信息。

另一种选择是将以下代码复制并粘贴到记事本中。将其命名为 Get-ADHealth.ps1 并将其放置在 C:\scripts 文件夹中。

<#
    .SYNOPSIS
    Get-ADHealth.ps1 - Domain Controller Health Check Script.

    .DESCRIPTION
    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.

    .OUTPUTS
    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.

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

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

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

    .LINK
    a-d.site/active-directory-health-check-powershell-script

    .NOTES
    Written by: ALI TAJRAN
    Website:    a-d.site
    LinkedIn:   linkedin.com/in/a-d

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

[CmdletBinding()]
Param(
    [Parameter( Mandatory = $false)]
    [string]$DomainName,

    [Parameter( Mandatory = $false)]
    [switch]$ReportFile,
        
    [Parameter( Mandatory = $false)]
    [switch]$SendEmail
)

#...................................
# Global Variables
#...................................

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

$smtpsettings = @{
    To         = '[email protected]'
    From       = '[email protected]'
    Subject    = "$reportemailsubject - $now"
    SmtpServer = "mail.domain.com"
    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 "..no 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>
                <style>
                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;}
                td.fail{background: #FF0000; color: #ffffff;}
                td.info{background: #85D4FF;}
                </style>
                <body>
                <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>
                        <p>
                        <table>
                        <tr>
                        <th>Server</th>
                        <th>Site</th>
                        <th>OS Version</th>
                        <th>Operation Master Roles</th>
                        <th>DNS</th>
                        <th>Ping</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>
                        </tr>"

# 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>$($reportline.site)</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.
                </body>
                </html>"

$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
    }
}

创建计划任务

假设您希望 Get-ADHealth.ps1 PowerShell 脚本自动运行并创建 AD 运行状况报告。阅读文章配置计划任务。

配置 SMTP 中继

您是否希望 Get-ADHealth.ps1 PowerShell 脚本通过电子邮件发送报告?在 PowerShell 脚本中的第 66-70 行中配置 SMTP 设置。如果没有它,它就无法发送电子邮件。

请阅读以下有关如何配置 SMTP 中继的文章:

  • 本地交换

  • 在线交流

创建 Active Directory 运行状况报告

要生成 Active Directory 运行状况报告,请执行以下步骤:

  1. 登录域控制器

  2. 以管理员身份运行 PowerShell

  3. 将目录路径更改为C:\scripts

  4. 运行.\Get-ADHealth.ps1 -ReportFile

PS C:\> cd C:\scripts
PS C:\scripts> .\Get-ADHealth.ps1 -ReportFile

这就是我们示例中的样子。

[玩转系统] 使用 PowerShell 脚本进行 Active Directory 运行状况检查

Get-ADHealth.ps1 PowerShell 脚本将生成 HTML 报告文件。该文件在脚本的同一目录中生成。

在此示例中,它是文件夹 C:\scripts

[玩转系统] 使用 PowerShell 脚本进行 Active Directory 运行状况检查

打开健康报告。

域控制器DC01-2019DC02-2019可达,所有测试均已通过。

[玩转系统] 使用 PowerShell 脚本进行 Active Directory 运行状况检查

让我们关闭域控制器 DC02-2019,运行脚本并检查报告状态。

运行状况报告将显示大多数测试的失败状态,这是正确的行为。

[玩转系统] 使用 PowerShell 脚本进行 Active Directory 运行状况检查

就是这样!

了解更多:使用 PowerShell 获取所有域控制器 »

结论

您了解了如何使用 Get-ADHealth.ps1 PowerShell 脚本检查 Active Directory 运行状况。 Active Directory 运行状况检查 PowerShell 脚本将检查域控制器并创建报告,这对于查看运行状况是否处于良好状态非常有用。

您喜欢这篇文章吗?您可能还喜欢使用 PowerShell 脚本检查 Windows Server 上的 TLS 设置。不要忘记关注我们并分享这篇文章。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯