mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
d6689888b2
Removes the logic that adds a `Success` property to the returned object when an existing driver package is found. This property is handled by the calling function, making this assignment unnecessary and simplifying the driver-saving task functions.
451 lines
25 KiB
PowerShell
451 lines
25 KiB
PowerShell
# Function to get the list of Lenovo models using the PSREF API
|
|
function Get-LenovoDriversModelList {
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$ModelSearchTerm, # User input for model/machine type
|
|
[Parameter(Mandatory = $true)]
|
|
[hashtable]$Headers,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$UserAgent
|
|
)
|
|
|
|
WriteLog "Querying Lenovo PSREF API for model/machine type: $ModelSearchTerm"
|
|
$url = "https://psref.lenovo.com/api/search/DefinitionFilterAndSearch/Suggest?kw=$([uri]::EscapeDataString($ModelSearchTerm))"
|
|
$models = [System.Collections.Generic.List[PSCustomObject]]::new()
|
|
|
|
try {
|
|
$OriginalVerbosePreference = $VerbosePreference
|
|
$VerbosePreference = 'SilentlyContinue'
|
|
$response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers $Headers -UserAgent $UserAgent -ErrorAction Stop
|
|
$VerbosePreference = $OriginalVerbosePreference
|
|
WriteLog "PSREF API query complete."
|
|
|
|
$jsonResponse = $response.Content | ConvertFrom-Json
|
|
|
|
if ($null -ne $jsonResponse.data -and $jsonResponse.data.Count -gt 0) {
|
|
foreach ($item in $jsonResponse.data) {
|
|
$productName = $item.ProductName
|
|
$machineTypes = $item.MachineType -split " / " # Split if multiple machine types are listed
|
|
|
|
foreach ($machineTypeRaw in $machineTypes) {
|
|
$machineType = $machineTypeRaw.Trim()
|
|
# Only add if machine type is not empty
|
|
if (-not [string]::IsNullOrWhiteSpace($machineType)) {
|
|
# Create the combined display string
|
|
$displayModel = "$productName ($machineType)"
|
|
# Add each combination as a separate entry
|
|
$models.Add([PSCustomObject]@{
|
|
Make = 'Lenovo'
|
|
Model = $displayModel
|
|
ProductName = $productName
|
|
MachineType = $machineType
|
|
})
|
|
}
|
|
else {
|
|
WriteLog "Skipping entry for product '$productName' due to missing machine type."
|
|
}
|
|
}
|
|
}
|
|
WriteLog "Found $($models.Count) potential model/machine type combinations for '$ModelSearchTerm'."
|
|
}
|
|
else {
|
|
WriteLog "No models found matching '$ModelSearchTerm' in Lenovo PSREF."
|
|
}
|
|
}
|
|
catch {
|
|
WriteLog "Error querying Lenovo PSREF API: $($_.Exception.Message)"
|
|
# Return empty list on error
|
|
}
|
|
return $models
|
|
}
|
|
# Function to download and extract drivers for a specific Lenovo model (Background Task)
|
|
function Save-LenovoDriversTask {
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[PSCustomObject]$DriverItemData, # Contains Model (ProductName) and MachineType
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$DriversFolder,
|
|
[Parameter(Mandatory = $true)]
|
|
[int]$WindowsRelease,
|
|
[Parameter(Mandatory = $true)]
|
|
[hashtable]$Headers,
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$UserAgent,
|
|
[Parameter()] # Made optional
|
|
[System.Collections.Concurrent.ConcurrentQueue[hashtable]]$ProgressQueue = $null,
|
|
[Parameter()]
|
|
[bool]$CompressToWim = $false
|
|
)
|
|
|
|
# The Model property from the UI already contains the combined "ProductName (MachineType)" string
|
|
$identifier = $DriverItemData.Model
|
|
$machineType = $DriverItemData.MachineType
|
|
$make = "Lenovo"
|
|
$sanitizedIdentifier = $identifier -replace '[\\/:"*?<>|]', '_'
|
|
$status = "Starting..."
|
|
$success = $false
|
|
|
|
# Define paths
|
|
$makeDriversPath = Join-Path -Path $DriversFolder -ChildPath $Make
|
|
# Use the identifier (which contains the model name and machine type) and sanitize it for the path
|
|
$modelPath = Join-Path -Path $makeDriversPath -ChildPath $sanitizedIdentifier
|
|
$driverRelativePath = Join-Path -Path $make -ChildPath $sanitizedIdentifier # Relative path for the driver folder
|
|
$tempDownloadPath = Join-Path -Path $makeDriversPath -ChildPath "_TEMP_$($machineType)_$($PID)" # Temp folder for catalog/package XMLs
|
|
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status "Checking..." }
|
|
|
|
try {
|
|
# Check for existing drivers
|
|
$existingDriver = Test-ExistingDriver -Make $make -Model $sanitizedIdentifier -DriversFolder $DriversFolder -Identifier $identifier -ProgressQueue $ProgressQueue
|
|
if ($null -ne $existingDriver) {
|
|
# The return object from Test-ExistingDriver uses 'Model' as the identifier key.
|
|
# We need to return 'Identifier' for Lenovo's logic.
|
|
$existingDriver | Add-Member -MemberType NoteProperty -Name 'Identifier' -Value $identifier -Force
|
|
$existingDriver.PSObject.Properties.Remove('Model')
|
|
|
|
# Special handling for existing folders that need compression
|
|
if ($CompressToWim -and $existingDriver.Status -eq 'Already downloaded') {
|
|
$wimFilePath = Join-Path -Path $makeDriversPath -ChildPath "$($sanitizedIdentifier).wim"
|
|
$sourceFolderPath = Join-Path -Path $makeDriversPath -ChildPath $sanitizedIdentifier
|
|
WriteLog "Attempting compression of existing folder '$sourceFolderPath' to '$wimFilePath'."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status "Compressing existing..." }
|
|
try {
|
|
Compress-DriverFolderToWim -SourceFolderPath $sourceFolderPath -DestinationWimPath $wimFilePath -WimName $identifier -WimDescription "Drivers for $identifier" -ErrorAction Stop
|
|
$existingDriver.Status = "Already downloaded & Compressed"
|
|
$existingDriver.DriverPath = Join-Path -Path $make -ChildPath "$($sanitizedIdentifier).wim"
|
|
$existingDriver.Success = $true
|
|
WriteLog "Successfully compressed existing drivers for $identifier to $wimFilePath."
|
|
}
|
|
catch {
|
|
WriteLog "Error compressing existing drivers for $($identifier): $($_.Exception.Message)"
|
|
$existingDriver.Status = "Already downloaded (Compression failed)"
|
|
$existingDriver.Success = $false
|
|
}
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $existingDriver.Status }
|
|
}
|
|
|
|
return $existingDriver
|
|
}
|
|
|
|
# Ensure base directories exist
|
|
if (-not (Test-Path -Path $makeDriversPath)) { New-Item -Path $makeDriversPath -ItemType Directory -Force | Out-Null }
|
|
if (-not (Test-Path -Path $modelPath)) { New-Item -Path $modelPath -ItemType Directory -Force | Out-Null }
|
|
if (-not (Test-Path -Path $tempDownloadPath)) { New-Item -Path $tempDownloadPath -ItemType Directory -Force | Out-Null }
|
|
|
|
# 2. Construct and Download Catalog URL
|
|
$modelRelease = $machineType + "_Win" + $WindowsRelease
|
|
$catalogUrl = "https://download.lenovo.com/catalog/$modelRelease.xml"
|
|
$lenovoCatalogXML = Join-Path -Path $tempDownloadPath -ChildPath "$modelRelease.xml"
|
|
|
|
$status = "Downloading Catalog..."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
WriteLog "Downloading Lenovo Driver catalog for '$identifier' from $catalogUrl"
|
|
|
|
# Check URL accessibility first
|
|
try {
|
|
$request = [System.Net.WebRequest]::Create($catalogUrl); $request.Method = 'HEAD'; $response = $request.GetResponse(); $response.Close()
|
|
}
|
|
catch { throw "Lenovo Driver catalog URL is not accessible: $catalogUrl. Error: $($_.Exception.Message)" }
|
|
|
|
Start-BitsTransferWithRetry -Source $catalogUrl -Destination $lenovoCatalogXML
|
|
WriteLog "Catalog download Complete: $lenovoCatalogXML"
|
|
|
|
# 3. Parse Catalog and Process Packages
|
|
$status = "Parsing Catalog..."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
[xml]$xmlContent = Get-Content -Path $lenovoCatalogXML -Encoding UTF8
|
|
|
|
$packages = @($xmlContent.packages.package) # Ensure it's an array
|
|
$totalPackages = $packages.Count
|
|
$processedPackages = 0
|
|
WriteLog "Found $totalPackages packages in catalog for '$identifier'."
|
|
|
|
foreach ($package in $packages) {
|
|
$processedPackages++
|
|
$category = $package.category
|
|
$packageUrl = $package.location # URL to the package's *XML* file
|
|
|
|
# Skip BIOS/Firmware based on category
|
|
if ($category -like 'BIOS*' -or $category -like 'Firmware*') {
|
|
WriteLog "($processedPackages/$totalPackages) Skipping BIOS/Firmware package: $category"
|
|
continue
|
|
}
|
|
|
|
# Sanitize category for path
|
|
$categoryClean = $category -replace '[\\/:"*?<>|]', '_'
|
|
if ($categoryClean -eq 'Motherboard Devices Backplanes core chipset onboard video PCIe switches') {
|
|
$categoryClean = 'Motherboard Devices' # Shorten long category name
|
|
}
|
|
|
|
$packageName = [System.IO.Path]::GetFileName($packageUrl)
|
|
$packageXMLPath = Join-Path -Path $tempDownloadPath -ChildPath $packageName
|
|
$baseURL = $packageUrl -replace [regex]::Escape($packageName), "" # Base URL for the driver file
|
|
|
|
$status = "($processedPackages/$totalPackages) Getting package info..."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
|
|
# Download the package XML
|
|
WriteLog "($processedPackages/$totalPackages) Downloading package XML: $packageUrl"
|
|
try {
|
|
Start-BitsTransferWithRetry -Source $packageUrl -Destination $packageXMLPath
|
|
}
|
|
catch {
|
|
WriteLog "($processedPackages/$totalPackages) Failed to download package XML '$packageUrl'. Skipping. Error: $($_.Exception.Message)"
|
|
continue # Skip this package
|
|
}
|
|
|
|
# Load and parse the package XML
|
|
[xml]$packageXmlContent = Get-Content -Path $packageXMLPath -Encoding UTF8
|
|
$packageType = $packageXmlContent.Package.PackageType.type
|
|
$packageTitleRaw = $packageXmlContent.Package.title.InnerText
|
|
|
|
# Filter out non-driver packages (Type 2 = Driver)
|
|
if ($packageType -ne 2) {
|
|
WriteLog "($processedPackages/$totalPackages) Skipping package '$packageTitleRaw' (Type: $packageType) - Not a driver."
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue # Clean up package XML
|
|
continue
|
|
}
|
|
|
|
# Sanitize title for folder name
|
|
$packageTitle = $packageTitleRaw -replace '[\\/:"*?<>|]', '_' -replace ' - .*', ''
|
|
|
|
# Extract driver file name and extract command
|
|
$driverFileName = $null
|
|
$extractCommand = $null
|
|
try {
|
|
$driverFileName = $packageXmlContent.Package.Files.Installer.File.Name
|
|
$extractCommand = $packageXmlContent.Package.ExtractCommand
|
|
}
|
|
catch {
|
|
WriteLog "($processedPackages/$totalPackages) Error parsing package XML '$packageXMLPath' for file name/command. Skipping. Error: $($_.Exception.Message)"
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
|
continue
|
|
}
|
|
|
|
|
|
# Skip if essential info is missing
|
|
if ([string]::IsNullOrWhiteSpace($driverFileName) -or [string]::IsNullOrWhiteSpace($extractCommand)) {
|
|
WriteLog "($processedPackages/$totalPackages) Skipping package '$packageTitleRaw' - Missing driver file name or extract command in XML."
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
|
continue
|
|
}
|
|
|
|
# Construct paths
|
|
$driverUrl = $baseURL + $driverFileName
|
|
$categoryPath = Join-Path -Path $modelPath -ChildPath $categoryClean
|
|
$downloadFolder = Join-Path -Path $categoryPath -ChildPath $packageTitle # Final destination subfolder
|
|
$driverFilePath = Join-Path -Path $downloadFolder -ChildPath $driverFileName
|
|
$extractFolder = Join-Path -Path $downloadFolder -ChildPath ($driverFileName -replace '\.exe$', '') # Extract to subfolder named after exe
|
|
# Check if already extracted
|
|
if (Test-Path -Path $extractFolder -PathType Container) {
|
|
$extractSize = (Get-ChildItem -Path $extractFolder -Recurse | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum
|
|
if ($extractSize -gt 1KB) {
|
|
WriteLog "($processedPackages/$totalPackages) Driver '$packageTitleRaw' already extracted to '$extractFolder'. Skipping."
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue # Clean up package XML
|
|
continue
|
|
}
|
|
}
|
|
|
|
# Ensure download folder exists
|
|
if (-not (Test-Path -Path $downloadFolder)) {
|
|
New-Item -Path $downloadFolder -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
# Download the driver .exe
|
|
$status = "($processedPackages/$totalPackages) Downloading $packageTitle..."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
WriteLog "($processedPackages/$totalPackages) Downloading driver: $driverUrl to $driverFilePath"
|
|
try {
|
|
Start-BitsTransferWithRetry -Source $driverUrl -Destination $driverFilePath
|
|
WriteLog "($processedPackages/$totalPackages) Driver downloaded: $driverFileName"
|
|
}
|
|
catch {
|
|
WriteLog "($processedPackages/$totalPackages) Failed to download driver '$driverUrl'. Skipping. Error: $($_.Exception.Message)"
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue # Clean up package XML
|
|
continue # Skip this driver
|
|
}
|
|
|
|
# --- Extraction Logic ---
|
|
$status = "($processedPackages/$totalPackages) Extracting $packageTitle..."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
|
|
# Always use a temporary extraction path to avoid long path issues
|
|
$originalExtractFolder = $extractFolder # Store the originally intended final path
|
|
$extractionSucceeded = $false
|
|
$tempExtractBase = $null # Initialize
|
|
|
|
# Create randomized number for use with temp folder name
|
|
$randomNumber = Get-Random -Minimum 1000 -Maximum 9999
|
|
$tempExtractBase = Join-Path $env:TEMP "LenovoDriverExtract_$randomNumber"
|
|
$extractFolder = Join-Path $tempExtractBase ($driverFileName -replace '\.exe$', '') # Actual temp extraction folder
|
|
WriteLog "($processedPackages/$totalPackages) Using temporary extraction path: $extractFolder"
|
|
|
|
# Ensure the base temp directory exists
|
|
if (-not (Test-Path -Path $tempExtractBase)) {
|
|
New-Item -Path $tempExtractBase -ItemType Directory -Force | Out-Null
|
|
}
|
|
# Ensure the target temporary extraction folder exists
|
|
if (-not (Test-Path -Path $extractFolder)) {
|
|
New-Item -Path $extractFolder -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
# Modify the extract command to point to the temporary folder
|
|
$modifiedExtractCommand = $extractCommand -replace '%PACKAGEPATH%', "`"$extractFolder`""
|
|
WriteLog "($processedPackages/$totalPackages) Extracting driver: $driverFilePath using command: $modifiedExtractCommand"
|
|
|
|
try {
|
|
Invoke-Process -FilePath $driverFilePath -ArgumentList $modifiedExtractCommand -Wait $true | Out-Null
|
|
WriteLog "($processedPackages/$totalPackages) Driver extracted to temporary path: $extractFolder"
|
|
$extractionSucceeded = $true
|
|
}
|
|
catch {
|
|
WriteLog "($processedPackages/$totalPackages) Failed to extract driver '$driverFilePath' to temporary path. Skipping. Error: $($_.Exception.Message)"
|
|
# Don't delete the downloaded exe yet if extraction fails
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue # Clean up package XML
|
|
# Clean up temp folder if extraction failed
|
|
if ($tempExtractBase -and (Test-Path -Path $tempExtractBase)) {
|
|
Remove-Item -Path $tempExtractBase -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
continue # Skip further processing for this driver
|
|
}
|
|
|
|
# --- Post-Extraction Handling (Move from Temp to Final Destination) ---
|
|
if ($extractionSucceeded) {
|
|
WriteLog "($processedPackages/$totalPackages) Performing post-extraction move from temp to final destination..."
|
|
try {
|
|
# Ensure the *original* final destination folder exists and is empty
|
|
if (Test-Path -Path $originalExtractFolder) {
|
|
WriteLog "($processedPackages/$totalPackages) Clearing existing final destination folder: $originalExtractFolder"
|
|
Get-ChildItem -Path $originalExtractFolder -Recurse | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
else {
|
|
WriteLog "($processedPackages/$totalPackages) Creating final destination folder: $originalExtractFolder"
|
|
New-Item -Path $originalExtractFolder -ItemType Directory -Force | Out-Null
|
|
}
|
|
|
|
# Get all items (files and folders) directly inside the temp extraction folder
|
|
$extractedItems = Get-ChildItem -Path $extractFolder -ErrorAction Stop
|
|
|
|
foreach ($item in $extractedItems) {
|
|
$itemName = $item.Name
|
|
$finalDestinationPath = $null
|
|
|
|
# Check if it's a directory containing 'Liteon'
|
|
if ($item.PSIsContainer -and $itemName -like '*Liteon*') {
|
|
# Rename Liteon folders with a random number suffix
|
|
$randomNumber = Get-Random -Minimum 1000 -Maximum 9999
|
|
$finalFolderName = "Liteon_$randomNumber"
|
|
$finalDestinationPath = Join-Path -Path $originalExtractFolder -ChildPath $finalFolderName
|
|
WriteLog "($processedPackages/$totalPackages) Moving Liteon folder '$itemName' to '$finalDestinationPath'"
|
|
}
|
|
else {
|
|
# For other files/folders, move them directly
|
|
$finalDestinationPath = Join-Path -Path $originalExtractFolder -ChildPath $itemName
|
|
WriteLog "($processedPackages/$totalPackages) Moving item '$itemName' to '$finalDestinationPath'"
|
|
}
|
|
|
|
# Perform the move
|
|
try {
|
|
Move-Item -Path $item.FullName -Destination $finalDestinationPath -Force -ErrorAction Stop
|
|
}
|
|
catch {
|
|
WriteLog "($processedPackages/$totalPackages) Failed to move item '$($item.FullName)' to '$finalDestinationPath'. Error: $($_.Exception.Message)"
|
|
# Decide if this should stop the whole process or just skip this item
|
|
# For now, we'll log and continue, but mark overall success as false
|
|
$extractionSucceeded = $false
|
|
}
|
|
} # End foreach ($item in $extractedItems)
|
|
|
|
if ($extractionSucceeded) {
|
|
WriteLog "($processedPackages/$totalPackages) All driver contents moved successfully from temp to final destination."
|
|
}
|
|
else {
|
|
WriteLog "($processedPackages/$totalPackages) Some driver contents failed to move. Check logs."
|
|
}
|
|
|
|
}
|
|
catch {
|
|
WriteLog "($processedPackages/$totalPackages) Error during post-extraction move: $($_.Exception.Message). Files might remain in temp."
|
|
$extractionSucceeded = $false # Mark as failed for cleanup logic below
|
|
}
|
|
finally {
|
|
# Clean up the base temporary directory regardless of move success/failure
|
|
if ($tempExtractBase -and (Test-Path -Path $tempExtractBase)) {
|
|
WriteLog "($processedPackages/$totalPackages) Cleaning up temporary extraction base: $tempExtractBase"
|
|
Remove-Item -Path $tempExtractBase -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
}
|
|
}
|
|
|
|
# --- Final Cleanup ---
|
|
# Delete the downloaded .exe only if extraction AND move were successful
|
|
if ($extractionSucceeded) {
|
|
WriteLog "($processedPackages/$totalPackages) Deleting driver installation file: $driverFilePath"
|
|
Remove-Item -Path $driverFilePath -Force -ErrorAction SilentlyContinue
|
|
}
|
|
else {
|
|
WriteLog "($processedPackages/$totalPackages) Keeping driver installation file due to extraction/move failure: $driverFilePath"
|
|
}
|
|
# Always delete the package XML
|
|
WriteLog "($processedPackages/$totalPackages) Deleting package XML file: $packageXMLPath"
|
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
|
|
|
} # End foreach package
|
|
|
|
# --- Compress to WIM if requested (after all drivers processed) ---
|
|
if ($CompressToWim) {
|
|
$status = "Compressing..."
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
$wimFileName = "$($sanitizedIdentifier).wim" # Use sanitized identifier for filename
|
|
$destinationWimPath = Join-Path -Path $makeDriversPath -ChildPath $wimFileName
|
|
$driverRelativePath = Join-Path -Path $make -ChildPath $wimFileName # Update relative path to the WIM file
|
|
WriteLog "Compressing '$modelPath' to '$destinationWimPath'..."
|
|
try {
|
|
$compressResult = Compress-DriverFolderToWim -SourceFolderPath $modelPath -DestinationWimPath $destinationWimPath -WimName $identifier -WimDescription $identifier -ErrorAction Stop
|
|
if ($compressResult) {
|
|
WriteLog "Compression successful for '$identifier'."
|
|
$status = "Completed & Compressed"
|
|
}
|
|
else {
|
|
WriteLog "Compression failed for '$identifier'. Check verbose/error output from Compress-DriverFolderToWim."
|
|
$status = "Completed (Compression Failed)"
|
|
}
|
|
}
|
|
catch {
|
|
WriteLog "Error during compression for '$identifier': $($_.Exception.Message)"
|
|
$status = "Completed (Compression Error)"
|
|
}
|
|
}
|
|
else {
|
|
$status = "Completed"
|
|
}
|
|
# --- End Compression ---
|
|
|
|
$success = $true # Mark success as download/extract was okay
|
|
|
|
}
|
|
catch {
|
|
$status = "Error: $($_.Exception.Message.Split('.')[0])" # Shorten error message
|
|
WriteLog "Error saving Lenovo drivers for '$identifier': $($_.Exception.ToString())" # Log full exception string
|
|
$success = $false
|
|
# Enqueue the error status before returning
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
# Ensure return object is created even on error
|
|
return [PSCustomObject]@{ Identifier = $identifier; Status = $status; Success = $success; DriverPath = $null }
|
|
}
|
|
finally {
|
|
# Clean up the main catalog XML and temp folder
|
|
WriteLog "Cleaning up temporary download folder: $tempDownloadPath"
|
|
Remove-Item -Path $tempDownloadPath -Recurse -Force -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
# Enqueue the final status (success or error) before returning
|
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
|
|
|
# Return the final status
|
|
return [PSCustomObject]@{ Identifier = $identifier; Status = $status; Success = $success; DriverPath = $driverRelativePath }
|
|
}
|
|
|
|
Export-ModuleMember -Function * |