Private/Status/Write-DriverStatusLogsInternal.ps1

#Requires -Version 5.1

function Write-DriverStatusLogsInternal {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [psobject]$Report,

        [Parameter()]
        [string]$OutputPath
    )

    # Always write JSON artifact (dual-logging default requirement)
    $artifact = Write-DriverStatusArtifactInternal -Report $Report -OutputPath $OutputPath

    # Determine compliance severity -> event id/type mapping (stable for FleetDM/Osquery)
    $complianceStatus = $null
    try { $complianceStatus = [string]$Report.Compliance.Status } catch { $complianceStatus = $null }
    if (-not $complianceStatus) { $complianceStatus = 'Pending' }

    $entryType = 'Information'
    $eventId = 1200
    switch ($complianceStatus) {
        'Compliant'    { $entryType = 'Information'; $eventId = 1200 }
        'NonCompliant' { $entryType = 'Warning';     $eventId = 2200 }
        'Pending'      { $entryType = 'Warning';     $eventId = 2200 }
        'Error'        { $entryType = 'Error';       $eventId = 3200 }
        default        { $entryType = 'Warning';     $eventId = 2200 }
    }

    $attempted = $true
    $written = $false
    $err = $null

    $logName = $script:ModuleConfig.EventLogName
    $source = $script:ModuleConfig.EventLogSource

    # Build single-line JSON summary message (best for Osquery/FleetDM parsing)
    $upToDate = $false
    $scanIncomplete = $true
    $rebootPending = $false
    $updatesPendingCount = 0
    $hardwareIssuesCount = 0
    $errorsCount = 0

    try { $upToDate = [bool]$Report.Compliance.UpToDate } catch { $upToDate = $false }
    try { $scanIncomplete = [bool]$Report.Compliance.ScanIncomplete } catch { $scanIncomplete = $true }
    try { $rebootPending = [bool]$Report.Compliance.RebootPending } catch { try { $rebootPending = [bool]$Report.PendingReboot.IsRebootPending } catch { $rebootPending = $false } }
    try { $updatesPendingCount = [int]$Report.Updates.PendingCount } catch { $updatesPendingCount = 0 }
    try { $hardwareIssuesCount = [int]$Report.Devices.NonOkCount } catch { $hardwareIssuesCount = 0 }
    try { $errorsCount = @($Report.Updates.Errors).Count } catch { $errorsCount = 0 }

    $summary = [ordered]@{
        EventType = 'StatusSummary'
        SchemaVersion = '1.0'
        GeneratedAt = $Report.GeneratedAt
        ComputerName = $Report.Host.ComputerName
        OEM = $Report.OEM.Detected
        Model = $Report.Host.Hardware.Model
        CorrelationId = $Report.CorrelationId

        ComplianceStatus = $complianceStatus
        UpToDate = $upToDate
        ScanIncomplete = $scanIncomplete
        RebootPending = $rebootPending

        UpdatesPendingCount = $updatesPendingCount
        HardwareIssuesCount = $hardwareIssuesCount
        ErrorsCount = $errorsCount

        ArtifactPath = $artifact.Path
    }

    $msg = ($summary | ConvertTo-Json -Compress -Depth 6)

    try {
        # Only write if source exists (Initialize-DriverManagementLogging will create it when elevated)
        if ([System.Diagnostics.EventLog]::SourceExists($source)) {
            Write-EventLog -LogName $logName -Source $source -EventId $eventId -EntryType $entryType -Message $msg -ErrorAction Stop
            $written = $true

            # Emit per-issue events (bounded) so monitoring can alert on exact problems
            $maxIssueEvents = 25

            # 2101 UpdatePending (Warning) - avoid collision with Write-DriverLog's generic Warning event id (2001)
            $pending = @()
            try { $pending = @($Report.Updates.PendingUpdates | Select-Object -First $maxIssueEvents) } catch { $pending = @() }
            foreach ($u in $pending) {
                $evt = [ordered]@{
                    EventType = 'UpdatePending'
                    ComputerName = $Report.Host.ComputerName
                    CorrelationId = $Report.CorrelationId
                    Provider = $u.Provider
                    UpdateType = $u.UpdateType
                    Title = $u.Title
                    Identifier = $u.Identifier
                    InstalledVersion = $u.InstalledVersion
                    AvailableVersion = $u.AvailableVersion
                    Severity = $u.Severity
                    RebootRequired = $u.RebootRequired
                }
                Write-EventLog -LogName $logName -Source $source -EventId 2101 -EntryType Warning -Message ($evt | ConvertTo-Json -Compress -Depth 6) -ErrorAction SilentlyContinue
            }

            # 2102 HardwareIssue (Warning)
            $hw = @()
            try { $hw = @($Report.Devices.NonOkDevices | Select-Object -First $maxIssueEvents) } catch { $hw = @() }
            foreach ($d in $hw) {
                $evt = [ordered]@{
                    EventType = 'HardwareIssue'
                    ComputerName = $Report.Host.ComputerName
                    CorrelationId = $Report.CorrelationId
                    FriendlyName = $d.FriendlyName
                    Class = $d.Class
                    InstanceId = $d.InstanceId
                    Status = $d.Status
                    Problem = $d.Problem
                    ConfigManagerErrorCode = $d.ConfigManagerErrorCode
                    ErrorDescription = $d.ErrorDescription
                    Remediation = $d.Remediation
                    DriverProviderName = $d.DriverProviderName
                    DriverVersion = $d.DriverVersion
                    InfName = $d.InfName
                }
                Write-EventLog -LogName $logName -Source $source -EventId 2102 -EntryType Warning -Message ($evt | ConvertTo-Json -Compress -Depth 6) -ErrorAction SilentlyContinue
            }

            # 3101 ProviderScanError (Error) - avoid collision with Write-DriverLog's generic Error event id (3001)
            $scanErrs = @()
            try { $scanErrs = @($Report.Updates.Errors | Select-Object -First $maxIssueEvents) } catch { $scanErrs = @() }
            foreach ($e in $scanErrs) {
                $evt = [ordered]@{
                    EventType = 'ProviderScanError'
                    ComputerName = $Report.Host.ComputerName
                    CorrelationId = $Report.CorrelationId
                    Provider = $e.Provider
                    Stage = $e.Stage
                    Message = $e.Message
                    Details = $e.Details
                }
                Write-EventLog -LogName $logName -Source $source -EventId 3101 -EntryType Error -Message ($evt | ConvertTo-Json -Compress -Depth 6) -ErrorAction SilentlyContinue
            }
        }
        else {
            $written = $false
            $err = 'Event source missing (not elevated to create or not yet created)'
        }
    }
    catch {
        $written = $false
        $err = $_.Exception.Message
    }

    return [pscustomobject]@{
        EventLog = [pscustomobject]@{
            Attempted = $attempted
            Written = $written
            LogName = $logName
            Source = $source
            EventId = $eventId
            EntryType = $entryType
            Error = $err
        }
        JsonArtifact = [pscustomobject]@{
            Path = $artifact.Path
            Written = $artifact.Written
            Error = $artifact.Error
            Copy = $artifact.Copy
        }
    }
}