I'm trying to upload really big VM Images (5-15 Gb size) to an HTTP server using PowerShell.
I tried to use for that few methods (here links to script with net.WebClient.UploadFile and script with Invoke-webRequest)
It works well for files less than 2GB, but not for files larger than this.
I'm trying to work with httpWebRequest directly but I unable to put FileStream
into it.
So my question is: how to put filestream into webrequest?
Or more generally: how to upload huge file via http with PowerShell?
$Timeout=10000000;
$fileName = "0.iso";
$data = "C:\\$fileName";
$url = "http://nexus.lab.local:8081/nexus/content/sites/myproj/$fileName";
#$buffer = [System.IO.File]::Open("$data",[System.IO.Filemode]::Open, [System.IO.FileAccess]::Read) #Err Cannot convert argument "buffer", with value: "System.IO.FileStream", for "Write" to type "System.Byte[]":
#$buffer = gc -en byte $data # too much space in memory
$buffer = [System.IO.File]::ReadAllBytes($data) #Limit 2gb
[System.Net.HttpWebRequest] $webRequest = [System.Net.WebRequest]::Create($url)
$webRequest.Timeout = $timeout
$webRequest.Method = "POST"
$webRequest.ContentType = "application/data"
#$webRequest.ContentLength = $buffer.Length;
$webRequest.Credentials = New-Object System.Net.NetworkCredential("admin", "admin123");
$requestStream = $webRequest.GetRequestStream()
$requestStream.Write($buffer, 0, $buffer.Length)
$requestStream.Flush()
$requestStream.Close()
[System.Net.HttpWebResponse] $webResponse = $webRequest.GetResponse()
$streamReader = New-Object System.IO.StreamReader($webResponse.GetResponseStream())
$result = $streamReader.ReadToEnd()
return $result
$stream.Close()
Thank you @Stoune, it was last thing that helped to receive finally working solution.
One more, it is need to organize stream file reading and writing to the webrequest buffer. And it possibly to do with that piece of code:
And final script look like this:
By default HttpWebRequest is buffering data in memory. Just set HttpWebRequest.AllowWriteStreamBuffering property to false and you would be able to upload files with almost any size. See more details at msdn
For uploading to Sonatype Nexus3 I used the code below. Took me some time to figure it out, working with uploads and reponse from Nexus3 and uploading and downloading large files (larger than 2GB). We have Apache in front of Nexus3 taking care of the https connections. Using basic authentication made sure that Nexus was responding right, when Apache is in front of it. Sending pre-authentication via HEAD and using chunked upload for large files fixed that uploading large files did not end prematurely.
Downloading large files via Invoke-WebRequest would fail too with different errors. Now I use
WebRequest
via .Net and it works, seeDownload-File
.And when the code was run via an automated process (from System Center Orchestrator), https would fail. So we force TLS 1.2 when scheme https is detected.