#powershell #microsoft-bits
#powershell #microsoft-bits
Вопрос:
Я выполняю передачу BITS ежедневных изображений с веб-сервера, и я продолжаю получать случайные удаления во время передачи.
При циклическом просмотре загрузок я время от времени получаю сообщение «Соединение было закрыто преждевременно» или «Произошла ошибка в службе поддержки защищенного канала». В каждой папке около 180 изображений, и это происходит, возможно, для 5-10% из них. Мне нужно повторить попытку загрузки для тех, которые не завершились.
Мой код для этого следующий — мой несовершенный обходной путь — запустить цикл дважды, но я надеюсь найти лучшее решение.
# Set the URL where the images are located
$url = 'https://www.nrlmry.navy.mil/archdat/global/stitched/MoS_2/navgem/wind_waves/latest/'
# Set the local path where the images will be stored
$path = 'C:imagesWind_Waveslatest'
# Create a list of all assets returned from $url
$site = Invoke-WebRequest -UseBasicParsing -Uri $url
# Create a table subset from the $site of all files returned with a .jpg extension
$table = $site.Links | Where-Object{ $_.tagName -eq 'A' -and $_.href.ToLower().EndsWith("jpg") }
# Create a list of all href items from the table amp; call it $images
$images = $table.href
# Enumerate all of the images - for troubleshooting purposes - can be removed
$images
# Check to make sure there are images available for download - arbitrarily picked more than 2 $images
if($images.count -gt 2){
# Delete all of the files in the "latest" folder
Remove-Item ($path "*.*") -Force
# For loop to check to see if we already have the image and, if not, download it
ForEach ($image in $images)
{
if(![System.IO.File]::Exists($path $image)){
Write-Output "Downloading: " $image
Start-BitsTransfer -Source ($url $image) -Destination $path -TransferType Download -RetryInterval 60
Start-Sleep 2
}
}
Get-BitsTransfer | Where-Object {$_.JobState -eq "Transferred"} | Complete-BitsTransfer
} else {
Write-Output "No images to download"}
Ответ №1:
Я не вижу никакой обработки ошибок в вашем коде для возобновления / повторной попытки / перезапуска при сбое.
- Значение, почему нет try / catch в цикле или Get?
- Если Get включен для каждого задания загрузки в цикле, почему он находится вне цикла?
Загрузка используется по умолчанию для TransferType, поэтому указывать не нужно, обычно при этом генерируется ошибка.
Итак, что-то вроде этого. Я проверил это, но никогда не получал сбоя. Тем не менее, у меня очень высокоскоростное подключение к Интернету. Если вы делаете это внутри предприятия, пограничные устройства (фильтры, прокси-серверы, также могут замедлять работу, потенциально вызывая тайм-ауты.)
$url = 'https://www.nrlmry.navy.mil/archdat/global/stitched/MoS_2/navgem/wind_waves/latest/'
$path = 'D:TempimagesWind_Waveslatest'
$site = Invoke-WebRequest -UseBasicParsing -Uri $url
# Create a table subset from the $site of all files returned with a .jpg extension
$table = $site.Links |
Where-Object{
$_.tagName -eq 'A' -and
$_.href.ToLower().EndsWith('jpg')
}
<#
# Create a list of all href items from the table amp; call it $images
Enumerate all of the images - for troubleshooting purposes - can be removed
Assign and display using variable squeezing
#>
($images = $table.href)
<#
Check to make sure there are images available for download - arbitrarily
picked more than 2 $images
#>
if($images.count -gt 2)
{
Remove-Item ($path '*.*') -Force
ForEach ($image in $images)
{
Try
{
Write-Verbose -Message "Downloading: $image" -Verbose
if(![System.IO.File]::Exists($path $image))
{
$StartBitsTransferSplat = @{
Source = ($url $image)
Destination = $path
RetryInterval = 60
}
Start-BitsTransfer @StartBitsTransferSplat -ErrorAction Stop
Start-Sleep 2
}
Get-BitsTransfer |
Where-Object {$PSItem.JobState -eq 'Transferred'} |
Complete-BitsTransfer
}
Catch
{
$PSItem.Exception.Message
Write-Warning -Message "Download of $image not complete or failed. Attempting a resume/retry" -Verbose
Get-BitsTransfer -Name $image | Resume-BitsTransfer
}
}
}
else
{
Write-Warning -Message 'No images to download'
$PSItem.Exception.Message
}
Смотрите файлы справки
Модуль Resume-BitsTransfer: bitstransfer возобновляет задание по передаче BITS.
# Example 1: Resume all BITS transfer jobs owned by the current user
Get-BitsTransfer | Resume-BitsTransfer
# Example 2: Resume a new BITS transfer job that was initially suspended
$Bits = Start-BitsTransfer -DisplayName "MyJob" -Suspended
Add-BitsTransfer -BitsJob $Bits -ClientFileName C:myFile -ServerFileName http://www.SomeSiteName.com/file1
Resume-BitsTransfer -BitsJob $Bits -Asynchronous
# Example 3: Resume the BITS transfer by the specified display name
Get-BitsTransfer -Name "TestJob01" | Resume-BitsTransfer
Комментарии:
1. Спасибо за это! При сбое загрузки я получаю следующее сообщение об ошибке в разделе Catch: «ПРЕДУПРЕЖДЕНИЕ: загрузка wind_waves_2020090300_0034.jpg не завершено или сбой. Попытка возобновить / повторить Get-BitsTransfer: не удается найти передачу битов с именем ‘wind_waves_2020090300_0034.jpg . Вы можете использовать командлет Get-BitsTransfer без каких-либо параметров для просмотра списка текущих передач битов. ПОДРОБНО: Загрузка: wind_waves_2020090300_0035.jpg Произошла ошибка в службе поддержки защищенного канала»
2. Не беспокойтесь. Как я уже говорил, у меня очень высокоскоростное соединение, а не шлюзы / фильтрация, поэтому я никогда не попадал в область ошибок. Тем не менее, вся эта ошибка означает, что имя при проверке задания недопустимо. Итак, это означает, что вам нужно перехватить имя задания в сеансе отладки, чтобы выяснить, что это может быть, или вместо этого использовать идентификатор задания.
3. Я оборачиваю раздел Try-Catch в цикле do-while со счетчиком, чтобы передача BITS повторялась до 5 раз.
Ответ №2:
Вот несколько измененная версия приведенного выше кода. Похоже, что объект задания BITS transfer исчезает при возникновении ошибки, поэтому нет смысла пытаться найти / возобновить это задание. Вместо этого я заключил весь блок Try-Catch в цикл while с завершением при загрузке файла.
$url = 'https://www.nrlmry.navy.mil/archdat/global/stitched/MoS_2/navgem/wind_waves/latest/'
$path = 'D:TempimagesWind_Waveslatest'
$site = Invoke-WebRequest -UseBasicParsing -Uri $url
$MaxRetries = 3 # Initialize the maximum number of retry attempts.
# Create a table subset from the $site of all files returned with a .jpg extension
$table = $site.Links |
Where-Object {
$_.tagName -eq 'A' -and
$_.href.ToLower().EndsWith('jpg')
}
<#
# Create a list of all href items from the table amp; call it $images
Enumerate all of the images - for troubleshooting purposes - can be removed
Assign and display using variable squeezing
#>
($images = $table.href)
<#
Check to make sure there are images available for download - arbitrarily
picked more than 2 $images
#>
if ($images.count -gt 2) {
Remove-Item ($path '*.*') -Force
ForEach ($image in $images) {
# Due to occasional failures to transfer, wrap the BITS transfer in a while loop
# re-initialize the exit counter for each new image
$retryCount = 0
while ($retryCount -le $MaxRetries){
Try {
Write-Verbose -Message "Downloading: $image" -Verbose
if (![System.IO.File]::Exists($path $image)) {
$StartBitsTransferSplat = @{
Source = ($url $image)
Destination = $path
RetryInterval = 60
}
Start-BitsTransfer @StartBitsTransferSplat -ErrorAction Stop
Start-Sleep 2
}
# To get here, the transfer must have finished, so set the counter
# greater than the max value to exit the loop
$retryCount = $MaxRetries 1
} # End Try block
Catch {
$PSItem.Exception.Message
$retryCount = 1
Write-Warning -Message "Download of $image not complete or failed. Attempting retry #: $retryCount" -Verbose
} # End Catch Block
} # End While loop for retries
} # End of loop over images
} # End of test for new images
else {
Write-Warning -Message 'No images to download'
$PSItem.Exception.Message
} # End of result for no new images
Комментарии:
1. Иногда передача зависает на полпути во время передачи и не продвигается вперед — в таких случаях система остается зависшей около часа, прежде чем выдает ошибку и пытается снова. Есть ли способ перехватить эти зависшие передачи и принудительно повторить попытку через x секунд?
Ответ №3:
Вот комбинация кода, предоставленного postanote, и цикла выполнения во время выполнения, чтобы повторить загрузку до 5 раз, если выдается ошибка.
$url = 'https://www.nrlmry.navy.mil/archdat/global/stitched/MoS_2/navgem/wind_waves/latest/'
$path = 'D:TempimagesWind_Waveslatest'
$site = Invoke-WebRequest -UseBasicParsing -Uri $url
# Create a table subset from the $site of all files returned with a .jpg extension
$table = $site.Links |
Where-Object{
$_.tagName -eq 'A' -and
$_.href.ToLower().EndsWith('jpg')
}
<#
# Create a list of all href items from the table amp; call it $images
Enumerate all of the images - for troubleshooting purposes - can be removed
Assign and display using variable squeezing
#>
($images = $table.href)
<# Check to make sure there are images available for download - arbitrarily
picked more than 2 $images #>
if($images.count -gt 2)
{
Remove-Item ($path '*.*') -Force
ForEach ($image in $images)
{
# Create a Do-While loop to retry downloads up to 5 times if they fail
$Stoploop = $false
[int]$Retrycount = "0"
do{
Try
{
Write-Verbose -Message "Downloading: $image" -Verbose
if(![System.IO.File]::Exists($path $image))
{
$StartBitsTransferSplat = @{
Source = ($url $image)
Destination = $path
RetryInterval = 60
}
Start-BitsTransfer @StartBitsTransferSplat -ErrorAction Stop
Start-Sleep 10
$Stoploop = $true
}
Get-BitsTransfer |
Where-Object {$PSItem.JobState -eq 'Transferred'} |
Complete-BitsTransfer
}
Catch
{
if ($Retrycount -gt 5){
$PSItem.Exception.Message
Write-Warning -Message "Download of $image not complete or failed." -Verbose
$Stoploop = $true
}
else {
Write-Host "Could not download the image, retrying..."
Start-Sleep 10
$Retrycount = $Retrycount 1
}
}
}
While ($Stoploop -eq $false)
}
}
else
{
Write-Warning -Message 'No images to download'
$PSItem.Exception.Message
}
Комментарии:
1. Похоже, что прерванные передачи все еще отображаются в списке окон терминала, когда происходит повторная попытка — не уверен, что я должен сделать, чтобы исправить это (если что-нибудь)?