dist/temp/WindowsUpdateTools/Private/Get-WUSystemHealth.ps1

function Test-WUSystemHealth {
    <#
    .SYNOPSIS
        Performs quick Windows Update system health assessment.
 
    .DESCRIPTION
        Lightweight health check focusing on common Windows Update issues
        that require remediation. Used to determine if remediation is needed
        when no specific issues are detected.
 
    .PARAMETER LogPath
        Path to the log file for detailed logging.
 
    .EXAMPLE
        $health = Test-WUSystemHealth -LogPath "C:\Logs\wu.log"
 
    .NOTES
        This is a private function used internally by the WindowsUpdateTools module.
        Returns boolean health status and specific issue indicators.
    #>


    [CmdletBinding()]
    param(
        [string]$LogPath
    )

    Write-WULog -Message "Performing Windows Update system health assessment" -LogPath $LogPath

    # Initialize health result
    $healthResult = [PSCustomObject]@{
        Healthy = $true
        ComponentStoreCorruption = $false
        ServiceIssues = $false
        DiskSpaceIssues = $false
        RecentErrors = $false
        ConfigurationIssues = $false
        Issues = @()
        Summary = ""
    }

    try {
        # Quick service check
        Write-WULog -Message "Checking critical Windows Update services..." -LogPath $LogPath
        $criticalServices = @('wuauserv', 'BITS', 'cryptsvc')
        
        foreach ($serviceName in $criticalServices) {
            try {
                $service = Get-Service -Name $serviceName -ErrorAction Stop
                if ($service.Status -ne 'Running') {
                    $healthResult.ServiceIssues = $true
                    $healthResult.Healthy = $false
                    $healthResult.Issues += "Critical service '$serviceName' is not running"
                    Write-WULog -Message "Service issue detected: $serviceName is $($service.Status)" -Level Warning -LogPath $LogPath
                }
            }
            catch {
                $healthResult.ServiceIssues = $true
                $healthResult.Healthy = $false
                $healthResult.Issues += "Critical service '$serviceName' is not accessible"
                Write-WULog -Message "Service access issue: $serviceName - $($_.Exception.Message)" -Level Warning -LogPath $LogPath
            }
        }

        # Quick disk space check
        Write-WULog -Message "Checking system disk space..." -LogPath $LogPath
        try {
            $systemDrive = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq $env:SystemDrive }
            $freeSpaceGB = [math]::Round($systemDrive.FreeSpace / 1GB, 2)
            
            if ($freeSpaceGB -lt 5) {
                $healthResult.DiskSpaceIssues = $true
                $healthResult.Healthy = $false
                $healthResult.Issues += "Critical disk space - only $freeSpaceGB GB free"
                Write-WULog -Message "Critical disk space issue: $freeSpaceGB GB free" -Level Warning -LogPath $LogPath
            } elseif ($freeSpaceGB -lt 10) {
                $healthResult.DiskSpaceIssues = $true
                $healthResult.Issues += "Low disk space - $freeSpaceGB GB free"
                Write-WULog -Message "Low disk space warning: $freeSpaceGB GB free" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            Write-WULog -Message "Could not check disk space: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Quick component store health check
        Write-WULog -Message "Quick component store health check..." -LogPath $LogPath
        try {
            $dismOutput = & dism.exe /online /cleanup-image /checkhealth 2>&1
            $dismExitCode = $LASTEXITCODE
            
            if ($dismExitCode -ne 0 -or $dismOutput -like "*Component Store is repairable*") {
                $healthResult.ComponentStoreCorruption = $true
                $healthResult.Healthy = $false
                $healthResult.Issues += "Component store corruption detected"
                Write-WULog -Message "Component store corruption detected" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            Write-WULog -Message "Could not check component store health: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Check for recent Windows Update errors in event log
        Write-WULog -Message "Checking for recent Windows Update errors..." -LogPath $LogPath
        try {
            $recentErrors = Get-WinEvent -FilterHashtable @{
                LogName = 'Microsoft-Windows-WindowsUpdateClient/Operational'
                Level = 1..2  # Critical and Error
                StartTime = (Get-Date).AddDays(-3)
            } -MaxEvents 10 -ErrorAction SilentlyContinue

            if ($recentErrors -and $recentErrors.Count -gt 0) {
                $healthResult.RecentErrors = $true
                $healthResult.Issues += "Found $($recentErrors.Count) recent Windows Update errors"
                Write-WULog -Message "Found $($recentErrors.Count) recent Windows Update errors" -Level Warning -LogPath $LogPath
                
                # If many recent errors, consider unhealthy
                if ($recentErrors.Count -gt 3) {
                    $healthResult.Healthy = $false
                }
            }
        }
        catch {
            # Event log access issues are not critical for health assessment
            Write-WULog -Message "Could not check recent Windows Update errors: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Quick configuration check
        Write-WULog -Message "Checking basic Windows Update configuration..." -LogPath $LogPath
        try {
            # Check if Windows Update service is disabled
            $wuServiceConfig = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\wuauserv" -ErrorAction SilentlyContinue
            if ($wuServiceConfig -and $wuServiceConfig.Start -eq 4) {  # 4 = Disabled
                $healthResult.ConfigurationIssues = $true
                $healthResult.Healthy = $false
                $healthResult.Issues += "Windows Update service is disabled"
                Write-WULog -Message "Windows Update service is disabled at system level" -Level Warning -LogPath $LogPath
            }

            # Check if automatic updates are disabled via policy
            $auDisabled = Get-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name "NoAutoUpdate" -ErrorAction SilentlyContinue
            if ($auDisabled -and $auDisabled.NoAutoUpdate -eq 1) {
                $healthResult.ConfigurationIssues = $true
                $healthResult.Issues += "Automatic updates are disabled via Group Policy"
                Write-WULog -Message "Automatic updates disabled via Group Policy" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            Write-WULog -Message "Could not check Windows Update configuration: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Check for pending reboot that might be blocking updates
        try {
            $pendingReboot = Test-WUPendingReboot
            if ($pendingReboot) {
                $healthResult.Issues += "Pending reboot detected - may affect Windows Update operations"
                Write-WULog -Message "Pending reboot detected" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            Write-WULog -Message "Could not check pending reboot status: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Generate summary
        if ($healthResult.Healthy) {
            $healthResult.Summary = "System appears healthy for Windows Update operations"
            Write-WULog -Message "System health assessment: HEALTHY" -LogPath $LogPath
        } else {
            $issueCount = $healthResult.Issues.Count
            $healthResult.Summary = "System health issues detected ($issueCount issues found)"
            Write-WULog -Message "System health assessment: ISSUES DETECTED ($issueCount issues)" -Level Warning -LogPath $LogPath
        }

        # Log specific issue areas
        $issueAreas = @()
        if ($healthResult.ServiceIssues) { $issueAreas += "Services" }
        if ($healthResult.ComponentStoreCorruption) { $issueAreas += "Component Store" }
        if ($healthResult.DiskSpaceIssues) { $issueAreas += "Disk Space" }
        if ($healthResult.RecentErrors) { $issueAreas += "Recent Errors" }
        if ($healthResult.ConfigurationIssues) { $issueAreas += "Configuration" }

        if ($issueAreas.Count -gt 0) {
            Write-WULog -Message "Issue areas identified: $($issueAreas -join ', ')" -LogPath $LogPath
        }

        if ($healthResult.Issues.Count -gt 0) {
            Write-WULog -Message "Specific issues found:" -LogPath $LogPath
            foreach ($issue in $healthResult.Issues) {
                Write-WULog -Message " - $issue" -LogPath $LogPath
            }
        }

    }
    catch {
        $healthResult.Healthy = $false
        $healthResult.Issues += "Error during health assessment: $($_.Exception.Message)"
        $healthResult.Summary = "Health assessment failed"
        Write-WULog -Message "Error during system health assessment: $($_.Exception.Message)" -Level Error -LogPath $LogPath
    }

    return $healthResult
}