Public/Diagnostics/Debug-DomainController.ps1

<#
Copyright © 2024 Integris. For internal company use only. All rights reserved.
#>


FUNCTION Debug-DomainController {
    <#
    .SYNOPSIS
    Diagnoses and debugs domain controller issues.
 
    .DESCRIPTION
    This function runs DCDiag to diagnose and debug issues with domain controllers, optionally filtering for failed tests only.
 
    .PARAMETER FailedOnly
    Switch to return only failed tests.
 
    .PARAMETER Server
    The server to run the diagnostics on. Default is the local computer.
 
    .PARAMETER All
    Switch to run diagnostics on all domain controllers.
 
    .EXAMPLE
    Debug-DomainController -Server "DC01" -FailedOnly
 
    .NOTES
    The function uses DCDiag to perform diagnostics and parses the results for easier readability.
    #>


    [CmdletBinding(DefaultParameterSetName='None')]

    PARAM (
        [Parameter(ParameterSetName = 'All')]
        [Parameter(ParameterSetName = 'Server')]
        [Parameter(ParameterSetName = 'None')]
        [Switch]$FailedOnly = $False,

        [Parameter(ParameterSetName = 'Server')]
        [string]$Server = $env:COMPUTERNAME,

        [Parameter(ParameterSetName = 'All')]
        [Switch]$All = $False
    )

    $Results = @()

    ### Check for DCDIAG EXE
    IF ($Null -eq (Get-Item C:\Windows\System32\dcdiag.exe -ErrorAction SilentlyContinue)) {
        Write-Warning "The DCDiag.exe tool was not found. Please re-run this command on a computer with the DCDiag."
        RETURN
    }

    ### Run DCDiag
    IF ($All -eq $True) { $DCDIAG = DCDIAG /e }
    ELSE { $DCDIAG = DCDIAG /s:$Server }

    ### Check for DNS Resolution Issue
    IF ($DCDIAG -like "*not be resolved to an IP address. Check*") {
        Write-Warning "Unable to resolve name $Server. Please check server and DNS and try again."
        RETURN
    }

    ### Check for DNS Resolution Issue
    IF ($DCDIAG -like "*the addresses could be reached (pinged). Please check the*") {
        Write-Warning "Unable to connect to $Server. Please check the connection try again."
        RETURN
    }

    ### Parse Results
    IF ($FailedOnly -eq $False) {
        $DCDIAG | select-string -pattern '\. (.*) \b(passed|failed)\b test (.*)' | ForEach-Object {
            $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                TestName = (Get-Culture).TextInfo.ToTitleCase($_.Matches.Groups[3].Value)
                TestResult = (Get-Culture).TextInfo.ToTitleCase($_.Matches.Groups[2].Value)
                Entity = (Get-Culture).TextInfo.ToTitleCase($_.Matches.Groups[1].Value)
            }
        }
    }
    IF ($FailedOnly -eq $True) {
        $DCDIAG | select-string -pattern '\. (.*) \b(failed)\b test (.*)' | ForEach-Object {
            $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                TestName = (Get-Culture).TextInfo.ToTitleCase($_.Matches.Groups[3].Value)
                TestResult = (Get-Culture).TextInfo.ToTitleCase($_.Matches.Groups[2].Value)
                Entity = (Get-Culture).TextInfo.ToTitleCase($_.Matches.Groups[1].Value)
            }
        }
        IF ($Results.Count -eq 0) {
            $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{
                TestName = "All"
                TestResult = "Passed"
                Entity = $env:COMPUTERNAME
            }
        }
    }

    ### Return Results
    RETURN $Results | Select-Object Entity, TestName, TestResult
}
New-Alias -Name Diagnose-DomainController -Value Debug-DomainController