private/WinPEDrivers/CloudWinPEDriver/Get-CloudWinPEDriverOemVMware.ps1
|
#Requires -PSEdition Core function Get-CloudWinPEDriverOemVMware { <# .SYNOPSIS Discovers the latest VMware Tools ISO metadata from the VMware packages index. .DESCRIPTION Internal helper called by Update-OSDeployWinPEDriversCatalog. Fetches the VMware packages directory listing for the latest Windows Tools ISOs (both amd64 and arm64), parses filenames for version and build ID, and reads Last-Modified and Size from the index table. Returns a two-element array: [amd64, arm64]. .OUTPUTS [PSCustomObject[]] Two entries ordered [amd64, arm64]: Architecture, ReadmeUri, Id, Version, ReleaseDate, FileName, FileSizeMB, DownloadUri, Checksums. #> [CmdletBinding()] [OutputType([PSCustomObject[]])] param () try { $searchUri = $global:OSDeployModule.WinPEDrivers.'vmware'.UpdateUri if ([string]::IsNullOrWhiteSpace($searchUri)) { throw "vmware UpdateUri is not defined in winpedrivers.json." } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Fetching VMware packages directory listing" $response = Invoke-WebRequest -Uri $searchUri -UseBasicParsing -ErrorAction Stop $html = $response.Content # Parse both ISO entries from an Apache autoindex table # amd64: VMware-tools-windows-13.0.10-25056151.iso # arm64: VMware-tools-windows-arm-13.0.10-25056151.iso $amd64Match = [regex]::Match($html, '(VMware-tools-windows-(\d+\.\d+\.\d+)-(\d+)\.iso)') $arm64Match = [regex]::Match($html, '(VMware-tools-windows-arm-(\d+\.\d+\.\d+)-(\d+)\.iso)') if (-not $amd64Match.Success) { Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Could not find amd64 ISO filename on '$searchUri'. Page format may have changed." return } if (-not $arm64Match.Success) { Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Could not find arm64 ISO filename on '$searchUri'. Page format may have changed." return } $amd64File = $amd64Match.Groups[1].Value $amd64Version = $amd64Match.Groups[2].Value $amd64Id = $amd64Match.Groups[3].Value $arm64File = $arm64Match.Groups[1].Value $arm64Version = $arm64Match.Groups[2].Value $arm64Id = $arm64Match.Groups[3].Value Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] amd64='$amd64File' arm64='$arm64File'" # Parse Last-Modified and Size from the directory listing row for each file # Apache autoindex rows: <td align="right">2026-01-20 10:30 </td><td align="right"> 113M</td> $amd64Meta = Get-VMwareListingRow -Html $html -FileName $amd64File $arm64Meta = Get-VMwareListingRow -Html $html -FileName $arm64File $baseUri = $searchUri.TrimEnd('/') @( [PSCustomObject]@{ Architecture = 'amd64' ReadmeUri = $searchUri PackageId = $amd64Id Version = $amd64Version ReleaseDate = $amd64Meta.ReleaseDate FileName = $amd64File FileSizeMB = $amd64Meta.FileSizeMB DownloadUri = "$baseUri/$amd64File" Checksums = [PSCustomObject]@{} }, [PSCustomObject]@{ Architecture = 'arm64' ReadmeUri = $searchUri PackageId = $arm64Id Version = $arm64Version ReleaseDate = $arm64Meta.ReleaseDate FileName = $arm64File FileSizeMB = $arm64Meta.FileSizeMB DownloadUri = "$baseUri/$arm64File" Checksums = [PSCustomObject]@{} } ) } catch { Write-Warning "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] $($_.Exception.Message)" } } function Get-VMwareListingRow { param ([string]$Html, [string]$FileName) $releaseDate = '' $fileSizeMB = $null # Match the exact ISO row in the autoindex table; avoid adjacent .sha and .sig rows. $rowPattern = '(?is)<tr[^>]*>\s*<td[^>]*>.*?<a href="' + [regex]::Escape($FileName) + '">' + [regex]::Escape($FileName) + '</a></td>\s*<td[^>]*>\s*(?<Date>\d{4}-\d{2}-\d{2})(?:\s+\d{2}:\d{2}Z?)?\s*</td>\s*<td[^>]*>\s*(?<Size>\d+(?:\.\d+)?)\s*(?<Unit>[MGK]B?|B)?\s*</td>' $rowMatch = [regex]::Match($Html, $rowPattern) if ($rowMatch.Success) { $releaseDate = $rowMatch.Groups['Date'].Value $rawSize = [double]$rowMatch.Groups['Size'].Value $unit = $rowMatch.Groups['Unit'].Value.ToUpperInvariant() $fileSizeMB = switch ($unit) { 'GB' { [math]::Round($rawSize * 1024, 2) } 'G' { [math]::Round($rawSize * 1024, 2) } 'MB' { [math]::Round($rawSize, 2) } 'M' { [math]::Round($rawSize, 2) } 'KB' { [math]::Round($rawSize / 1024, 2) } 'K' { [math]::Round($rawSize / 1024, 2) } 'B' { [math]::Round($rawSize / 1MB, 2) } default { [math]::Round($rawSize, 2) } } } [PSCustomObject]@{ ReleaseDate = $releaseDate FileSizeMB = $fileSizeMB } } |