Использование Powershell и Invoke-WebRequest для загрузки 2,5 ГБ на веб-сервер

Я сетевой инженер и не имею никакого опыта в написании сценариев или PowerShell, однако я начал заниматься этим в последнее время, так как мне нужно создать пару сценариев. Я работаю в VMware и хочу создать сценарий, который автоматизирует обновление среды NSX, и первый шаг для этого - загрузить пакет обновления в NSX Manager (который в конце является веб-сервером). Из Руководства по API NSX (https://pubs.vmware.com/NSX-62/topic/com.vmware.ICbase/PDF/nsx_62_api.pdf) вы должны использовать указанный ниже API для загрузки пакета обновления POST https://NSX-Manager-IP-Address/api/1.0/appliance-management/upgrade/uploadbundle/NSX Итак, я пытаюсь создать сценарий, который сначала будет запрашивать у вас требуемую версию для обновления, и на основе этого я помещу путь к файлу в переменную, а затем использую invoke-webrequest с параметром -Infile для загрузки пакета обновления.

Однако, когда я это делаю, процесс загрузки начинается, но через пару минут я всегда получаю следующую ошибку (Invoke-WebRequest: базовое соединение было закрыто: при отправке произошла непредвиденная ошибка).

После некоторого поиска я понял, что invoke-webrequest сначала буферизует файл размером 2,5 ГБ, а затем загрузит его, и, возможно, поэтому соединение закрыто, поскольку NSX Manager еще ничего не получил.

Также я понял, что могу отключить буферизацию, используя следующее (в качестве примера): $ webRequest.AllowWriteStreamBuffering = $ false $ webRequest.SendChunked = $ true

Однако я не знаю, как добавить это в сценарий.

Ниже приведен полный сценарий, который у меня есть на данный момент: PS: версия PowerShell, которую я использую, составляет 5

[CmdletBinding()]
$NSXUsername = "admin"
$NSXPassword = "VMware1!"
$uriP = "https://HQ-NSX-01a.nsx.gss"


# Start time.
$startclock = (Get-Date)
Write-Host -BackgroundColor:Black -ForegroundColor:Green "Hello"
Write-Host -BackgroundColor:Black -ForegroundColor:Green "This script will help you to automate a full NSX environment UPgrade"
Write-Host -BackgroundColor:Black -ForegroundColor:Green "FULL NSX Tier UPgrade for Single-VC is starting, This UPgrade proccess will take an average of 40 min
========================================================================================
                                 "




# Create NSX authorization string and store in $head and used in API Calls
# $nsxcreds = New-Object System.Management.Automation.PSCredential $NSXUsername,$NSXPassword
$auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($NSXUsername + ":" + $NSXPassword))
$head = @{"Authorization"="Basic $auth"}

# Allow untrusted SSL certs else will error out
    add-type @"
        using System.Net;
        using System.Security.Cryptography.X509Certificates;
        public class TrustAllCertsPolicy : ICertificatePolicy {
            public bool CheckValidationResult(
                ServicePoint srvPoint, X509Certificate certificate,
                WebRequest request, int certificateProblem) {
                return true;
            }
        }
"@
    [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

##################################################
# Choosing the required NSX Version to be deployed
##################################################

[int]$menuoptions = 0
while ( $menuoptions -lt 1 -or $menuoptions -gt 12 ) {
Write-host -BackgroundColor:Black -ForegroundColor:Red "    Please choose the required version of NSX to be deployed (Accepted inputs are a number from 1 to 12)                    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     1.NSX-6.2.0 "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     2.NSX-6.2.1 "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     3.NSX-6.2.1a    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     4.NSX-6.2.2 "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     5.NSX-6.2.2a    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     6.NSX-6.2.2b    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     7.NSX-6.2.3 "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     8.NSX-6.2.3a    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     9.NSX-6.2.3b    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     10.NSX-6.2.4    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     11.NSX-6.2.5    "
Write-host -BackgroundColor:Black -ForegroundColor:Yellow "     12.NSX-6.3.6    "
[int]$menuoptions = read-host
if ($menuoptions -lt 1 -or $menuoptions -gt 12) {Write-host -BackgroundColor:Black -ForegroundColor:Red "       Invalid Input Detected, Please choose a valid input"}
}
Switch( $menuoptions ) {
1{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.0-2986609.tar.gz"}
2{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.1-3300239.tar.gz"}
3{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.1a-3496286.tar.gz"}
4{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.2-3604087.tar.gz"}
5{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.2a-3638734.tar.gz"}
6{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.2b-3755950.tar.gz"}
7{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.3-3979471.tar.gz"}
8{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.3a-4167369.tar.gz"}
9{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.3b-4287432.tar.gz"}
10{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.4-4292526.tar.gz"}
11{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.5-4818372.tar.gz"}
12{$nsxpath = "D:\NSX-6.2.x-UPGrade-Bundles\VMware-NSX-Manager-upgrade-bundle-6.2.6-4977495.tar.gz"}
}

Switch( $menuoptions ) {
1{$nsxversion = "NSX-6.2.0"}
2{$nsxversion = "NSX-6.2.1"}
3{$nsxversion = "NSX-6.2.1a"}
4{$nsxversion = "NSX-6.2.2"}
5{$nsxversion = "NSX-6.2.2a"}
6{$nsxversion = "NSX-6.2.2b"}
7{$nsxversion = "NSX-6.2.3"}
8{$nsxversion = "NSX-6.2.3a"}
9{$nsxversion = "NSX-6.2.3b"}
10{$nsxversion = "NSX-6.2.4"}
11{$nsxversion = "NSX-6.2.5"}
12{$nsxversion = "NSX-6.3.6"}
}


#===========================================================================================================================================    
#===========================================================================================================================================    


#########################
# Upgrading NSX Manager
#########################

    Write-Host -BackgroundColor:Black -ForegroundColor:Green "1. Deploying NSX Manager with version $nsxversion"

    Write-Host -BackgroundColor:Black -ForegroundColor:Yellow "     UPloading the required upgrade bundel to NSX Manager"


$r = Invoke-WebRequest -Uri "$uriP/api/1.0/appliance-management/upgrade/uploadbundle/NSX" -Method:Post -Headers $head -ContentType "application/xml" -InFile $nsxpath -TimeoutSec 66000 -DisableKeepAlive 

Любая идея будет очень полезна и очень оценена

Спасибо за помощь.


person Taher Shaker    schedule 16.02.2017    source источник


Ответы (1)


Я думаю, что этот вопрос задавался здесь раньше: Загрузить БОЛЬШИЕ файлы через HTTP

Похоже, что предлагаемое решение - использовать класс .NET [System.Net.HttpWebRequest].

Я не тестировал это, но думаю, вы можете заменить свой $r = Invoke-WebRequest чем-нибудь в этом роде:

$webRequest = [System.Net.HttpWebRequest]::Create("$uriP/api/1.0/appliance-management/upgrade/uploadbundle/NSX")
$webRequest.Timeout = 66000
$webRequest.Method = "POST"
$webRequest.ContentType = "application/xml"
$webRequest.AllowWriteStreamBuffering=$false
$webRequest.SendChunked=$true
$webRequest.Credentials = $auth
$webRequest.Headers["Authorization"] = "Basic $auth"

$requestStream = $webRequest.GetRequestStream()
$fileStream = [System.IO.File]::OpenRead($nsxpath)
$chunk = New-Object byte[] $bufSize
  while( $bytesRead = $fileStream.Read($chunk,0,$bufsize) )
  {
    $requestStream.write($chunk, 0, $bytesRead)
    $requestStream.Flush()
  }

$responseStream = $webRequest.getresponse()

$FileStream.Close()
$requestStream.Close()
$responseStream.Close()

$responseStream
$responseStream.GetResponseHeader("Content-Length") 
$responseStream.StatusCode
person Mark Wragg    schedule 17.02.2017
comment
Марк, Большое спасибо за вашу помощь. Я пробовал это раньше, но с вашей помощью я смог лучше понять это, однако я столкнулся с проблемой, так как я получаю следующую ошибку, когда скрипт достигает цикла while. Исключение, вызывающее запись с 3 аргументами: Невозможно для записи данных в транспортное соединение: существующее соединение было принудительно закрыто удаленным хостом. и это связано с этой частью скрипта: while ($ bytesRead = $ fileStream.Read ($ chunk, 0, $ bufsize)) {$ requestStream.write ($ chunk, 0, $ bytesRead) $ requestStream.Flush () } - person Taher Shaker; 17.02.2017