У меня есть сценарий PowerShell, который я разрабатываю, который будет загружать файлы с HTTP-сервера через прокси и включать UN / PW на сервере.
У меня файлы загружаются нормально, но некоторые файлы очень большие, поэтому я добавил функцию, чтобы проверить, не изменился ли файл (проверка размера). Это работает с первым файлом. Но время ожидания второго файла в этой строке истекает:
$test = $wc2.OpenRead($source) | Out-Null)
Код моего сценария, за исключением учетных данных, приведен ниже. Я был бы признателен за совет о том, как правильно закрыть соединение (как я подозреваю, этого не происходит) или о том, как получить размер удаленного файла через HTTP с помощью Powershell.
Function getWebClient {
$webClient = new-object System.Net.WebClient
$pxy = new-object System.Net.WebProxy $proxy
$pxy.Credentials = New-Object System.Net.NetworkCredential ("tnad\$proxy_un", "$proxy_pw")
$webClient.proxy=$pxy
$webClient.Headers.Add("user-agent", "Windows Powershell WebClient Header")
$WebClient.Credentials = New-Object System.Net.Networkcredential($un, $pw)
return $WebClient
}
foreach ($ds in $datasetsTest) {
Write-Host "Checking: $ds"
$source = "$server$ds"
$dest = "$destFolder$ds"
#Test whether the destination file already exists, if it exists, compare file sizes.
$destExists = Test-Path $dest
if($destExists -eq $false) {
Try {
$wc1 = getWebClient
$wc1.DownloadFile($source, $dest)
$wc1.Dispose()
Write-Host "File downloaded" -foregroundcolor "green"
} Catch {
Write-Host "Downloading $ds failed..." -foregroundcolor "red"
}
} else {
$localFileSize = (Get-Item $dest).length
$wc2 = getWebClient
$test = $wc2.OpenRead($source) | Out-Null
$wc2.Dispose()
$remoteFileSize = $wc2.ResponseHeaders["Content-Length"]
Write-Host "Local file size: $localFileSize, remote file size: $remoteFileSize"
if(!($localFileSize -eq $remoteFileSize)) {
#file exists, but the server version changed...
Try {
Remove-Item $dest
$wc3 = getWebClient
$wc3.DownloadFile($source, $dest)
$wc3.Dispose($true)
Write-Host "File downloaded" -foregroundcolor "green"
} Catch {
Write-Host "Downloading $ds failed..." -foregroundcolor "red"
}
} else {
Write-Host "Skipping, file exists and hasn't changed" -foregroundcolor "magenta"
}
}
}
Я не могу комментировать этот конкретный вопрос как таковой, но хотел бы дать несколько общих рекомендаций. За последние несколько лет я написал очень важный код PS, некоторые из которых взаимодействуют с удаленным телеметрическим оборудованием через HTTPS. Этот код должен либо успешно завершиться, либо корректно завершиться с очень подробным ведением журнала. Код, хотя и выполняется на виртуальных машинах Windows, рассматривается как «встроенная система / устройство».
Я искренне рекомендую добавить в ваш скрипт код обработки ошибок. Конечно, в Интернете полно потрясающих примеров кода PowerShell, и каждый последующий шаг предполагает, что предыдущий был успешным. Иногда это усугубляется чрезмерным использованием конвейеров PS, например: enumerate-something | foreach-object {do-something}, где некоторые действия не работают, что означает, что вы часто попадаете в ситуацию невозможного отката.
Во всяком случае, хватит болтовни. Рекомендации:
Я остановлюсь на этом!
Удачи.
Проблема связана с тем, что переменной $ test присвоено нулевое значение.
Когда вы создаете переменную $ test
$test = $wc2.OpenRead($source) | Out-Null
часть "| Out-Null" обнуляет результаты, вызывая присвоение null $ test, удалите его, и у вас не должно быть проблем.
В качестве отступления от вашего вопроса о закрытии соединений System.Net.WebClient: Действие на вашем конце не требуется, все HTTP-соединения закрываются по мере необходимости и не должны мешать установлению второго соединения. Открытое постоянное соединение обеспечит более своевременное и эффективное соединение при последующих подключениях к тому же URL-адресу. Более подробную информацию о постоянных HTTP-соединениях можно найти Вот.