Private/Status/New-DriverStatusReportInternal.ps1

#Requires -Version 5.1

function New-DriverStatusReportInternal {
    [CmdletBinding()]
    param(
        [Parameter()]
        [ValidateRange(1, 1680)]
        [int]$LookbackHours = 24,

        [Parameter()]
        [ValidateRange(50, 5000)]
        [int]$MaxEventsPerChannel = 500,

        [Parameter()]
        [switch]$IncludeDriverInventory
    )

    $now = Get-Date
    $start = $now.AddHours(-1 * $LookbackHours)

    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    $cs = Get-CimInstance -ClassName Win32_ComputerSystem
    $bios = Get-CimInstance -ClassName Win32_BIOS -ErrorAction SilentlyContinue

    $pending = Get-PendingRebootStateInternal
    $oemTooling = Get-OemToolingStateInternal
    $devices = Get-PnpNonOkDevicesInternal

    # Scan-only pending update discovery (no installs; may be incomplete if tooling is missing)
    $pendingUpdates = $null
    try { $pendingUpdates = Get-StatusPendingUpdatesInternal -OemTooling $oemTooling } catch { $pendingUpdates = $null }

    $kernelPnp411 = Get-KernelPnp411Internal -StartTime $start -MaxEvents $MaxEventsPerChannel

    $channels = @(
        'Microsoft-Windows-Kernel-PnP/Configuration'
        'Microsoft-Windows-DeviceSetupManager/Admin'
        'Microsoft-Windows-DriverFrameworks-UserMode/Operational'
        'Microsoft-Windows-DriverFrameworks-KernelMode/Operational'
        'System'
    )
    $channelsPresent = foreach ($l in $channels) {
        $x = Get-WinEvent -ListLog $l -ErrorAction SilentlyContinue
        if ($x) {
            [pscustomobject]@{ LogName = $l; Exists = $true; IsEnabled = $x.IsEnabled; RecordCount = $x.RecordCount }
        }
        else {
            [pscustomobject]@{ LogName = $l; Exists = $false; IsEnabled = $null; RecordCount = $null }
        }
    }

    $inventory = $null
    if ($IncludeDriverInventory) {
        $inventory = [pscustomobject]@{
            DriverStore = Get-DriverStoreInventoryInternal
        }
    }

    $health = Get-DriverHealthScoreInternal -NonOkDeviceCount $devices.NonOkCount -KernelPnp411Count $kernelPnp411.Count -IsRebootPending ([bool]$pending.IsRebootPending)

    # Compute machine-readable compliance summary for status mode consumers
    $pendingUpdateCount = 0
    $pendingUpdateItems = @()
    $updateScanErrors = @()
    $providerState = $null

    try { $pendingUpdateItems = @($pendingUpdates.PendingUpdates) } catch { $pendingUpdateItems = @() }
    try { $pendingUpdateCount = @($pendingUpdateItems).Count } catch { $pendingUpdateCount = 0 }
    try { $updateScanErrors = @($pendingUpdates.Errors) } catch { $updateScanErrors = @() }
    try { $providerState = $pendingUpdates.Providers } catch { $providerState = $null }

    $scanIncomplete = $true
    try {
        if ($providerState) {
            $allProviders = @($providerState.PSObject.Properties | ForEach-Object { $_.Value })
            $scanIncomplete = (@($allProviders | Where-Object { $_.Required -and (-not $_.Success) }).Count -gt 0)
        }
    }
    catch { $scanIncomplete = $true }

    $rebootPending = [bool]$pending.IsRebootPending
    $hardwareIssueCount = [int]$devices.NonOkCount
    $errorCount = @($updateScanErrors).Count

    $upToDate = (-not $scanIncomplete) -and (-not $rebootPending) -and ($pendingUpdateCount -eq 0) -and ($hardwareIssueCount -eq 0) -and ($errorCount -eq 0)

    $complianceStatus = [ComplianceStatus]::Unknown
    if ($errorCount -gt 0) {
        $complianceStatus = [ComplianceStatus]::Error
    }
    elseif ($rebootPending -or $scanIncomplete) {
        $complianceStatus = [ComplianceStatus]::Pending
    }
    elseif (($pendingUpdateCount -gt 0) -or ($hardwareIssueCount -gt 0)) {
        $complianceStatus = [ComplianceStatus]::NonCompliant
    }
    else {
        $complianceStatus = [ComplianceStatus]::Compliant
    }

    $complianceMessageParts = New-Object System.Collections.Generic.List[string]
    if ($upToDate) {
        $complianceMessageParts.Add('UpToDate') | Out-Null
    }
    else {
        $complianceMessageParts.Add(("UpdatesPending={0}" -f $pendingUpdateCount)) | Out-Null
        $complianceMessageParts.Add(("HardwareIssues={0}" -f $hardwareIssueCount)) | Out-Null
        if ($rebootPending) { $complianceMessageParts.Add('RebootPending=True') | Out-Null }
        if ($scanIncomplete) { $complianceMessageParts.Add('ScanIncomplete=True') | Out-Null }
        if ($errorCount -gt 0) { $complianceMessageParts.Add(("Errors={0}" -f $errorCount)) | Out-Null }
    }
    $complianceMessage = ($complianceMessageParts -join '; ')

    $report = [pscustomobject]@{
        SchemaVersion = '1.0'
        GeneratedAt = $now.ToString('o')
        Lookback = [pscustomobject]@{
            Hours = $LookbackHours
            StartTime = $start.ToString('o')
            EndTime = $now.ToString('o')
        }
        CorrelationId = $script:CorrelationId
        Host = [pscustomobject]@{
            ComputerName = $env:COMPUTERNAME
            Domain = $env:USERDOMAIN
            OS = [pscustomobject]@{
                Caption = $os.Caption
                Version = $os.Version
                BuildNumber = $os.BuildNumber
            }
            BIOS = [pscustomobject]@{
                SMBIOSBIOSVersion = $bios.SMBIOSBIOSVersion
                ReleaseDate = if ($bios.ReleaseDate) { ([datetime]$bios.ReleaseDate).ToString('o') } else { $null }
            }
            Hardware = [pscustomobject]@{
                Manufacturer = $cs.Manufacturer
                Model = $cs.Model
                SystemSKU = $cs.SystemSKUNumber
            }
        }
        OEM = $oemTooling
        PendingReboot = $pending
        Devices = $devices
        Updates = if ($pendingUpdates) {
            [pscustomobject]@{
                PendingUpdates = @($pendingUpdates.PendingUpdates)
                PendingCount = @($pendingUpdates.PendingUpdates).Count
                Providers = $pendingUpdates.Providers
                Errors = @($pendingUpdates.Errors)
            }
        } else {
            [pscustomobject]@{
                PendingUpdates = @()
                PendingCount = 0
                Providers = $null
                Errors = @([pscustomobject]@{ Provider = 'Status'; Stage = 'Scan'; Message = 'Pending update scan failed to execute.'; Details = @{} })
            }
        }
        DriverSignals = [pscustomobject]@{
            KernelPnp = [pscustomobject]@{
                ProblemStarting411 = $kernelPnp411
            }
            DeviceInstall = [pscustomobject]@{
                ChannelsPresent = @($channelsPresent)
            }
            WUDriver = [pscustomobject]@{
                DriverUpdateEvents = @()
            }
        }
        Inventory = $inventory
        Health = $health
        Compliance = [pscustomobject]@{
            Status = $complianceStatus.ToString()
            UpToDate = $upToDate
            ScanIncomplete = $scanIncomplete
            RebootPending = $rebootPending
            UpdatesPending = $pendingUpdateCount
            HardwareIssues = $hardwareIssueCount
            Errors = $errorCount
            Message = $complianceMessage
        }
    }

    return $report
}