mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Enhances driver download error handling and logging across Dell and Lenovo driver tasks.
- Implements detailed failure tracking for driver downloads, capturing model names and statuses for failed attempts. - Updates logging to provide clearer messages for both successful and failed downloads, improving traceability. - Modifies the user interface to display comprehensive error messages when downloads fail, including a summary of failed models. - Ensures that all exceptions during download and extraction processes are logged and thrown, preventing silent failures.
This commit is contained in:
@@ -4948,46 +4948,78 @@ if ($driversJsonPath -and (Test-Path $driversJsonPath) -and ($InstallDrivers -or
|
|||||||
-ListViewControl $null `
|
-ListViewControl $null `
|
||||||
-MainThreadLogPath $LogFile
|
-MainThreadLogPath $LogFile
|
||||||
|
|
||||||
# After processing, update the driver mapping file
|
# After processing, update the driver mapping file and detect failures
|
||||||
$successfullyDownloaded = [System.Collections.Generic.List[PSCustomObject]]::new()
|
$successfullyDownloaded = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||||
|
$failedDownloads = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||||
|
|
||||||
if ($null -ne $parallelResults) {
|
if ($null -ne $parallelResults) {
|
||||||
# Create a lookup table from the original items to get the 'Make'
|
# Create a lookup table from the original items to get the 'Make'
|
||||||
$makeLookup = @{}
|
$makeLookup = @{}
|
||||||
$driversToProcess | ForEach-Object { $makeLookup[$_.Model] = $_.Make }
|
$driversToProcess | ForEach-Object { $makeLookup[$_.Model] = $_.Make }
|
||||||
|
|
||||||
# Filter for objects that could be results, avoiding stray log strings
|
foreach ($result in $parallelResults) {
|
||||||
foreach ($result in ($parallelResults | Where-Object { $_ -is [hashtable] })) {
|
|
||||||
if ($null -eq $result) { continue }
|
if ($null -eq $result) { continue }
|
||||||
|
|
||||||
# The result from Invoke-ParallelProcessing is a hashtable.
|
$lookupModelName = $null
|
||||||
# Access properties using their keys.
|
$resultStatus = $null
|
||||||
$modelName = $result['Identifier']
|
$resultDriverPath = $null
|
||||||
$resultCode = $result['ResultCode']
|
$resultSuccess = $false
|
||||||
$driverPath = $result['DriverPath']
|
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($modelName)) {
|
if ($result -is [hashtable]) {
|
||||||
WriteLog "Could not determine model name from result object: $($result | ConvertTo-Json -Compress -Depth 3)"
|
$lookupModelName = $result['Identifier']
|
||||||
continue
|
$resultStatus = $result['Status']
|
||||||
|
if ($result.ContainsKey('DriverPath')) { $resultDriverPath = $result['DriverPath'] }
|
||||||
|
if ($result.ContainsKey('Success')) {
|
||||||
|
$resultSuccess = [bool]$result['Success']
|
||||||
|
}
|
||||||
|
elseif ($result.ContainsKey('ResultCode')) {
|
||||||
|
$resultSuccess = ($result['ResultCode'] -eq 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif ($result -is [pscustomobject]) {
|
||||||
|
if ($result.PSObject.Properties.Name -contains 'Identifier' -and -not [string]::IsNullOrWhiteSpace($result.Identifier)) {
|
||||||
|
$lookupModelName = $result.Identifier
|
||||||
|
}
|
||||||
|
elseif ($result.PSObject.Properties.Name -contains 'Model' -and -not [string]::IsNullOrWhiteSpace($result.Model)) {
|
||||||
|
$lookupModelName = $result.Model
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result.PSObject.Properties.Name -contains 'Status') { $resultStatus = $result.Status }
|
||||||
|
if ($result.PSObject.Properties.Name -contains 'DriverPath') { $resultDriverPath = $result.DriverPath }
|
||||||
|
if ($result.PSObject.Properties.Name -contains 'Success') {
|
||||||
|
$resultSuccess = [bool]$result.Success
|
||||||
|
}
|
||||||
|
elseif ($result.PSObject.Properties.Name -contains 'ResultCode') {
|
||||||
|
$resultSuccess = ($result.ResultCode -eq 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($resultCode -eq 0 -and -not [string]::IsNullOrWhiteSpace($driverPath)) {
|
if ($resultSuccess -and -not [string]::IsNullOrWhiteSpace($resultDriverPath)) {
|
||||||
# The task was successful and returned a driver path.
|
$modelKey = if (-not [string]::IsNullOrWhiteSpace($lookupModelName)) { $lookupModelName } else { 'Unknown model' }
|
||||||
$makeJson = $makeLookup[$modelName]
|
$makeJson = $null
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($lookupModelName) -and $makeLookup.ContainsKey($lookupModelName)) {
|
||||||
|
$makeJson = $makeLookup[$lookupModelName]
|
||||||
|
}
|
||||||
|
|
||||||
if ($makeJson) {
|
if ($makeJson) {
|
||||||
$successfullyDownloaded.Add([PSCustomObject]@{
|
$successfullyDownloaded.Add([PSCustomObject]@{
|
||||||
Make = $makeJson
|
Make = $makeJson
|
||||||
Model = $modelName
|
Model = $modelKey
|
||||||
DriverPath = $driverPath
|
DriverPath = $resultDriverPath
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WriteLog "Warning: Could not find 'Make' for successful download of model '$modelName'. Skipping from DriverMapping.json."
|
WriteLog "Warning: Could not find 'Make' for successful download of model '$modelKey'. Skipping from DriverMapping.json."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$logMessage = "Driver download failed or did not return a path for model '$modelName'. Status: $($result['Status'])"
|
$failureModel = if (-not [string]::IsNullOrWhiteSpace($lookupModelName)) { $lookupModelName } else { 'Unknown model' }
|
||||||
WriteLog $logMessage
|
$failureStatus = if (-not [string]::IsNullOrWhiteSpace($resultStatus)) { $resultStatus } else { 'Driver download failed without a status message. Check the log for details.' }
|
||||||
Write-Warning $logMessage
|
$failedDownloads.Add([PSCustomObject]@{
|
||||||
|
Model = $failureModel
|
||||||
|
Status = $failureStatus
|
||||||
|
})
|
||||||
|
WriteLog "Driver download failed for '$failureModel'. Status: $failureStatus"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4995,52 +5027,13 @@ if ($driversJsonPath -and (Test-Path $driversJsonPath) -and ($InstallDrivers -or
|
|||||||
WriteLog "Invoke-ParallelProcessing returned null or no results."
|
WriteLog "Invoke-ParallelProcessing returned null or no results."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Update the driver mapping JSON if there are any successful downloads
|
if ($failedDownloads.Count -gt 0) {
|
||||||
if ($successfullyDownloaded.Count -gt 0) {
|
$firstFailure = $failedDownloads[0]
|
||||||
try {
|
$errorMessage = "Driver download failed for model '$($firstFailure.Model)': $($firstFailure.Status)"
|
||||||
WriteLog "Updating DriverMapping.json with $($successfullyDownloaded.Count) successfully downloaded drivers."
|
WriteLog $errorMessage
|
||||||
Update-DriverMappingJson -DownloadedDrivers $successfullyDownloaded -DriversFolder $DriversFolder
|
throw $errorMessage
|
||||||
}
|
|
||||||
catch {
|
|
||||||
WriteLog "Warning: Failed to update DriverMapping.json: $($_.Exception.Message)"
|
|
||||||
# This is not a fatal error for the build process itself, so just show a warning.
|
|
||||||
Write-Warning "The driver download process completed, but failed to update the DriverMapping.json file. Please check the log for details."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
WriteLog "Finished processing drivers from $driversJsonPath."
|
|
||||||
|
|
||||||
# After processing, update the driver mapping file
|
|
||||||
$successfullyDownloaded = [System.Collections.Generic.List[PSCustomObject]]::new()
|
|
||||||
if ($null -ne $parallelResults) {
|
|
||||||
# Create a lookup table from the original items to get the 'Make'
|
|
||||||
$makeLookup = @{}
|
|
||||||
$driversToProcess | ForEach-Object { $makeLookup[$_.Model] = $_.Make }
|
|
||||||
|
|
||||||
foreach ($result in $parallelResults) {
|
|
||||||
if ($null -ne $result) {
|
|
||||||
# Collect successful results for driver mapping
|
|
||||||
if ($result.PSObject.Properties['Success'] -and $result.Success -and $result.PSObject.Properties['DriverPath'] -and -not [string]::IsNullOrWhiteSpace($result.DriverPath)) {
|
|
||||||
$modelName = if ($result.PSObject.Properties.Name -contains 'Identifier') { $result.Identifier } else { $result.Model }
|
|
||||||
|
|
||||||
# Find the 'Make' from the original list
|
|
||||||
$makeJson = $makeLookup[$modelName]
|
|
||||||
|
|
||||||
if ($makeJson) {
|
|
||||||
$successfullyDownloaded.Add([PSCustomObject]@{
|
|
||||||
Make = $makeJson
|
|
||||||
Model = $modelName
|
|
||||||
DriverPath = $result.DriverPath
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
WriteLog "Warning: Could not find 'Make' for successful download of model '$modelName'. Skipping from DriverMapping.json."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update the driver mapping JSON if there are any successful downloads
|
|
||||||
if ($successfullyDownloaded.Count -gt 0) {
|
if ($successfullyDownloaded.Count -gt 0) {
|
||||||
try {
|
try {
|
||||||
WriteLog "Updating DriverMapping.json with $($successfullyDownloaded.Count) successfully downloaded drivers."
|
WriteLog "Updating DriverMapping.json with $($successfullyDownloaded.Count) successfully downloaded drivers."
|
||||||
@@ -5052,6 +5045,8 @@ if ($driversJsonPath -and (Test-Path $driversJsonPath) -and ($InstallDrivers -or
|
|||||||
Write-Warning "The driver download process completed, but failed to update the DriverMapping.json file. Please check the log for details."
|
Write-Warning "The driver download process completed, but failed to update the DriverMapping.json file. Please check the log for details."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteLog "Finished processing drivers from $driversJsonPath."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# Existing single-model driver download logic
|
# Existing single-model driver download logic
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ function Get-DellDriversModelList {
|
|||||||
$final = [System.Collections.Generic.List[pscustomobject]]::new()
|
$final = [System.Collections.Generic.List[pscustomobject]]::new()
|
||||||
foreach ($m in $dellModels) {
|
foreach ($m in $dellModels) {
|
||||||
$final.Add([pscustomobject]@{
|
$final.Add([pscustomobject]@{
|
||||||
Make = $Make
|
Make = $Make
|
||||||
Model = $m.ModelDisplay
|
Model = $m.ModelDisplay
|
||||||
Brand = $m.Brand
|
Brand = $m.Brand
|
||||||
ModelNumber = $m.ModelNumber
|
ModelNumber = $m.ModelNumber
|
||||||
SystemId = $m.SystemId
|
SystemId = $m.SystemId
|
||||||
CabRelativePath = $m.CabRelativePath
|
CabRelativePath = $m.CabRelativePath
|
||||||
CabUrl = $m.CabUrl
|
CabUrl = $m.CabUrl
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return $final
|
return $final
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ function Get-DellDriversModelList {
|
|||||||
$settings = New-Object System.Xml.XmlReaderSettings
|
$settings = New-Object System.Xml.XmlReaderSettings
|
||||||
$settings.IgnoreWhitespace = $true
|
$settings.IgnoreWhitespace = $true
|
||||||
$settings.IgnoreComments = $true
|
$settings.IgnoreComments = $true
|
||||||
$reader = [System.Xml.XmlReader]::Create($dellCatalogXML,$settings)
|
$reader = [System.Xml.XmlReader]::Create($dellCatalogXML, $settings)
|
||||||
$inDriver = $false
|
$inDriver = $false
|
||||||
$inModel = $false
|
$inModel = $false
|
||||||
$depthModel = -1
|
$depthModel = -1
|
||||||
@@ -144,7 +144,7 @@ function Save-DellDriversTask {
|
|||||||
$target = (Resolve-Path $Path -ErrorAction SilentlyContinue)?.ProviderPath
|
$target = (Resolve-Path $Path -ErrorAction SilentlyContinue)?.ProviderPath
|
||||||
if ($null -eq $target) { return }
|
if ($null -eq $target) { return }
|
||||||
if ($target -eq $dellRoot) { return }
|
if ($target -eq $dellRoot) { return }
|
||||||
if (-not ($target.StartsWith($dellRoot,[System.StringComparison]::OrdinalIgnoreCase))) { return }
|
if (-not ($target.StartsWith($dellRoot, [System.StringComparison]::OrdinalIgnoreCase))) { return }
|
||||||
Remove-Item -Path $target -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path $target -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,18 +246,18 @@ function Save-DellDriversTask {
|
|||||||
$driverPath = $component.path
|
$driverPath = $component.path
|
||||||
$downloadUrl = $baseLocation + $driverPath
|
$downloadUrl = $baseLocation + $driverPath
|
||||||
$fileName = [IO.Path]::GetFileName($driverPath)
|
$fileName = [IO.Path]::GetFileName($driverPath)
|
||||||
$name = $component.Name.Display.'#cdata-section' -replace '[\\\/\:\*\?\"\<\>\| ]','_' -replace '[\,]','-'
|
$name = $component.Name.Display.'#cdata-section' -replace '[\\\/\:\*\?\"\<\>\| ]', '_' -replace '[\,]', '-'
|
||||||
$category = $component.Category.Display.'#cdata-section' -replace '[\\\/\:\*\?\"\<\>\| ]','_'
|
$category = $component.Category.Display.'#cdata-section' -replace '[\\\/\:\*\?\"\<\>\| ]', '_'
|
||||||
$version = [version]$component.vendorVersion
|
$version = [version]$component.vendorVersion
|
||||||
$namePrefix = ($name -split '-')[0]
|
$namePrefix = ($name -split '-')[0]
|
||||||
if (-not $latestDrivers[$category]) { $latestDrivers[$category] = @{} }
|
if (-not $latestDrivers[$category]) { $latestDrivers[$category] = @{} }
|
||||||
if (-not $latestDrivers[$category][$namePrefix] -or $latestDrivers[$category][$namePrefix].Version -lt $version) {
|
if (-not $latestDrivers[$category][$namePrefix] -or $latestDrivers[$category][$namePrefix].Version -lt $version) {
|
||||||
$latestDrivers[$category][$namePrefix] = [pscustomobject]@{
|
$latestDrivers[$category][$namePrefix] = [pscustomobject]@{
|
||||||
Name = $name
|
Name = $name
|
||||||
DownloadUrl = $downloadUrl
|
DownloadUrl = $downloadUrl
|
||||||
DriverFileName = $fileName
|
DriverFileName = $fileName
|
||||||
Version = $version
|
Version = $version
|
||||||
Category = $category
|
Category = $category
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,7 +280,7 @@ function Save-DellDriversTask {
|
|||||||
$status = "$idx/$total Downloading $driverName"
|
$status = "$idx/$total Downloading $driverName"
|
||||||
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelDisplay -Status $status }
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelDisplay -Status $status }
|
||||||
|
|
||||||
$categorySafe = ($pkg.Category -replace '[\\\/\:\*\?\"\<\>\| ]','_')
|
$categorySafe = ($pkg.Category -replace '[\\\/\:\*\?\"\<\>\| ]', '_')
|
||||||
$downloadFolder = Join-Path $modelPath $categorySafe
|
$downloadFolder = Join-Path $modelPath $categorySafe
|
||||||
if (-not (Test-Path $downloadFolder)) { New-Item -Path $downloadFolder -ItemType Directory -Force | Out-Null }
|
if (-not (Test-Path $downloadFolder)) { New-Item -Path $downloadFolder -ItemType Directory -Force | Out-Null }
|
||||||
$driverFilePath = Join-Path $downloadFolder $pkg.DriverFileName
|
$driverFilePath = Join-Path $downloadFolder $pkg.DriverFileName
|
||||||
@@ -296,7 +296,11 @@ function Save-DellDriversTask {
|
|||||||
if (-not (Test-Path $driverFilePath)) {
|
if (-not (Test-Path $driverFilePath)) {
|
||||||
WriteLog "$status URL: $($pkg.DownloadUrl)"
|
WriteLog "$status URL: $($pkg.DownloadUrl)"
|
||||||
try { Start-BitsTransferWithRetry -Source $pkg.DownloadUrl -Destination $driverFilePath }
|
try { Start-BitsTransferWithRetry -Source $pkg.DownloadUrl -Destination $driverFilePath }
|
||||||
catch { WriteLog "Download failed: $($pkg.DownloadUrl) $($_.Exception.Message)"; continue }
|
catch {
|
||||||
|
$failureMessage = "Failed to download driver '$driverName' from $($pkg.DownloadUrl): $($_.Exception.Message)"
|
||||||
|
WriteLog $failureMessage
|
||||||
|
throw (New-Object System.Exception($failureMessage, $_.Exception))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$status = "$idx/$total Extracting $driverName"
|
$status = "$idx/$total Extracting $driverName"
|
||||||
@@ -326,6 +330,11 @@ function Save-DellDriversTask {
|
|||||||
if ($ok) {
|
if ($ok) {
|
||||||
Remove-Item $driverFilePath -Force -ErrorAction SilentlyContinue
|
Remove-Item $driverFilePath -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$failureMessage = "Failed to extract driver '$driverName'."
|
||||||
|
WriteLog $failureMessage
|
||||||
|
throw (New-Object System.Exception($failureMessage))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($CompressToWim) {
|
if ($CompressToWim) {
|
||||||
@@ -349,10 +358,10 @@ function Save-DellDriversTask {
|
|||||||
return [pscustomobject]@{ Model = $modelDisplay; Status = $statusFinal; Success = $true; DriverPath = $driverRelativePath }
|
return [pscustomobject]@{ Model = $modelDisplay; Status = $statusFinal; Success = $true; DriverPath = $driverRelativePath }
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$err = "Error: $($_.Exception.Message.Split('.')[0])"
|
$errorStatus = "Error: $($_.Exception.Message)"
|
||||||
WriteLog "Save-DellDriversTask error for $($modelDisplay): $($_.Exception.ToString())"
|
WriteLog "Save-DellDriversTask error for $($modelDisplay): $($_.Exception.ToString())"
|
||||||
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelDisplay -Status $err }
|
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $modelDisplay -Status $errorStatus }
|
||||||
return [pscustomobject]@{ Model = $modelDisplay; Status = $err; Success = $false; DriverPath = $null }
|
return [pscustomobject]@{ Model = $modelDisplay; Status = $errorStatus; Success = $false; DriverPath = $null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -216,8 +216,10 @@ function Save-LenovoDriversTask {
|
|||||||
Start-BitsTransferWithRetry -Source $packageUrl -Destination $packageXMLPath
|
Start-BitsTransferWithRetry -Source $packageUrl -Destination $packageXMLPath
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog "($processedPackages/$totalPackages) Failed to download package XML '$packageUrl'. Skipping. Error: $($_.Exception.Message)"
|
$failureMessage = "Failed to download Lenovo package XML '$packageUrl': $($_.Exception.Message)"
|
||||||
continue # Skip this package
|
WriteLog "($processedPackages/$totalPackages) $failureMessage"
|
||||||
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
||||||
|
throw (New-Object System.Exception($failureMessage, $_.Exception))
|
||||||
}
|
}
|
||||||
|
|
||||||
# Load and parse the package XML
|
# Load and parse the package XML
|
||||||
@@ -286,9 +288,10 @@ function Save-LenovoDriversTask {
|
|||||||
WriteLog "($processedPackages/$totalPackages) Driver downloaded: $driverFileName"
|
WriteLog "($processedPackages/$totalPackages) Driver downloaded: $driverFileName"
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog "($processedPackages/$totalPackages) Failed to download driver '$driverUrl'. Skipping. Error: $($_.Exception.Message)"
|
$failureMessage = "Failed to download driver '$packageTitle' from $($driverUrl): $($_.Exception.Message)"
|
||||||
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue # Clean up package XML
|
WriteLog "($processedPackages/$totalPackages) $failureMessage"
|
||||||
continue # Skip this driver
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
||||||
|
throw (New-Object System.Exception($failureMessage, $_.Exception))
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Extraction Logic ---
|
# --- Extraction Logic ---
|
||||||
@@ -325,14 +328,13 @@ function Save-LenovoDriversTask {
|
|||||||
$extractionSucceeded = $true
|
$extractionSucceeded = $true
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog "($processedPackages/$totalPackages) Failed to extract driver '$driverFilePath' to temporary path. Skipping. Error: $($_.Exception.Message)"
|
$failureMessage = "Failed to extract driver package '$packageTitle': $($_.Exception.Message)"
|
||||||
# Don't delete the downloaded exe yet if extraction fails
|
WriteLog "($processedPackages/$totalPackages) $failureMessage"
|
||||||
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue # Clean up package XML
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
||||||
# Clean up temp folder if extraction failed
|
|
||||||
if ($tempExtractBase -and (Test-Path -Path $tempExtractBase)) {
|
if ($tempExtractBase -and (Test-Path -Path $tempExtractBase)) {
|
||||||
Remove-Item -Path $tempExtractBase -Recurse -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path $tempExtractBase -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
continue # Skip further processing for this driver
|
throw (New-Object System.Exception($failureMessage, $_.Exception))
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- Post-Extraction Handling (Move from Temp to Final Destination) ---
|
# --- Post-Extraction Handling (Move from Temp to Final Destination) ---
|
||||||
@@ -375,10 +377,9 @@ function Save-LenovoDriversTask {
|
|||||||
Move-Item -Path $item.FullName -Destination $finalDestinationPath -Force -ErrorAction Stop
|
Move-Item -Path $item.FullName -Destination $finalDestinationPath -Force -ErrorAction Stop
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
WriteLog "($processedPackages/$totalPackages) Failed to move item '$($item.FullName)' to '$finalDestinationPath'. Error: $($_.Exception.Message)"
|
$failureMessage = "Failed to move extracted item '$($item.FullName)' to '$finalDestinationPath': $($_.Exception.Message)"
|
||||||
# Decide if this should stop the whole process or just skip this item
|
WriteLog "($processedPackages/$totalPackages) $failureMessage"
|
||||||
# For now, we'll log and continue, but mark overall success as false
|
throw (New-Object System.Exception($failureMessage, $_.Exception))
|
||||||
$extractionSucceeded = $false
|
|
||||||
}
|
}
|
||||||
} # End foreach ($item in $extractedItems)
|
} # End foreach ($item in $extractedItems)
|
||||||
|
|
||||||
@@ -415,6 +416,9 @@ function Save-LenovoDriversTask {
|
|||||||
# Always delete the package XML
|
# Always delete the package XML
|
||||||
WriteLog "($processedPackages/$totalPackages) Deleting package XML file: $packageXMLPath"
|
WriteLog "($processedPackages/$totalPackages) Deleting package XML file: $packageXMLPath"
|
||||||
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
Remove-Item -Path $packageXMLPath -Force -ErrorAction SilentlyContinue
|
||||||
|
if (-not $extractionSucceeded) {
|
||||||
|
throw (New-Object System.Exception("Failed to extract driver '$packageTitle'. See log for details."))
|
||||||
|
}
|
||||||
|
|
||||||
} # End foreach package
|
} # End foreach package
|
||||||
|
|
||||||
@@ -451,12 +455,10 @@ function Save-LenovoDriversTask {
|
|||||||
|
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$status = "Error: $($_.Exception.Message.Split('.')[0])" # Shorten error message
|
$status = "Error: $($_.Exception.Message)"
|
||||||
WriteLog "Error saving Lenovo drivers for '$identifier': $($_.Exception.ToString())" # Log full exception string
|
WriteLog "Error saving Lenovo drivers for '$identifier': $($_.Exception.ToString())"
|
||||||
$success = $false
|
$success = $false
|
||||||
# Enqueue the error status before returning
|
|
||||||
if ($null -ne $ProgressQueue) { Invoke-ProgressUpdate -ProgressQueue $ProgressQueue -Identifier $identifier -Status $status }
|
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 }
|
return [PSCustomObject]@{ Identifier = $identifier; Status = $status; Success = $success; DriverPath = $null }
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|||||||
@@ -716,6 +716,7 @@ function Invoke-DownloadSelectedDrivers {
|
|||||||
|
|
||||||
$overallSuccess = $true
|
$overallSuccess = $true
|
||||||
$successfullyDownloaded = [System.Collections.Generic.List[PSCustomObject]]::new()
|
$successfullyDownloaded = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||||
|
$failedDownloads = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||||
|
|
||||||
# Check the results from the parallel processing tasks
|
# Check the results from the parallel processing tasks
|
||||||
if ($null -ne $parallelResults) {
|
if ($null -ne $parallelResults) {
|
||||||
@@ -737,11 +738,21 @@ function Invoke-DownloadSelectedDrivers {
|
|||||||
if ([string]::IsNullOrWhiteSpace($modelName)) {
|
if ([string]::IsNullOrWhiteSpace($modelName)) {
|
||||||
WriteLog "Could not determine model name from result object: $($result | ConvertTo-Json -Compress -Depth 3)"
|
WriteLog "Could not determine model name from result object: $($result | ConvertTo-Json -Compress -Depth 3)"
|
||||||
$overallSuccess = $false
|
$overallSuccess = $false
|
||||||
|
$failedDownloads.Add([PSCustomObject]@{
|
||||||
|
Model = 'Unknown model'
|
||||||
|
Status = 'Driver task returned without a model identifier.'
|
||||||
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($resultCode -ne 0) {
|
if ($resultCode -ne 0) {
|
||||||
$overallSuccess = $false
|
$overallSuccess = $false
|
||||||
|
$failureStatus = $result['Status']
|
||||||
|
if ([string]::IsNullOrWhiteSpace($failureStatus)) { $failureStatus = 'Driver download failed. Check the log for details.' }
|
||||||
|
$failedDownloads.Add([PSCustomObject]@{
|
||||||
|
Model = $modelName
|
||||||
|
Status = $failureStatus
|
||||||
|
})
|
||||||
WriteLog "Error detected for model $modelName."
|
WriteLog "Error detected for model $modelName."
|
||||||
}
|
}
|
||||||
elseif (-not [string]::IsNullOrWhiteSpace($driverPath)) {
|
elseif (-not [string]::IsNullOrWhiteSpace($driverPath)) {
|
||||||
@@ -758,6 +769,16 @@ function Invoke-DownloadSelectedDrivers {
|
|||||||
WriteLog "Warning: Could not find 'Make' for successful download of model '$modelName'. Skipping from DriverMapping.json."
|
WriteLog "Warning: Could not find 'Make' for successful download of model '$modelName'. Skipping from DriverMapping.json."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
$overallSuccess = $false
|
||||||
|
$fallbackStatus = $result['Status']
|
||||||
|
if ([string]::IsNullOrWhiteSpace($fallbackStatus)) { $fallbackStatus = 'Driver download did not return a driver path.' }
|
||||||
|
$failedDownloads.Add([PSCustomObject]@{
|
||||||
|
Model = $modelName
|
||||||
|
Status = $fallbackStatus
|
||||||
|
})
|
||||||
|
WriteLog "Driver download did not provide a path for model $modelName."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,8 +876,21 @@ function Invoke-DownloadSelectedDrivers {
|
|||||||
[System.Windows.MessageBox]::Show("All selected driver downloads processed. Check status column for details.", "Download Process Finished", "OK", "Information")
|
[System.Windows.MessageBox]::Show("All selected driver downloads processed. Check status column for details.", "Download Process Finished", "OK", "Information")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$State.Controls.txtStatus.Text = "Driver downloads processed with some errors. Check status column and log."
|
$State.Controls.txtStatus.Text = "Driver download failed. Resolve the errors and try again."
|
||||||
[System.Windows.MessageBox]::Show("Driver downloads processed, but some errors occurred. Please check the status column for each driver and the log file for details.", "Download Process Finished with Errors", "OK", "Warning")
|
$messageLines = [System.Collections.Generic.List[string]]::new()
|
||||||
|
if ($failedDownloads.Count -gt 0) {
|
||||||
|
$messageLines.Add("Driver download failed for:")
|
||||||
|
foreach ($item in ($failedDownloads | Select-Object -First 5)) {
|
||||||
|
$messageLines.Add("- $($item.Model): $($item.Status)")
|
||||||
|
}
|
||||||
|
if ($failedDownloads.Count -gt 5) {
|
||||||
|
$messageLines.Add("...see the log for additional failures.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$messageLines.Add("One or more driver downloads failed. Check the log for details.")
|
||||||
|
}
|
||||||
|
[System.Windows.MessageBox]::Show(($messageLines -join [System.Environment]::NewLine), "Driver Download Failed", "OK", "Error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user