mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Add HTTP fallback for BITS transfer network authentication errors
Enhances the BITS transfer retry logic to detect when the current session lacks network authentication and automatically falls back to Invoke-WebRequest for completion. Detects the "not logged on to the network" error condition by checking both the HResult code (0x800704DD) and error message patterns, then triggers an HTTP-based fallback mechanism to retry the download with remaining attempts. This ensures downloads can succeed even when BITS fails due to authentication issues, improving reliability of the transfer function in environments with network authentication requirements.
This commit is contained in:
@@ -148,26 +148,45 @@ function Start-BitsTransferWithRetry {
|
|||||||
|
|
||||||
$attempt = 0
|
$attempt = 0
|
||||||
$lastError = $null
|
$lastError = $null
|
||||||
|
$notLoggedOnHResult = [int]0x800704dd
|
||||||
|
$fallbackTriggered = $false
|
||||||
|
|
||||||
while ($attempt -lt $Retries) {
|
while ($attempt -lt $Retries -and -not $fallbackTriggered) {
|
||||||
$OriginalVerbosePreference = $VerbosePreference
|
$OriginalVerbosePreference = $VerbosePreference
|
||||||
$OriginalProgressPreference = $ProgressPreference
|
$OriginalProgressPreference = $ProgressPreference
|
||||||
try {
|
try {
|
||||||
$VerbosePreference = 'SilentlyContinue'
|
$VerbosePreference = 'SilentlyContinue'
|
||||||
$ProgressPreference = 'SilentlyContinue'
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
|
||||||
Start-BitsTransfer -Source $Source -Destination $Destination -Priority Normal -ErrorAction Stop
|
Start-BitsTransfer -Source $Source -Destination $Destination -Priority Normal -ErrorAction Stop
|
||||||
|
|
||||||
$ProgressPreference = $OriginalProgressPreference
|
$ProgressPreference = $OriginalProgressPreference
|
||||||
$VerbosePreference = $OriginalVerbosePreference
|
$VerbosePreference = $OriginalVerbosePreference
|
||||||
WriteLog "Successfully transferred $Source to $Destination."
|
WriteLog "Successfully transferred $Source to $Destination."
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
$lastError = $_
|
$lastError = $_
|
||||||
$attempt++
|
$attempt++
|
||||||
WriteLog "Attempt $attempt of $Retries failed to download $Source. Error: $($lastError.Exception.Message)."
|
$errorMessage = $lastError.Exception.Message
|
||||||
Start-Sleep -Seconds (1 * $attempt)
|
WriteLog "Attempt $attempt of $Retries failed to download $Source. Error: $errorMessage."
|
||||||
|
$hResult = $null
|
||||||
|
if ($null -ne $lastError.Exception) {
|
||||||
|
$hResult = $lastError.Exception.HResult
|
||||||
|
}
|
||||||
|
$needsHttpFallback = $false
|
||||||
|
if ($hResult -eq $notLoggedOnHResult) {
|
||||||
|
$needsHttpFallback = $true
|
||||||
|
}
|
||||||
|
elseif ($errorMessage -match '0x800704DD' -or $errorMessage -match 'not.*logged on to the network') {
|
||||||
|
$needsHttpFallback = $true
|
||||||
|
}
|
||||||
|
if ($needsHttpFallback) {
|
||||||
|
WriteLog "BITS cannot download $Source because the current session is not logged on to the network. Falling back to Invoke-WebRequest."
|
||||||
|
$fallbackTriggered = $true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Start-Sleep -Seconds (1 * $attempt)
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (Get-Variable -Name 'OriginalProgressPreference' -ErrorAction SilentlyContinue) {
|
if (Get-Variable -Name 'OriginalProgressPreference' -ErrorAction SilentlyContinue) {
|
||||||
@@ -179,8 +198,43 @@ function Start-BitsTransferWithRetry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteLog "Failed to download $Source after $Retries attempts. Last Error: $($lastError.Exception.Message)"
|
if ($fallbackTriggered) {
|
||||||
throw $lastError
|
$remainingAttempts = $Retries - $attempt
|
||||||
|
if ($remainingAttempts -lt 1) {
|
||||||
|
$remainingAttempts = 1
|
||||||
|
}
|
||||||
|
$httpAttempt = 0
|
||||||
|
while ($httpAttempt -lt $remainingAttempts) {
|
||||||
|
$httpAttempt++
|
||||||
|
$OriginalVerbosePreference = $VerbosePreference
|
||||||
|
$OriginalProgressPreference = $ProgressPreference
|
||||||
|
try {
|
||||||
|
$VerbosePreference = 'SilentlyContinue'
|
||||||
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
Invoke-WebRequest -Uri $Source -OutFile $Destination -ErrorAction Stop
|
||||||
|
$ProgressPreference = $OriginalProgressPreference
|
||||||
|
$VerbosePreference = $OriginalVerbosePreference
|
||||||
|
WriteLog "Successfully transferred $Source to $Destination via HTTP fallback."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
$lastError = $_
|
||||||
|
WriteLog "HTTP fallback attempt $httpAttempt of $remainingAttempts failed to download $Source. Error: $($lastError.Exception.Message)."
|
||||||
|
Start-Sleep -Seconds (1 * $httpAttempt)
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (Get-Variable -Name 'OriginalProgressPreference' -ErrorAction SilentlyContinue) {
|
||||||
|
$ProgressPreference = $OriginalProgressPreference
|
||||||
|
}
|
||||||
|
if (Get-Variable -Name 'OriginalVerbosePreference' -ErrorAction SilentlyContinue) {
|
||||||
|
$VerbosePreference = $OriginalVerbosePreference
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLog "Failed to download $Source after $Retries attempts. Last Error: $($lastError.Exception.Message)"
|
||||||
|
throw $lastError
|
||||||
}
|
}
|
||||||
|
|
||||||
function Set-Progress {
|
function Set-Progress {
|
||||||
|
|||||||
Reference in New Issue
Block a user