private/WinPEDrivers/CloudWinPEDriver/Get-CloudWinPEDriverSurface.ps1
|
#Requires -PSEdition Core function Get-CloudWinPEDriverSurface { <# .SYNOPSIS Discovers the latest Microsoft Surface driver package metadata from a download details page. .DESCRIPTION Internal helper used by Update-OSDeployWinPEDriversCatalog for Surface Laptop models that publish their current MSI package on a Microsoft Download Center details page. The function selects the live MSI link exposed on the page, prefers Win11 MSI filenames when multiple current candidates are present, and returns normalized metadata for the catalog. .PARAMETER Name Surface source name from config.json. .OUTPUTS [PSCustomObject] with Architecture, ReadmeUri, Id, Version, ReleaseDate, FileName, FileSizeMB, DownloadUri, and Checksums. #> [CmdletBinding()] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name ) $sourceData = $global:OSDeployModule.WinPEDrivers.$Name if (-not $sourceData) { throw "Surface source '$Name' was not found in winpedrivers.json." } $searchUri = $sourceData.SearchUri if ([string]::IsNullOrWhiteSpace($searchUri)) { throw "Surface SearchUri is not defined for '$Name' in winpedrivers.json." } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Fetching Surface page '$searchUri' for '$Name'" $response = Invoke-WebRequest -Uri $searchUri -UseBasicParsing -ErrorAction Stop $msiLinks = @( $response.Links | Where-Object { $_.href -match '(?i)^https://download\.microsoft\.com/.+\.msi(?:\?|$)' } | ForEach-Object { $_.href } | Select-Object -Unique ) if (-not $msiLinks) { throw "Could not locate any MSI download links on '$searchUri'. Page format may have changed." } $preferredLinks = @($msiLinks | Where-Object { $_ -match '(?i)Win11' }) $selectedUri = if ($preferredLinks) { $preferredLinks[0] } else { $msiLinks[0] } $fileName = [System.IO.Path]::GetFileName(($selectedUri -split '\?')[0]) if ([string]::IsNullOrWhiteSpace($fileName)) { throw "Could not derive a file name from Surface download URI '$selectedUri'." } $versionMatch = [regex]::Match($fileName, '_(?<Version>\d+(?:\.\d+){3})\.msi$') $version = if ($versionMatch.Success) { $versionMatch.Groups['Version'].Value } else { $null } $releaseDate = $null $releaseDateMatch = [regex]::Match( $response.Content, '(?is)Date Published:\s*</h3>\s*<p[^>]*>\s*(?<Date>[^<]+?)\s*</p>' ) if ($releaseDateMatch.Success) { try { $releaseDate = (Get-Date -Date $releaseDateMatch.Groups['Date'].Value.Trim()).ToString('yyyy-MM-dd') } catch { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Could not parse release date '$($releaseDateMatch.Groups['Date'].Value.Trim())' for '$Name'" } } $fileSizeMb = $null try { $headResponse = Invoke-WebRequest -Uri $selectedUri -Method Head -UseBasicParsing -ErrorAction Stop $contentLength = @($headResponse.Headers['Content-Length']) | Select-Object -First 1 if ($contentLength) { $fileSizeMb = [math]::Round(([double]$contentLength) / 1MB, 1) } } catch { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] HEAD request failed for '$selectedUri': $($_.Exception.Message)" } $packResults = foreach ($pack in $sourceData.DriverPacks) { [PSCustomObject]@{ Architecture = $pack.Architecture ReadmeUri = $searchUri PackageId = if ($pack.PackageId) { $pack.PackageId } else { (($searchUri -split 'id=')[-1] -split '&')[0] } Version = $version ReleaseDate = $releaseDate FileName = $fileName FileSizeMB = $fileSizeMb DownloadUri = $selectedUri Checksums = [PSCustomObject]@{} } } foreach ($entry in $packResults) { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] '$Name' — Architecture='$($entry.Architecture)' Version='$($entry.Version)' ReleaseDate='$($entry.ReleaseDate)' FileName='$($entry.FileName)'" } $packResults } |