Public/Get-PatchStatus.ps1

function Get-PatchStatus {
    <#
    .SYNOPSIS
        Gets the current patch status for managed applications
    .DESCRIPTION
        Checks all managed applications for available updates and returns their status
        including deferral state, conflicting processes, and priority
    .PARAMETER AppId
        Optional specific application ID to check
    .PARAMETER ManagedOnly
        Only check applications defined in the managed catalog
    .PARAMETER IncludeDeferralState
        Include deferral state information in results
    .EXAMPLE
        Get-PatchStatus
        Gets status for all managed applications
    .EXAMPLE
        Get-PatchStatus -AppId 'Google.Chrome'
        Gets status for a specific application
    .EXAMPLE
        gps -ManagedOnly
        Uses alias to get status for managed applications only
    #>

    [CmdletBinding()]
    [Alias('gpst')]
    param(
        [Parameter()]
        [string]$AppId,
        
        [Parameter()]
        [switch]$ManagedOnly,
        
        [Parameter()]
        [switch]$IncludeDeferralState
    )
    
    Write-PatchLog "Checking patch status..." -Type Info
    
    try {
        # Ensure winget is available
        if (-not (Test-WingetAvailable -AutoInstall)) {
            Write-PatchLog "Winget not available - cannot check patch status" -Type Error
            return @()
        }
        
        # Get available updates
        $updates = Get-AvailableUpdate -AppId $AppId -ManagedOnly:$ManagedOnly
        
        # Get managed app configurations
        $managedApps = Get-ManagedApplicationsInternal
        
        $results = foreach ($update in $updates) {
            # Find managed app config
            $appConfig = $managedApps | Where-Object { $_.Id -eq $update.AppId } | Select-Object -First 1
            
            # Add deferral state if requested
            if ($IncludeDeferralState) {
                $deferralState = Get-StateFromRegistry -AppId $update.AppId
                $update | Add-Member -NotePropertyName 'DeferralState' -NotePropertyValue $deferralState -PassThru
            }
            else {
                $update
            }
        }
        
        Write-PatchLog "Patch status check complete. Found $($results.Count) updates." -Type Info
        return $results
    }
    catch {
        Write-PatchLog "Failed to check patch status: $_" -Type Error
        return @()
    }
}

function Get-PatchCompliance {
    <#
    .SYNOPSIS
        Gets compliance status for the device
    .DESCRIPTION
        Returns a compliance summary suitable for reporting to MDM systems
    .PARAMETER OutputFormat
        Output format: Object, JSON, or Hashtable
    .EXAMPLE
        Get-PatchCompliance
        Returns compliance object
    .EXAMPLE
        Get-PatchCompliance -OutputFormat JSON
        Returns JSON string for API submission
    #>

    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateSet('Object', 'JSON', 'Hashtable')]
        [string]$OutputFormat = 'Object'
    )
    
    try {
        $updates = Get-PatchStatus -ManagedOnly
        $deferralStates = Get-AllDeferralStates
        
        $critical = ($updates | Where-Object { $_.Priority -eq [UpdatePriority]::Critical }).Count
        $high = ($updates | Where-Object { $_.Priority -eq [UpdatePriority]::High }).Count
        $pastDeadline = ($deferralStates | Where-Object { $_.Phase -eq [DeferralPhase]::Elapsed }).Count
        
        $compliance = [PSCustomObject]@{
            Timestamp         = [datetime]::UtcNow.ToString('o')
            ComputerName      = $env:COMPUTERNAME
            Compliant         = ($updates.Count -eq 0)
            TotalPending      = $updates.Count
            CriticalPending   = $critical
            HighPending       = $high
            PastDeadline      = $pastDeadline
            WingetAvailable   = (Test-WingetAvailable)
            LastCheckTime     = [datetime]::UtcNow.ToString('o')
            PendingUpdates    = @($updates | ForEach-Object {
                @{
                    Id               = $_.AppId
                    Name             = $_.AppName
                    InstalledVersion = $_.InstalledVersion
                    AvailableVersion = $_.AvailableVersion
                    Priority         = $_.Priority.ToString()
                }
            })
        }
        
        switch ($OutputFormat) {
            'JSON' { 
                return $compliance | ConvertTo-Json -Depth 10 -Compress 
            }
            'Hashtable' {
                return @{
                    Timestamp       = $compliance.Timestamp
                    ComputerName    = $compliance.ComputerName
                    Compliant       = $compliance.Compliant
                    TotalPending    = $compliance.TotalPending
                    CriticalPending = $compliance.CriticalPending
                    PastDeadline    = $compliance.PastDeadline
                }
            }
            default { 
                return $compliance 
            }
        }
    }
    catch {
        Write-PatchLog "Failed to get compliance status: $_" -Type Error
        throw
    }
}