# Function to get the list of Microsoft Surface models function Get-MicrosoftDriversModelList { [CmdletBinding()] param( [hashtable]$Headers, # Pass necessary headers [string]$UserAgent # Pass UserAgent ) $url = "https://support.microsoft.com/en-us/surface/download-drivers-and-firmware-for-surface-09bb2e09-2a4b-cb69-0951-078a7739e120" $models = @() try { WriteLog "Getting Surface driver information from $url" $OriginalVerbosePreference = $VerbosePreference $VerbosePreference = 'SilentlyContinue' # Use passed-in UserAgent and Headers $webContent = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers $Headers -UserAgent $UserAgent $VerbosePreference = $OriginalVerbosePreference WriteLog "Complete" WriteLog "Parsing web content for models and download links" $html = $webContent.Content $divPattern = ']*class="selectable-content-options__option-content(?: ocHidden)?"[^>]*>(.*?)' $divMatches = [regex]::Matches($html, $divPattern, [System.Text.RegularExpressions.RegexOptions]::Singleline) foreach ($divMatch in $divMatches) { $divContent = $divMatch.Groups[1].Value $tablePattern = ']*>(.*?)' $tableMatches = [regex]::Matches($divContent, $tablePattern, [System.Text.RegularExpressions.RegexOptions]::Singleline) foreach ($tableMatch in $tableMatches) { $tableContent = $tableMatch.Groups[1].Value $rowPattern = ']*>(.*?)' $rowMatches = [regex]::Matches($tableContent, $rowPattern, [System.Text.RegularExpressions.RegexOptions]::Singleline) foreach ($rowMatch in $rowMatches) { $rowContent = $rowMatch.Groups[1].Value $cellPattern = ']*>\s*(?:]*>)?(.*?)(?:

)?\s*' $cellMatches = [regex]::Matches($rowContent, $cellPattern, [System.Text.RegularExpressions.RegexOptions]::Singleline) if ($cellMatches.Count -ge 2) { $modelName = ([System.Net.WebUtility]::HtmlDecode(($cellMatches[0].Groups[1].Value).Trim())) $secondTdContent = $cellMatches[1].Groups[1].Value.Trim() # $linkPattern = ']+href="([^"]+)"[^>]*>' # Change linkPattern to match https://www.microsoft.com/download/details.aspx?id= $linkPattern = ']+href="(https://www\.microsoft\.com/download/details\.aspx\?id=\d+)"[^>]*>' $linkMatch = [regex]::Match($secondTdContent, $linkPattern, [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) if ($linkMatch.Success) { $modelLink = $linkMatch.Groups[1].Value } else { continue } $models += [PSCustomObject]@{ Make = 'Microsoft' Model = $modelName Link = $modelLink } } } } } WriteLog "Parsing complete. Found $($models.Count) models." return $models } catch { WriteLog "Error getting Microsoft models: $($_.Exception.Message)" throw "Failed to retrieve Microsoft Surface models." } } # Function to download and extract drivers for a specific Microsoft model (Modified for ForEach-Object -Parallel) function Save-MicrosoftDriversTask { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [PSCustomObject]$DriverItemData, # Pass data, not the UI object [Parameter(Mandatory = $true)] [string]$DriversFolder, [Parameter(Mandatory = $true)] [int]$WindowsRelease, [Parameter(Mandatory = $true)] [hashtable]$Headers, # Pass necessary headers [Parameter(Mandatory = $true)] [string]$UserAgent, # Pass UserAgent [Parameter()] # Made optional [System.Collections.Concurrent.ConcurrentQueue[hashtable]]$ProgressQueue = $null, # Default to null [Parameter()] [bool]$CompressToWim = $false # New parameter for compression # REMOVED: UI-related parameters ) $modelName = $DriverItemData.Model $modelLink = $DriverItemData.Link $make = $DriverItemData.Make $driverRelativePath = Join-Path -Path $make -ChildPath $modelName # Relative path for the driver folder $status = "Getting download link..." # Initial local status $success = $false # Initial status update if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status "Checking..." } try { # Check if WIM file or driver folder already exist $makeDriversPath = Join-Path -Path $DriversFolder -ChildPath $Make $wimFilePath = Join-Path -Path $makeDriversPath -ChildPath "$($modelName).wim" if (Test-Path -Path $wimFilePath -PathType Leaf) { $status = "Already downloaded (WIM)" WriteLog "Driver WIM for '$modelName' already exists at '$wimFilePath'." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status $status } $wimRelativePath = Join-Path -Path $make -ChildPath "$($modelName).wim" return [PSCustomObject]@{ Model = $modelName; Status = $status; Success = $true; DriverPath = $wimRelativePath } } $modelPath = Join-Path -Path $makeDriversPath -ChildPath $modelName if (Test-Path -Path $modelPath -PathType Container) { $folderSize = (Get-ChildItem -Path $modelPath -Recurse | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum if ($folderSize -gt 1MB) { $status = "Already downloaded" WriteLog "Drivers for '$modelName' already exist in '$modelPath'." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status $status } return [PSCustomObject]@{ Model = $modelName; Status = $status; Success = $true; DriverPath = $driverRelativePath } } else { WriteLog "Driver folder '$modelPath' for '$modelName' exists but is empty or very small. Re-downloading." } } ### GET THE DOWNLOAD LINK $status = "Getting download link..." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status $status } WriteLog "Getting download page content for $modelName from $modelLink" $OriginalVerbosePreference = $VerbosePreference $VerbosePreference = 'SilentlyContinue' # Use passed-in UserAgent and Headers $downloadPageContent = Invoke-WebRequest -Uri $modelLink -UseBasicParsing -Headers $Headers -UserAgent $UserAgent $VerbosePreference = $OriginalVerbosePreference WriteLog "Complete" $status = "Parsing download page..." if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelName -Status $status } WriteLog "Parsing download page for file" $scriptPattern = '