Skip to content

Instantly share code, notes, and snippets.

@jschlackman
Forked from MattHodge/Save-Download.ps1
Created May 18, 2022 16:14
Show Gist options
  • Save jschlackman/e8b80442a76ded45ec4ae2c26f43f691 to your computer and use it in GitHub Desktop.
Save jschlackman/e8b80442a76ded45ec4ae2c26f43f691 to your computer and use it in GitHub Desktop.
Save-Download.ps1
function Save-Download {
<#
.SYNOPSIS
Given either the result of WebResponseObject or a Uri, will download the file to disk without having to specify a name.
.DESCRIPTION
Given either the result of WebResponseObject or a Uri, will download the file to disk without having to specify a name.
.PARAMETER WebResponse
A WebResponseObject from running an Invoke-WebRequest on a file to download.
.PARAMETER Uri
Uri of a file to download in lieu of supplying a WebResponseObject.
.PARAMETER Directory
Directory to save download into. Defaults to the current working directory.
.EXAMPLE
# Download Microsoft Edge
$download = Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2109047&Channel=Stable&language=en&consent=1"
$download | Save-Download
#>
[CmdletBinding(DefaultParameterSetName = 'Uri')]
param (
[Parameter(Mandatory = $true, ValueFromPipeline, ParameterSetName = 'WebResponse')]
[Microsoft.PowerShell.Commands.WebResponseObject]
$WebResponse,
[Parameter(Mandatory = $true, ParameterSetName = 'Uri')]
[string]
$Uri,
[Parameter(Mandatory = $false)]
[string]
$Directory = (Get-Location).Path
)
If ($PSCmdlet.ParameterSetName -eq 'Uri') {
do {
$WebResponse = Invoke-WebRequest -Uri $Uri -UserAgent 'Mozilla/5.0' -MaximumRedirection 0 -ErrorAction:SilentlyContinue
If ([bool]$WebResponse.Headers.Location) {
$Uri = $WebResponse.Headers.Location
Write-Verbose "Redirected to: $Uri"
}
} until (!$WebResponse.Headers.Location)
}
$errorMessage = "Cannot determine filename for download."
if (!($WebResponse.Headers.ContainsKey("Content-Disposition"))) {
If ($Uri) {
Write-Verbose "No content disposition header, using filename from Uri"
$fileName = Split-Path -Path $Uri -Leaf
}
else {
$fileName = ''
}
}
else
{
$content = [System.Net.Mime.ContentDisposition]::new($WebResponse.Headers["Content-Disposition"])
$fileName = $content.FileName
}
if (!$fileName) {
Write-Error $errorMessage -ErrorAction Stop
}
if (!(Test-Path -Path $Directory)) {
New-Item -Path $Directory -ItemType Directory
}
$fullPath = Join-Path -Path $Directory -ChildPath $fileName
Write-Verbose "Downloading to $fullPath"
$file = [System.IO.FileStream]::new($fullPath, [System.IO.FileMode]::Create)
$file.Write($WebResponse.Content, 0, $WebResponse.RawContentLength)
$file.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment