Private/Test-WUComponentStore.ps1

function Test-WUComponentStore {
    <#
    .SYNOPSIS
        Tests Windows Component Store health for corruption issues.
 
    .DESCRIPTION
        Performs component store health assessment using DISM CheckHealth and ScanHealth
        operations. Also analyzes CBS.log for corruption indicators.
 
    .PARAMETER LogPath
        Path to the log file for detailed logging.
 
    .EXAMPLE
        $componentHealth = Test-WUComponentStore -LogPath "C:\Logs\wu.log"
 
    .NOTES
        This is a private function used internally by the WindowsUpdateTools module.
        Returns component store health status and corruption indicators.
    #>


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

    Write-WULog -Message "Testing Component Store health" -LogPath $LogPath

    # Initialize results object
    $results = [PSCustomObject]@{
        CorruptionDetected = $false
        HealthCheckPassed = $false
        ScanHealthPassed = $false
        CBSLogIssues = 0
        Issues = @()
        CheckHealthExitCode = $null
        ScanHealthExitCode = $null
        ErrorMessage = $null
    }

    try {
        # Step 1: DISM CheckHealth (quick check)
        Write-WULog -Message "Running DISM CheckHealth..." -LogPath $LogPath
        
        try {
            $checkHealthOutput = & dism.exe /online /cleanup-image /checkhealth 2>&1
            $results.CheckHealthExitCode = $LASTEXITCODE
            
            Write-WULog -Message "DISM CheckHealth exit code: $($results.CheckHealthExitCode)" -LogPath $LogPath
            
            if ($results.CheckHealthExitCode -eq 0) {
                if ($checkHealthOutput -like "*Component Store is repairable*") {
                    $results.CorruptionDetected = $true
                    $results.Issues += "DISM CheckHealth detected repairable component store corruption"
                    Write-WULog -Message "Component store corruption detected by CheckHealth" -Level Warning -LogPath $LogPath
                } else {
                    $results.HealthCheckPassed = $true
                    Write-WULog -Message "DISM CheckHealth passed - no corruption detected" -LogPath $LogPath
                }
            } else {
                $results.Issues += "DISM CheckHealth failed with exit code: $($results.CheckHealthExitCode)"
                Write-WULog -Message "DISM CheckHealth failed with exit code: $($results.CheckHealthExitCode)" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            $results.Issues += "Error running DISM CheckHealth: $($_.Exception.Message)"
            Write-WULog -Message "Error running DISM CheckHealth: $($_.Exception.Message)" -Level Error -LogPath $LogPath
        }

        # Step 2: DISM ScanHealth (more thorough check) - only if CheckHealth passed or we want to be thorough
        if ($results.HealthCheckPassed -or $results.CorruptionDetected) {
            Write-WULog -Message "Running DISM ScanHealth for thorough analysis..." -LogPath $LogPath
            
            try {
                $scanHealthOutput = & dism.exe /online /cleanup-image /scanhealth 2>&1
                $results.ScanHealthExitCode = $LASTEXITCODE
                
                Write-WULog -Message "DISM ScanHealth exit code: $($results.ScanHealthExitCode)" -LogPath $LogPath
                
                if ($results.ScanHealthExitCode -eq 0) {
                    if ($scanHealthOutput -like "*Component Store corruption was detected*") {
                        $results.CorruptionDetected = $true
                        $results.Issues += "DISM ScanHealth confirmed component store corruption"
                        Write-WULog -Message "Component store corruption confirmed by ScanHealth" -Level Warning -LogPath $LogPath
                    } else {
                        $results.ScanHealthPassed = $true
                        Write-WULog -Message "DISM ScanHealth passed - no corruption detected" -LogPath $LogPath
                    }
                } else {
                    $results.Issues += "DISM ScanHealth failed with exit code: $($results.ScanHealthExitCode)"
                    Write-WULog -Message "DISM ScanHealth failed with exit code: $($results.ScanHealthExitCode)" -Level Warning -LogPath $LogPath
                }
            }
            catch {
                $results.Issues += "Error running DISM ScanHealth: $($_.Exception.Message)"
                Write-WULog -Message "Error running DISM ScanHealth: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
            }
        }

        # Step 3: Analyze CBS.log for corruption indicators
        Write-WULog -Message "Analyzing CBS.log for corruption indicators..." -LogPath $LogPath
        
        try {
            $cbsLogPath = "$env:WINDIR\Logs\CBS\CBS.log"
            if (Test-Path $cbsLogPath) {
                # Get recent entries (last 200 lines for better coverage)
                $recentCbsEntries = Get-Content $cbsLogPath -Tail 200 -ErrorAction SilentlyContinue
                
                if ($recentCbsEntries) {
                    $corruptionKeywords = @('corrupt', 'corruption', 'failed to repair', 'cannot repair', 'error 0x', 'failed', 'missing')
                    $corruptionIndicators = @()
                    
                    foreach ($line in $recentCbsEntries) {
                        $lineLower = $line.ToLower()
                        foreach ($keyword in $corruptionKeywords) {
                            if ($lineLower -like "*$keyword*" -and $lineLower -notlike "*successfully*") {
                                $corruptionIndicators += $line.Trim()
                                break
                            }
                        }
                    }
                    
                    $results.CBSLogIssues = $corruptionIndicators.Count
                    
                    if ($corruptionIndicators.Count -gt 0) {
                        $results.Issues += "Found $($corruptionIndicators.Count) potential corruption indicators in CBS.log"
                        Write-WULog -Message "Found $($corruptionIndicators.Count) potential corruption indicators in CBS.log" -Level Warning -LogPath $LogPath
                        
                        # Log a few examples (not all to avoid log spam)
                        $sampleIndicators = $corruptionIndicators | Select-Object -First 3
                        foreach ($indicator in $sampleIndicators) {
                            Write-WULog -Message " CBS Log indicator: $indicator" -LogPath $LogPath
                        }
                        
                        # If we have many indicators, this suggests corruption
                        if ($corruptionIndicators.Count -gt 5) {
                            $results.CorruptionDetected = $true
                            Write-WULog -Message "High number of corruption indicators suggests component store issues" -Level Warning -LogPath $LogPath
                        }
                    } else {
                        Write-WULog -Message "No corruption indicators found in recent CBS.log entries" -LogPath $LogPath
                    }
                } else {
                    $results.Issues += "Could not read CBS.log entries"
                    Write-WULog -Message "Could not read CBS.log entries" -Level Warning -LogPath $LogPath
                }
            } else {
                $results.Issues += "CBS.log not found at expected location"
                Write-WULog -Message "CBS.log not found at $cbsLogPath" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            $results.Issues += "Error analyzing CBS.log: $($_.Exception.Message)"
            Write-WULog -Message "Error analyzing CBS.log: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
        }

        # Step 4: Check for pending component store operations
        try {
            $pendingOperations = Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending"
            if ($pendingOperations) {
                $results.Issues += "Pending component store operations detected - reboot may be required"
                Write-WULog -Message "Pending component store operations detected" -Level Warning -LogPath $LogPath
            }
        }
        catch {
            Write-WULog -Message "Could not check for pending component store operations" -Level Warning -LogPath $LogPath
        }

    }
    catch {
        $results.ErrorMessage = $_.Exception.Message
        Write-WULog -Message "Critical error during component store health test: $($_.Exception.Message)" -Level Error -LogPath $LogPath
    }

    # Summary
    Write-WULog -Message "Component Store health test completed:" -LogPath $LogPath
    Write-WULog -Message " Corruption detected: $($results.CorruptionDetected)" -LogPath $LogPath
    Write-WULog -Message " Health check passed: $($results.HealthCheckPassed)" -LogPath $LogPath
    Write-WULog -Message " Scan health passed: $($results.ScanHealthPassed)" -LogPath $LogPath
    Write-WULog -Message " CBS log issues: $($results.CBSLogIssues)" -LogPath $LogPath
    Write-WULog -Message " Total issues found: $($results.Issues.Count)" -LogPath $LogPath

    if ($results.CorruptionDetected) {
        Write-WULog -Message "RECOMMENDATION: Run component store repair (DISM RestoreHealth)" -Level Warning -LogPath $LogPath
    }

    return $results
}