Private/Kinds/ImageIntegrity.ps1

# The ImageIntegrity Kind: whether the Windows component store is still intact.
#
# Opt-in, and the only Check in Gutcheck that a Technician has to ask for by name. It takes
# minutes rather than seconds, which on a Customer's machine at a Customer Site is a real
# cost, and it answers a question worth asking only once other explanations are exhausted.
# It reaches a Run through -RunIntegrityCheck, which adds its Check Definition.

$script:ImageIntegrityNeedsAdmin = $true

function Get-ImageIntegrityData {
    [CmdletBinding()]
    [OutputType([psobject])]
    param([hashtable]$Parameters = @{})

    $state    = $null
    $scanned  = $false
    $message  = ''

    if ((Get-CurrentPrivilege) -ne 'admin') {
        return [pscustomobject]@{
            PSTypeName       = 'Gutcheck.Data.ImageIntegrity'
            Scanned          = $false
            Elevated         = $false
            ImageHealthState = $null
            Message          = ''
        }
    }

    Write-Host (Get-Text 'Console.Progress.ScanHealth') -ForegroundColor Gray
    try {
        $result  = Repair-WindowsImage -Online -ScanHealth -ErrorAction Stop
        $state   = "$($result.ImageHealthState)"
        $scanned = $true
    }
    catch { $message = $_.Exception.Message }

    [pscustomobject]@{
        PSTypeName       = 'Gutcheck.Data.ImageIntegrity'
        Scanned          = $scanned
        Elevated         = $true
        ImageHealthState = $state
        Message          = $message
    }
}

function ConvertTo-ImageIntegrityFinding {
    [CmdletBinding()]
    [OutputType([psobject])]
    param(
        [AllowNull()]$Data,
        [hashtable]$Parameters = @{}
    )

    if (-not (Get-DataProperty $Data 'Elevated')) {
        return New-Finding -Category Integrity -Check (Get-Text 'Check.ImageIntegrity.ComponentStore') -Severity INFO `
            -Value (Get-Text 'Value.ImageIntegrity.SkippedNeedsAdmin') `
            -Hint (Get-Text 'Hint.ImageIntegrity.RerunAndAllowTheAdmin')
    }

    if (-not (Get-DataProperty $Data 'Scanned')) {
        return New-UnavailableFinding -Category Integrity -Check (Get-Text 'Check.ImageIntegrity.ComponentStore') `
            -Hint ((Get-Text 'Hint.ImageIntegrity.ScanDidNotComplete') -f (Get-DataProperty $Data 'Message')).Trim()
    }

    # Healthy is the only answer that is not a problem. Repairable and NonRepairable are
    # both "this machine needs servicing", and the difference is how much.
    $state = "$(Get-DataProperty $Data 'ImageHealthState')"

    New-Finding -Category Integrity -Check (Get-Text 'Check.ImageIntegrity.ComponentStore') `
        -Severity $(if ($state -eq 'Healthy') { 'OK' } else { 'FAIL' }) -Value $state `
        -Hint (Get-Text 'Hint.ImageIntegrity.RepairDISMOnlineCleanupImage')
}