Public/HP.Client.Update/Public/Get-HPUpdate.ps1

function Get-HPUpdate {
    <#
    .SYNOPSIS
        Gets HP-recommended SoftPaq updates applicable to this computer.
 
    .DESCRIPTION
        Queries HP's platform-specific recommendation API and evaluates local
        device, file, BIOS, UWP, and component state without HP CMSL.
 
    .PARAMETER Type
        Returns updates in the specified HP update class. The default is All.
 
    .PARAMETER ReleaseType
        Returns updates matching the specified HP release type. The default is All.
 
    .EXAMPLE
        Get-HPUpdate -Type Drivers
    #>

    [CmdletBinding()]
    param(
        [switch]$All,
        [switch]$NoTestInstalled,
        [switch]$UseCachedCatalog,
        [switch]$Details,
        [ValidateSet('All', 'BIOS', 'Drivers', 'Software', 'Firmware', 'Accessories')]
        [string]$Type = 'All',
        [ValidateSet('All', 'Critical', 'Recommended', 'Routine')]
        [string]$ReleaseType = 'All',
        [string]$CatalogDirectory = (Get-HPUpdatePath -Name Catalogs)
    )

    if ($NoTestInstalled -and -not $All) { throw '-NoTestInstalled can only be used with -All.' }
    $device = Get-HPUpdateDeviceInfo
    $operatingSystem = Get-HPUpdateOperatingSystem
    $catalog = Get-HPUpdateCatalog -Platform $device.Platform -OperatingSystem $operatingSystem -UseCachedCatalog:$UseCachedCatalog -CatalogDirectory $CatalogDirectory
    $operatingSystem = $catalog.SelectedOperatingSystem
    $softpaqs = @($catalog.softpaqs)
    $driverInventory = @()
    $referenceCatalog = $null
    $fileVersionCache = @{}
    $appxPackages = @()
    if (-not $NoTestInstalled -and @($softpaqs | Where-Object { $_.type -eq 'Driver' }).Count) {
        $driverInventory = Get-HPUpdateDriverInventory
        $referenceCatalog = Get-HPUpdateReferenceCatalog -Platform $device.Platform -OperatingSystem $operatingSystem -CatalogDirectory $CatalogDirectory
        $appxPackages = @(Get-AppxPackage -ErrorAction Stop)
    }

    Write-Host "Evaluating HP update catalog for platform $($device.Platform) ($($device.Model)) ..."
    $candidateUpdates = [System.Collections.Generic.List[object]]::new()
    foreach ($softpaq in $softpaqs) {
        $isRequired = [string]$softpaq.isSoftpaqRequired -match '^(?i:true|1)$'
        $state = if ($NoTestInstalled) {
            [pscustomobject]@{ IsApplicable = $true; IsInstalled = $null; WhyApplicable = 'Installed state was not evaluated.'; Matches = @() }
        }
        elseif ($softpaq.type -eq 'Driver' -and [string]$softpaq.isUwpApp -match '^(?i:true|1)$') {
            Resolve-HPUpdateUwpState -Softpaq $softpaq -AppxPackages $appxPackages
        }
        elseif ($softpaq.type -eq 'Driver') {
            Resolve-HPUpdateState -Softpaq $softpaq -DriverInventory $driverInventory -ReferenceCatalog $referenceCatalog -OperatingSystem $operatingSystem -FileVersionCache $fileVersionCache
        }
        elseif ($softpaq.type -eq 'ROMPAQ') {
            Resolve-HPUpdateBiosState -Softpaq $softpaq
        }
        else {
            [pscustomobject]@{ IsApplicable = $true; IsInstalled = -not $isRequired; WhyApplicable = if ($isRequired) { 'HP recommends this SoftPaq for the current device state.' } else { 'HP reports this SoftPaq is current for the device.' }; Matches = @() }
        }
        $releaseDate = [datetime]::MinValue
        $null = [datetime]::TryParse([string]$softpaq.effectivityDate, [ref]$releaseDate)
        $update = [pscustomobject]@{
            ID = "sp$($softpaq.softpaqId)"
            SoftpaqID = "sp$($softpaq.softpaqId)"
            PackageID = [string]$softpaq.softpaqId
            Title = [string]$softpaq.title
            Name = [string]$softpaq.title
            Version = [string]$softpaq.version
            VendorVersion = [string]$softpaq.vendorVersion
            Type = [string]$softpaq.type
            Category = [string]$softpaq.categoryName
            ReleaseType = [string]$softpaq.releaseType
            Severity = [string]$softpaq.recommendedType
            ReleaseDate = $releaseDate
            Size = [long]$softpaq.softpaqBinarySize
            FileSize = [long]$softpaq.softpaqBinarySize
            DownloadUri = [uri]$softpaq.downloadUrl
            URL = [uri]$softpaq.downloadUrl
            MetadataUri = [uri]$softpaq.metadataUrl
            Sha256 = [string]$softpaq.softpaqSha256
            Installer = [pscustomobject]@{ Program = "sp$($softpaq.softpaqId).exe"; Arguments = [string]$softpaq.silentInstall; Unattended = -not [string]::IsNullOrWhiteSpace([string]$softpaq.silentInstall) }
            SuccessCodes = @($softpaq.successCodes)
            RebootCodes = @($softpaq.rebootCodes)
            IsApplicable = [bool]$state.IsApplicable
            IsInstalled = $state.IsInstalled
            WhyApplicable = [string]$state.WhyApplicable
            ApplicabilityRuleStatus = 1
            InstallRuleStatus = if ($NoTestInstalled) { $null } elseif ($state.IsInstalled) { 1 } else { 0 }
            MatchedDevices = @($state.Matches)
            ComponentFamily = [string]$state.FamilyKey
            PnpOutdated = [bool]$state.PnpOutdated
            CatalogPackage = $softpaq
        }
        $update.PSObject.TypeNames.Insert(0, 'HP.Client.Update.HPUpdate')
        if (-not $Details) {
            $properties = [string[]]@('ID', 'Name', 'Version', 'ReleaseDate', 'Type', 'Category', 'ReleaseType', 'URL', 'WhyApplicable')
            $propertySet = [System.Management.Automation.PSPropertySet]::new('DefaultDisplayPropertySet', $properties)
            $members = [System.Management.Automation.PSMemberSet]::new('PSStandardMembers', [System.Management.Automation.PSMemberInfo[]]@($propertySet))
            $update.PSObject.Members.Add($members)
        }
        $candidateUpdates.Add($update)
    }

    foreach ($family in ($candidateUpdates | Where-Object { $_.PnpOutdated -and $_.ComponentFamily } | Group-Object ComponentFamily | Where-Object Count -gt 1)) {
        $winner = $family.Group | Sort-Object ReleaseDate, PackageID -Descending | Select-Object -First 1
        if ($winner.IsInstalled -ne $false) {
            $winner.IsApplicable = $true
            $winner.IsInstalled = $false
            $winner.InstallRuleStatus = 0
            $winner.WhyApplicable = 'The active device component is below the HP reference version; this is the newest SoftPaq for that component family.'
        }
        foreach ($superseded in @($family.Group | Where-Object { $_ -ne $winner })) {
            $superseded.IsInstalled = $true
            $superseded.InstallRuleStatus = 1
            $superseded.WhyApplicable = "Superseded by $($winner.ID) for the same active device component family."
        }
    }

    foreach ($update in $candidateUpdates) {
        if (-not $All -and $update.IsInstalled -ne $false) { continue }
        $matchesType = switch ($Type) {
            'All' { $true }
            'BIOS' { $update.Category -like 'BIOS -*' }
            'Drivers' { $update.Category -like 'Driver -*' -or $update.Category -eq 'Manageability - Driver Pack' }
            'Software' { $update.Category -like 'Software -*' -or $update.Type -eq 'Application' }
            'Firmware' { $update.Category -match '(?i)firmware' -and $update.Category -notlike 'BIOS -*' }
            'Accessories' { $update.Category -match '^(?i)(dock|accessor)' }
        }
        if (-not $matchesType) { continue }
        if ($ReleaseType -ne 'All' -and $update.ReleaseType -ne $ReleaseType) { continue }
        $update
    }
}