Domain Controller Analyzer Tool
<# .SYNOPSIS Domain Controller Analyzer Tool .DESCRIPTION This script analyzes Domain Controllers in an Active Directory environment, providing detailed information about DC health, replication status, performance metrics, and potential issues. .NOTES File Name : DCAnalyzer.ps1 Author : [Your Name] Prerequisite : PowerShell V5.1 or later, Active Directory module, and appropriate AD permissions Version : 1.0 Date : [Current Date] .EXAMPLE .\DCAnalyzer.ps1 #> # Import required modules Import-Module ActiveDirectory # Global variables $global:reportPath = "$env:USERPROFILE\Desktop\DC_Analysis_Report_$(Get-Date -Format 'yyyyMMdd_HHmmss').html" <# .SYNOPSIS Displays the main menu of the tool. #> function Show-Menu { Clear-Host Write-Host "=== Domain Controller Analyzer Tool ===" -ForegroundColor Cyan Write-Host "1. Perform DC Health Check" Write-Host "2. Analyze Replication Status" Write-Host "3. Check FSMO Roles" Write-Host "4. Analyze DC Performance Metrics" Write-Host "5. Check AD Services Status" Write-Host "6. Verify DNS Configuration" Write-Host "7. Analyze SYSVOL and NETLOGON Shares" Write-Host "8. Generate Comprehensive HTML Report" Write-Host "9. Exit" } <# .SYNOPSIS Performs a health check on all Domain Controllers. .OUTPUTS Array of PSObjects containing DC health check results. #> function Perform-DCHealthCheck { Write-Host "`nPerforming DC Health Check..." -ForegroundColor Yellow $dcs = Get-ADDomainController -Filter * $healthResults = @() foreach ($dc in $dcs) { $dcdiag = Invoke-Command -ComputerName $dc.HostName -ScriptBlock { dcdiag /test:services /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount /test:replications /test:netlogons /test:systemlog } -ErrorAction SilentlyContinue $healthResults += [PSCustomObject]@{ DomainController = $dc.HostName Services = if ($dcdiag -match "passed test Services") { "Passed" } else { "Failed" } Advertising = if ($dcdiag -match "passed test Advertising") { "Passed" } else { "Failed" } FSMORoles = if ($dcdiag -match "passed test FsmoCheck") { "Passed" } else { "Failed" } RidManager = if ($dcdiag -match "passed test RidManager") { "Passed" } else { "Failed" } MachineAccount = if ($dcdiag -match "passed test MachineAccount") { "Passed" } else { "Failed" } Replications = if ($dcdiag -match "passed test Replications") { "Passed" } else { "Failed" } Netlogons = if ($dcdiag -match "passed test NetLogons") { "Passed" } else { "Failed" } SystemLog = if ($dcdiag -match "passed test SystemLog") { "Passed" } else { "Failed" } } } $healthResults | Format-Table -AutoSize return $healthResults } <# .SYNOPSIS Analyzes replication status between Domain Controllers. .OUTPUTS Array of PSObjects containing replication status details. #> function Analyze-ReplicationStatus { Write-Host "`nAnalyzing Replication Status..." -ForegroundColor Yellow $replicationStatus = @() $dcs = Get-ADDomainController -Filter * foreach ($dc in $dcs) { $replStatus = repadmin /showrepl $dc.HostName | Select-String "Last attempt" -Context 2,0 foreach ($status in $replStatus) { $replicationStatus += [PSCustomObject]@{ SourceDC = $dc.HostName DestinationDC = ($status.Context.PreContext[0] -split ":")[1].Trim() LastAttempt = ($status.Line -split "@")[1].Trim() Result = $status.Context.PostContext[0].Trim() } } } $replicationStatus | Format-Table -AutoSize return $replicationStatus } <# .SYNOPSIS Checks FSMO roles distribution. .OUTPUTS PSObject containing FSMO roles information. #> function Check-FSMORoles { Write-Host "`nChecking FSMO Roles..." -ForegroundColor Yellow $forest = Get-ADForest $domain = Get-ADDomain $fsmoRoles = [PSCustomObject]@{ SchemaMaster = $forest.SchemaMaster DomainNamingMaster = $forest.DomainNamingMaster PDCEmulator = $domain.PDCEmulator RIDMaster = $domain.RIDMaster InfrastructureMaster = $domain.InfrastructureMaster } $fsmoRoles | Format-List return $fsmoRoles } <# .SYNOPSIS Analyzes performance metrics of Domain Controllers. .OUTPUTS Array of PSObjects containing DC performance metrics. #> function Analyze-DCPerformanceMetrics { Write-Host "`nAnalyzing DC Performance Metrics..." -ForegroundColor Yellow $dcs = Get-ADDomainController -Filter * $performanceMetrics = @() foreach ($dc in $dcs) { $cpu = Get-WmiObject Win32_Processor -ComputerName $dc.HostName | Measure-Object -Property LoadPercentage -Average | Select-Object -ExpandProperty Average $memory = Get-WmiObject Win32_OperatingSystem -ComputerName $dc.HostName | Select-Object @{Name="MemoryUsage";Expression={"{0:N2}" -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize)}} $disk = Get-WmiObject Win32_LogicalDisk -ComputerName $dc.HostName -Filter "DeviceID='C:'" | Select-Object @{Name="FreeSpace";Expression={"{0:N2}" -f ($_.FreeSpace/1GB)}} $performanceMetrics += [PSCustomObject]@{ DomainController = $dc.HostName CPUUsage = "$cpu%" MemoryUsage = "$($memory.MemoryUsage)%" FreeDiskSpace = "$($disk.FreeSpace) GB" } } $performanceMetrics | Format-Table -AutoSize return $performanceMetrics } <# .SYNOPSIS Checks the status of critical AD services on Domain Controllers. .OUTPUTS Array of PSObjects containing AD services status. #> function Check-ADServicesStatus { Write-Host "`nChecking AD Services Status..." -ForegroundColor Yellow $dcs = Get-ADDomainController -Filter * $servicesStatus = @() $criticalServices = @("NTDS", "Netlogon", "DNS", "DFSR", "KDC") foreach ($dc in $dcs) { $services = Get-Service -ComputerName $dc.HostName -Name $criticalServices -ErrorAction SilentlyContinue $servicesStatus += [PSCustomObject]@{ DomainController = $dc.HostName NTDS = ($services | Where-Object {$_.Name -eq "NTDS"}).Status Netlogon = ($services | Where-Object {$_.Name -eq "Netlogon"}).Status DNS = ($services | Where-Object {$_.Name -eq "DNS"}).Status DFSR = ($services | Where-Object {$_.Name -eq "DFSR"}).Status KDC = ($services | Where-Object {$_.Name -eq "KDC"}).Status } } $servicesStatus | Format-Table -AutoSize return $servicesStatus } <# .SYNOPSIS Verifies DNS configuration on Domain Controllers. .OUTPUTS Array of PSObjects containing DNS configuration details. #> function Verify-DNSConfiguration { Write-Host "`nVerifying DNS Configuration..." -ForegroundColor Yellow $dcs = Get-ADDomainController -Filter * $dnsConfig = @() foreach ($dc in $dcs) { $dnsServers = Get-DnsClientServerAddress -CimSession $dc.HostName -AddressFamily IPv4 | Where-Object {$_.InterfaceAlias -notlike "*Loopback*"} $dnsConfig += [PSCustomObject]@{ DomainController = $dc.HostName DNSServers = ($dnsServers.ServerAddresses -join ", ") HasDNSRole = [bool](Get-WindowsFeature -ComputerName $dc.HostName -Name DNS).Installed } } $dnsConfig | Format-Table -AutoSize return $dnsConfig } <# .SYNOPSIS Analyzes SYSVOL and NETLOGON shares on Domain Controllers. .OUTPUTS Array of PSObjects containing SYSVOL and NETLOGON share details. #> function Analyze-SYSVOLandNETLOGON { Write-Host "`nAnalyzing SYSVOL and NETLOGON Shares..." -ForegroundColor Yellow $dcs = Get-ADDomainController -Filter * $shareAnalysis = @() foreach ($dc in $dcs) { $sysvol = Get-WmiObject -Class Win32_Share -ComputerName $dc.HostName -Filter "Name='SYSVOL'" $netlogon = Get-WmiObject -Class Win32_Share -ComputerName $dc.HostName -Filter "Name='NETLOGON'" $shareAnalysis += [PSCustomObject]@{ DomainController = $dc.HostName SYSVOLPath = $sysvol.Path NETLOGONPath = $netlogon.Path SYSVOLAccessible = Test-Path "\\$($dc.HostName)\SYSVOL" -ErrorAction SilentlyContinue NETLOGONAccessible = Test-Path "\\$($dc.HostName)\NETLOGON" -ErrorAction SilentlyContinue } } $shareAnalysis | Format-Table -AutoSize return $shareAnalysis } <# .SYNOPSIS Generates a comprehensive HTML report of all analyses. .PARAMETER AllResults Hashtable containing all analysis results. .OUTPUTS Saves an HTML report to the desktop. #> function Generate-HTMLReport { param([hashtable]$AllResults) Write-Host "`nGenerating Comprehensive HTML Report..." -ForegroundColor Yellow $reportContent = @" <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Domain Controller Analysis Report</title> <style> body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 20px; } h1, h2, h3 { color: #0078D4; } table { border-collapse: collapse; width: 100%; margin-bottom: 20px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; } </style> </head> <body> <h1>Domain Controller Analysis Report</h1> <p>Generated on: $(Get-Date)</p> <h2>DC Health Check</h2> $($AllResults.HealthCheck | ConvertTo-Html -Fragment) <h2>Replication Status</h2> $($AllResults.ReplicationStatus | ConvertTo-Html -Fragment) <h2>FSMO Roles</h2> $($AllResults.FSMORoles | ConvertTo-Html -Fragment) <h2>DC Performance Metrics</h2> $($AllResults.PerformanceMetrics | ConvertTo-Html -Fragment) <h2>AD Services Status</h2> $($AllResults.ServicesStatus | ConvertTo-Html -Fragment) <h2>DNS Configuration</h2> $($AllResults.DNSConfig | ConvertTo-Html -Fragment) <h2>SYSVOL and NETLOGON Analysis</h2> $($AllResults.ShareAnalysis | ConvertTo-Html -Fragment) </body> </html> "@ $reportContent | Out-File -FilePath $global:reportPath Write-Host "Report generated and saved to: $global:reportPath" -ForegroundColor Green } # Main program loop $allResults = @{} do { Show-Menu $choice = Read-Host "`nEnter your choice (1-9)" switch ($choice) { "1" { $allResults.HealthCheck = Perform-DCHealthCheck } "2" { $allResults.ReplicationStatus = Analyze-ReplicationStatus } "3" { $allResults.FSMORoles = Check-FSMORoles } "4" { $allResults.PerformanceMetrics = Analyze-DCPerformanceMetrics } "5" { $allResults.ServicesStatus = Check-ADServicesStatus } "6" { $allResults.DNSConfig = Verify-DNSConfiguration } "7" { $allResults.ShareAnalysis = Analyze-SYSVOLandNETLOGON } "8" { Generate-HTMLReport -AllResults $allResults } "9" { Write-Host "Exiting program..." -ForegroundColor Yellow; break } default { Write-Host "Invalid choice. Please try again." -ForegroundColor Red } } if ($choice -ne "9") { Read-Host "`nPress Enter to continue..." } } while ($choice -ne "9")
This Domain Controller Analyzer Tool includes:
- A menu-driven interface for easy navigation.
- Functions to analyze various aspects of Domain Controllers:
- DC Health Check using dcdiag
- Replication Status analysis
- FSMO Roles check
- Performance Metrics analysis
- AD Services Status check
- DNS Configuration verification
- SYSVOL and NETLOGON share analysis
- Comprehensive error handling for each analysis function.
- A function to generate an HTML report of all collected data.
Key features:
- Detailed health check of all Domain Controllers
- Analysis of replication status between DCs
- Verification of FSMO roles distribution
- Performance metrics collection (CPU, Memory, Disk)
- Status check of critical AD services
- DNS configuration verification
- SYSVOL and NETLOGON share accessibility check
- HTML report generation for easy sharing and viewing of results
This tool is particularly useful for:
- Active Directory administrators
- System administrators managing Domain Controllers
- IT professionals troubleshooting AD issues
- Security teams auditing AD infrastructure
To use this script effectively:
- Run PowerShell as an administrator
- Ensure you have the necessary permissions to query Domain Controllers
- Have the Active Directory PowerShell module installed
This script provides a comprehensive overview of Domain Controllers in an Active Directory environment, making it easier to identify issues, performance bottlenecks, or misconfigurations. It can significantly streamline the process of maintaining and troubleshooting Domain Controllers in organizations of any size.

Leave a Reply
Want to join the discussion?Feel free to contribute!