Public/Get-UpdateConfiguration.ps1

function Get-UpdateConfiguration {
    <#
    .SYNOPSIS
        Displays a summary of Windows Update configuration and health status.
 
    .DESCRIPTION
        Provides a quick overview of Windows Update configuration including:
        - Update source (Windows Update, WSUS, WUfB)
        - Policy source (Intune, GPO, RMM)
        - Patch management tool detection
        - Current version and Orchestrator status
        - Key registry settings
        - Detected issues
 
    .PARAMETER Detailed
        Show all registry settings and detailed configuration.
 
    .PARAMETER PassThru
        Return the configuration object instead of displaying formatted output.
 
    .EXAMPLE
        Get-UpdateConfiguration
        Displays a summary of Windows Update configuration.
 
    .EXAMPLE
        Get-UpdateConfiguration -Detailed
        Shows detailed configuration including all registry settings.
 
    .EXAMPLE
        $config = Get-UpdateConfiguration -PassThru
        Returns the configuration object for programmatic use.
 
    .NOTES
        Part of the WindowsUpdateTools module.
    #>


    [CmdletBinding()]
    param(
        [switch]$Detailed,
        [switch]$PassThru
    )

    # Get configuration from private function
    $config = Get-WUConfiguration

    # Get current OS version info
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    $buildNumber = [int]$os.BuildNumber
    $displayVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -ErrorAction SilentlyContinue).DisplayVersion
    $ubr = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -ErrorAction SilentlyContinue).UBR
    $fullBuild = "$buildNumber.$ubr"

    # Check Orchestrator version
    $orchestratorBuild = $null
    $orchestratorStale = $false
    $orchestratorPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Orchestrator"
    if (Test-Path $orchestratorPath) {
        $orchProps = Get-ItemProperty -Path $orchestratorPath -ErrorAction SilentlyContinue
        if ($orchProps.CurrentBuild) {
            $orchestratorBuild = $orchProps.CurrentBuild
            if ([int]$orchestratorBuild -ne $buildNumber) {
                $orchestratorStale = $true
            }
        }
    }

    # Add extra info to config object
    $config | Add-Member -NotePropertyName 'OSVersion' -NotePropertyValue $displayVersion -Force
    $config | Add-Member -NotePropertyName 'OSBuild' -NotePropertyValue $fullBuild -Force
    $config | Add-Member -NotePropertyName 'OrchestratorBuild' -NotePropertyValue $orchestratorBuild -Force
    $config | Add-Member -NotePropertyName 'OrchestratorStale' -NotePropertyValue $orchestratorStale -Force

    if ($PassThru) {
        return $config
    }

    # Display formatted output
    Write-Host ""
    Write-Host "=== Windows Update Configuration ===" -ForegroundColor Cyan
    Write-Host ""

    # System Info
    Write-Host "System Information:" -ForegroundColor White
    Write-Host " Windows Version: $displayVersion (Build $fullBuild)"
    if ($orchestratorBuild) {
        if ($orchestratorStale) {
            Write-Host " Orchestrator Build: $orchestratorBuild " -NoNewline
            Write-Host "[STALE - Mismatch!]" -ForegroundColor Red
        } else {
            Write-Host " Orchestrator Build: $orchestratorBuild " -NoNewline
            Write-Host "[OK]" -ForegroundColor Green
        }
    }
    Write-Host ""

    # Update Source
    Write-Host "Update Configuration:" -ForegroundColor White
    Write-Host " Update Source: $($config.UpdateSource)"
    Write-Host " Policy Source: $($config.PolicySource)"
    
    if ($config.WSUSConfigured) {
        Write-Host " WSUS Server: $($config.WSUSServer)" -ForegroundColor Yellow
    }

    if ($config.WindowsUpdateForBusiness) {
        Write-Host " WUfB Configured: Yes" -ForegroundColor Green
    }

    Write-Host ""

    # Patch Management
    Write-Host "Patch Management:" -ForegroundColor White
    if ($config.PatchManagementSource) {
        Write-Host " Managed By: $($config.PatchManagementSource)" -ForegroundColor Cyan
    } elseif ($config.RMMProvider) {
        Write-Host " RMM Detected: $($config.RMMProvider)"
        if ($config.RMMManaged) {
            Write-Host " RMM Managing Patches: Yes" -ForegroundColor Cyan
        }
    } else {
        Write-Host " Managed By: Windows Update (Default)"
    }

    if ($config.AutoUpdateEnabled) {
        Write-Host " Auto Update: Enabled" -ForegroundColor Green
    } else {
        Write-Host " Auto Update: Disabled" -ForegroundColor Yellow
    }

    Write-Host " Update Policy: $($config.UpdatePolicy)"
    Write-Host ""

    # Version Targeting
    if ($config.TargetReleaseVersionLocked) {
        Write-Host "Version Targeting:" -ForegroundColor White
        Write-Host " Target Version: $($config.TargetReleaseVersion)" -ForegroundColor Yellow
        Write-Host " Feature Updates: Blocked to specific version" -ForegroundColor Yellow
        Write-Host ""
    }

    # Deferral Settings - filter out provider entries and clean up display
    if ($config.DeferralSettings.Count -gt 0) {
        # Filter to only show actual deferral values (not provider names)
        $deferralKeys = $config.DeferralSettings.Keys | Where-Object { $_ -notmatch '_Provider$' -and $config.DeferralSettings[$_] -match '^\d+$' }
        if ($deferralKeys.Count -gt 0) {
            Write-Host "Deferral Settings:" -ForegroundColor White
            foreach ($key in $deferralKeys) {
                $value = $config.DeferralSettings[$key]
                # Clean up the key name for display
                $displayName = $key -replace 'MDM_', '' -replace 'Enrolled', '' -replace 'Update', ' Updates'
                $displayName = $displayName.Trim()
                if ($displayName) {
                    Write-Host " ${displayName}: $value days"
                }
            }
            Write-Host ""
        }
    }

    # Compatibility
    Write-Host "Compatibility:" -ForegroundColor White
    if ($config.Windows11_24H2_Compatible) {
        Write-Host " Windows 11 24H2: Compatible" -ForegroundColor Green
    } else {
        Write-Host " Windows 11 24H2: Not Compatible" -ForegroundColor Red
    }
    Write-Host ""

    # Issues
    if ($config.Issues.Count -gt 0) {
        Write-Host "Issues Detected ($($config.Issues.Count)):" -ForegroundColor Yellow
        foreach ($issue in $config.Issues) {
            if ($issue.Severity -eq 'Critical' -or $issue.Severity -eq 'Error') {
                Write-Host " [!] $($issue.Issue)" -ForegroundColor Red
            } elseif ($issue.Severity -eq 'Warning') {
                Write-Host " [!] $($issue.Issue)" -ForegroundColor Yellow
            } else {
                Write-Host " [i] $($issue.Issue)" -ForegroundColor Gray
            }
        }
        Write-Host ""
    }

    # Orchestrator warning
    if ($orchestratorStale) {
        Write-Host "WARNING: Stale Orchestrator State Detected" -ForegroundColor Red
        Write-Host " The Update Orchestrator thinks this is build $orchestratorBuild" -ForegroundColor Red
        Write-Host " but the actual build is $buildNumber." -ForegroundColor Red
        Write-Host " This causes UUP download failures and missing updates." -ForegroundColor Red
        Write-Host ""
        Write-Host " Fix: Run 'Repair-WindowsUpdate -ClearCache'" -ForegroundColor Cyan
        Write-Host ""
    }

    # Detailed registry settings
    if ($Detailed -and $config.RegistrySettings.Count -gt 0) {
        Write-Host "Registry Settings:" -ForegroundColor White
        foreach ($regKey in $config.RegistrySettings.Keys | Sort-Object) {
            $regValue = $config.RegistrySettings[$regKey]
            # Check if value is a hashtable and expand it
            if ($regValue -is [System.Collections.Hashtable] -or $regValue -is [System.Collections.IDictionary]) {
                Write-Host " [$regKey]" -ForegroundColor Gray
                foreach ($subKey in $regValue.Keys | Sort-Object) {
                    $subValue = $regValue[$subKey]
                    Write-Host " $subKey = $subValue" -ForegroundColor DarkGray
                }
            } else {
                Write-Host " $regKey = $regValue" -ForegroundColor Gray
            }
        }
        Write-Host ""
    }

    Write-Host "---" -ForegroundColor DarkGray
    Write-Host "Tip: Use -Detailed for registry settings, -PassThru for object output" -ForegroundColor DarkGray
}