Last active
May 13, 2019 15:18
-
-
Save dindoliboon/f378b41ed09a820d10407466a503161e to your computer and use it in GitHub Desktop.
Download files in Nano Server.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.DESCRIPTION | |
Downloads a file from the specified website. | |
.EXAMPLE | |
Downloads Jetty 9.3.20. | |
Get-WebFile -Uri 'http://central.maven.org/maven2/org/eclipse/jetty/jetty-distribution/9.3.20.v20170531/jetty-distribution-9.3.20.v20170531.zip' -OutFile 'C:\jetty-distribution-9.3.20.v20170531.zip' | |
.EXAMPLE | |
Downloads Oracle Server JRE 8u131 and verifies hash. | |
Get-WebFile -Uri 'http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/server-jre-8u131-windows-x64.tar.gz' -OutFile 'C:\server-jre-8u131-windows-x64.tar.gz' -Cookie 'oraclelicense=accept-securebackup-cookie;' -Hash '1806EBE235EAB2B21C893ACBF0B287A392CE6B5EDFEA3286FC8FF7D6DEFB19CB' | |
.OUTPUTS | |
Boolean. True if successful and if specified, hash value matches. Otheriwse, False is returned. | |
.NOTES | |
Tested on Windows Server 2016, Nano Server. | |
[Environment]::OSVersion | |
Platform Version | |
-------- ------- | |
Win32NT 10.0.14393.0 | |
$PSVersionTable | |
Name Value | |
---- ----- | |
PSVersion 5.1.14393.1000 | |
SerializationVersion 1.1.0.1 | |
PSEdition Core | |
PSRemotingProtocolVersion 2.3 | |
CLRVersion | |
BuildVersion 10.0.14393.1000 | |
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} | |
WSManStackVersion 3.0 | |
Code from the following websites: | |
https://stackoverflow.com/questions/20661652/progress-bar-with-httpclient | |
https://github.com/dotnet/corefx/issues/6849 | |
https://stackoverflow.com/a/13287224 | |
https://serverfault.com/a/788951 | |
#> | |
function Get-WebFile ($Uri, $OutFile, $Cookie, $Hash, $Algorithm='SHA256', $BufferSize=64KB) | |
{ | |
$ret = $false | |
if ((Test-Path -Path $OutFile) -eq $false) | |
{ | |
Add-Type -AssemblyName System.Net.Http | |
$handler = New-Object -TypeName System.Net.Http.HttpClientHandler -Property @{UseCookies = $false} | |
$client = New-Object -TypeName System.Net.Http.HttpClient($handler) -Property @{BaseAddress = $Uri} | |
if ($null -ne $Cookie -and $Cookie.Length -gt 0) | |
{ | |
$client.DefaultRequestHeaders.Add('Cookie', $Cookie) | |
} | |
$client.GetAsync($Uri, [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead) |% { | |
$_.Wait() | |
$response = $_.Result | |
Write-Verbose -Message "Status: $($response.StatusCode)" | |
if ($response.StatusCode -eq 'Redirect') | |
{ | |
$ret = Get-WebFile -Uri $response.Headers.Location.OriginalString -OutFile $OutFile -Cookie $Cookie -BufferSize $BufferSize | |
} | |
elseif ($response.StatusCode -eq 'OK' -and $null -ne $response.Content.Headers.ContentLength) | |
{ | |
$contentStream = $response.Content.ReadAsStreamAsync() | |
$contentStream.Wait() | |
$totalRead = 0 | |
$totalReads = 0 | |
$buffer = New-Object -TypeName byte[] -ArgumentList $BufferSize | |
$isMoreToRead = $true | |
$downloadedFileStream = New-Object -TypeName System.IO.FileStream($OutFile, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::None, $BufferSize, $true) | |
do | |
{ | |
$read = $contentStream.Result.ReadAsync($buffer, 0, $BufferSize) | |
if ($read.Result -eq 0) | |
{ | |
$isMoreToRead = $false | |
$downloadedFileStream.Close() | |
} | |
else | |
{ | |
$downloadedFileStream.WriteAsync($buffer, 0, $read.Result) | Out-Null | |
$totalRead += $read.Result | |
$totalReads += 1 | |
$percentage = $totalRead / $response.Content.Headers.ContentLength * 100 | |
Write-Progress -Activity 'Writing web request' -status "Writing request stream... (Number of bytes written: $totalRead/$($response.Content.Headers.ContentLength)) = $percentage%" -PercentComplete $percentage | |
} | |
} while ($isMoreToRead) | |
$ret = $true | |
} | |
else | |
{ | |
Write-Error -Message 'Unable to continue. No redirect, or OK status with file size returned.' | |
} | |
} | |
$client.Dispose() | |
$client = $null | |
$handler.Dispose() | |
$handler = $null | |
} | |
if ($null -ne $Hash -and $Hash.Length -gt 0) | |
{ | |
$fileHash = Get-FileHash -Path $OutFile -Algorithm $Algorithm | |
if ($fileHash.Hash -eq $Hash) | |
{ | |
$ret = $true | |
} | |
else | |
{ | |
Write-Error -Message "File hash does not match. Expected [$Hash], got [$($fileHash.Hash)]." | |
$ret = $false | |
} | |
} | |
$ret | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment