private/WinPEDrivers/CloudWinPEDriver/Get-CloudWinPEDriverOemHp.ps1

#Requires -PSEdition Core

function Get-CloudWinPEDriverOemHp {
    <#
    .SYNOPSIS
        Discovers the latest HP WinPE 10/11 driver pack metadata from the HP DriverPack page.
 
    .DESCRIPTION
        Internal helper called by Update-OSDeployWinPEDriversCatalog. Fetches the HP WinPE
        DriverPack HTML page stored in config.json, parses the current WinPE 10/11
        row, and returns the latest x64 driver pack entry as a single-element array
        of PSCustomObjects. No extra metadata fetches, downloads, or extraction are
        performed.
 
    .OUTPUTS
        [PSCustomObject[]] One entry: Architecture, ReadmeUri, Id, Version, ReleaseDate,
        FileName, FileSizeMB, DownloadUri, Checksums.
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param ()

    try {
        $searchUri = $global:OSDeployModule.WinPEDrivers.'hp'.UpdateUri
        if ([string]::IsNullOrWhiteSpace($searchUri)) {
            throw "hp UpdateUri is not defined in winpedrivers.json."
        }

        $normalizeHtml = {
            param([AllowNull()][string]$Value)

            if ([string]::IsNullOrWhiteSpace($Value)) {
                return ''
            }

            $decoded = [System.Net.WebUtility]::HtmlDecode($Value)
            $text = [regex]::Replace($decoded, '<[^>]+>', ' ')
            ([regex]::Replace($text, '\s+', ' ')).Trim()
        }

        $convertReleaseDate = {
            param([string]$Value)

            foreach ($format in @('M/d/yyyy', 'MM/dd/yyyy', 'dd MMM yyyy', 'yyyy-MM-dd')) {
                try {
                    return [datetime]::ParseExact(
                        $Value,
                        $format,
                        [System.Globalization.CultureInfo]::InvariantCulture
                    ).ToString('yyyy-MM-dd')
                }
                catch {
                }
            }

            try { ([datetime]$Value).ToString('yyyy-MM-dd') }
            catch { $Value }
        }

        $getCellValue = {
            param(
                [string[]]$Cells,
                [int]$Index
            )

            if ($Index -lt $Cells.Count) {
                return $Cells[$Index]
            }

            $null
        }

        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Fetching HP WinPE DriverPack page '$searchUri'"
        $response = Invoke-WebRequest -Uri $searchUri -UseBasicParsing -ErrorAction Stop
        $html = $response.Content

        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Parsing WinPEDriverPacks table"
        $tableMatch = [regex]::Match(
            $html,
            '(?is)<table[^>]+id=["'']WinPEDriverPacks["''][^>]*>(?<Table>.*?)</table>'
        )

        $driverInfo = $null
        if ($tableMatch.Success) {
            foreach ($rowMatch in [regex]::Matches($tableMatch.Groups['Table'].Value, '(?is)<tr[^>]*>(?<Row>.*?)</tr>')) {
                $rowHtml = $rowMatch.Groups['Row'].Value
                $cells = @(
                    [regex]::Matches($rowHtml, '(?is)<t[dh][^>]*>(?<Cell>.*?)</t[dh]>') |
                        ForEach-Object { & $normalizeHtml $_.Groups['Cell'].Value }
                )

                if ($cells.Count -lt 4) {
                    continue
                }

                $packName = & $getCellValue $cells 0
                if ($packName -notmatch '(?i)^winpe\s*10/11$') {
                    continue
                }

                $links = [regex]::Matches($rowHtml, '(?is)<a[^>]+href=["''](?<Uri>[^"'']+)["''][^>]*>')
                $downloadUri = $null
                $readmeUri = $searchUri
                foreach ($link in $links) {
                    $uri = [System.Net.WebUtility]::HtmlDecode($link.Groups['Uri'].Value)
                    if (-not $downloadUri -and $uri -match '(?i)\.exe(?:\?|$)') {
                        $downloadUri = $uri
                        continue
                    }

                    if ($uri -match '(?i)WinPE(?:10|11)?\.html(?:\?|$)') {
                        $readmeUri = $uri
                    }
                }

                $id = & $getCellValue $cells 2
                if (-not $id -and $downloadUri) {
                    $id = [System.IO.Path]::GetFileNameWithoutExtension(($downloadUri -split '\?')[0])
                }

                $driverInfo = [PSCustomObject]@{
                    PackageId    = $id
                    Version      = & $getCellValue $cells 1
                    ReleaseDate  = & $convertReleaseDate (& $getCellValue $cells 3)
                    FileSizeMB   = $null
                    DownloadUri  = $downloadUri
                    FileName     = if ($downloadUri) { Split-Path -Path (($downloadUri -split '\?')[0]) -Leaf } else { $null }
                    ReadmeUri    = $readmeUri
                }
                break
            }
        }

        if (-not $driverInfo) {
            Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Could not locate the HP WinPE 10/11 driver pack on '$searchUri'."
            return
        }

        Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] PackageId='$($driverInfo.PackageId)' Version='$($driverInfo.Version)' ReleaseDate='$($driverInfo.ReleaseDate)' FileName='$($driverInfo.FileName)'"

        @(
            [PSCustomObject]@{
                Architecture = 'amd64'
                ReadmeUri    = $driverInfo.ReadmeUri
                PackageId    = $driverInfo.PackageId
                Version      = $driverInfo.Version
                ReleaseDate  = $driverInfo.ReleaseDate
                FileName     = $driverInfo.FileName
                FileSizeMB   = $driverInfo.FileSizeMB
                DownloadUri  = $driverInfo.DownloadUri
                Checksums    = [PSCustomObject]@{}
            }
        )
    }
    catch {
        Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] $($_.Exception.Message)"
    }
}