Get-RemoteFile.ps1
<#PSScriptInfo
.VERSION 1.0.1 .AUTHOR kalichuza .GUID abc12345-6789-0123-4567-abcdef123456 .COMPANYNAME .COPYRIGHT (c) 2024 kalichuza. All rights reserved. .TAGS Download, File, Hash .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .REQUIREDSCRIPTS .ATTACHEDFILES .RELEASENOTES Initial release .DESCRIPTION Downloads a file from a provided URL to a path. Can compare the hash and automatically remove the failed download. UserName and Password can be used for URLs that require basic authentication. #> #Requires -Version 2.0 <# .SYNOPSIS Downloads a file from a provided URL to a path. .EXAMPLE -Url "https://www.google.com/" -FilePath "C:\temp\index.html" Downloads the index html page from google.com to C:\temp\index.html .EXAMPLE -Url "https://www.nirsoft.net/utils/advancedrun.zip" -FilePath "C:\temp\advancedrun.zip" -Hash "b2c65aa6e71b0f154c5f3a8b884582779d716ff2c03d6cdca9e157f0fe397c9c" -Algorithm SHA256 Downloads the advancedrun.zip file from nirsoft to C:\temp\advancedrun.zip and validates that the SHA256 hash matches. .EXAMPLE -Url "https://www.nirsoft.net/utils/advancedrun.zip" -FilePath "C:\temp\advancedrun.zip" -Hash "b2c65aa6e71b0f154c5f3a8b884582779d716ff2c03d6cdca9e157f0fe397c9c" -AutoRemove Downloads the advancedrun.zip file from nirsoft to C:\temp\advancedrun.zip and validates that the SHA256 hash matches. If the hash does not match, the file will be removed. Not specifying Algorithm defaults to SHA256. .OUTPUTS String[] .NOTES Minimum OS Architecture Supported: Windows 7, Windows Server 2008 R2 Release Notes: Initial Release .COMPONENT Download #> [CmdletBinding()] param ( # Url that will be used to download a file [Parameter(Mandatory = $true)] [string]$Url, # File path that the file will be placed [Parameter(Mandatory = $true)] [string]$FilePath, # Expected hash of downloaded file [Parameter()] [string]$Hash, # Hashing Algorithm to use for hash comparison [Parameter()][ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MD5")] [string]$Algorithm = "SHA256", # Removes failed download automatically [Parameter()] [switch]$AutoRemove, # UserName [Parameter()] [string]$UserName, # Password [Parameter()] [string]$Password ) # For PowerShell 2.0 and 3.0 compatibility if ($PSVersionTable.PSVersion.Major -lt 4) { function Get-FileHash { param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string[]]$Path, [Parameter(Mandatory = $false)] [ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MD5")] [string]$Algorithm = "SHA256" ) $Path | ForEach-Object { # Only hash files that exist $CurrentPath = $_ if ($(Test-Path -Path $CurrentPath -ErrorAction SilentlyContinue)) { $HashAlgorithm = New-Object -TypeName System.Security.Cryptography.$($Algorithm)CryptoServiceProvider $Hash = [System.BitConverter]::ToString($hashAlgorithm.ComputeHash([System.IO.File]::ReadAllBytes($CurrentPath))) @{ Algorithm = $Algorithm Path = $Path Hash = $Hash.Replace('-', '') } } } } } # For PowerShell 2.0 compatibility if ($PSVersionTable.PSVersion.Major -le 2) { $client = New-Object System.Net.WebClient if ($PSBoundParameters.ContainsKey("UserName") -and $PSBoundParameters.ContainsKey("Password")) { $client.Credentials = New-Object System.Net.NetworkCredential($UserName, $(ConvertTo-SecureString -String $Password -AsPlainText -Force)) } elseif ( ($PSBoundParameters.ContainsKey("UserName") -and -not $PSBoundParameters.ContainsKey("Password")) -or (-not $PSBoundParameters.ContainsKey("UserName") -and $PSBoundParameters.ContainsKey("Password")) ) { Write-Error "UserName and Password parameters have to be used together." exit 1 } try { if ($null -ne $FilePath) { $client.DownloadFile($Url, $FilePath) } else { # Similar functionality to Invoke-WebRequest if -OutFile was not used, null, or an empty string # Defaults to the current directory $client.DownloadFile($Url, ".\") } } catch { Write-Error $_ Write-Host "System.Net.WebClient Failed to download from $Url to $FilePath" exit 1 } } else { $Splat = @{ Uri = $Url OutFile = $FilePath Credential = if ($PSBoundParameters.ContainsKey("UserName") -and $PSBoundParameters.ContainsKey("Password")) { New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName, $SecureString } else { $null } } try { Invoke-WebRequest @Splat } catch { Write-Error $_ Write-Host "Invoke-WebRequest failed to download from $Url to $FilePath" exit 1 } } Write-Host "Computing hash using $Algorithm" $ComputedHash = $(Get-FileHash -Path $FilePath -Algorithm $Algorithm).Hash Write-Host "Computed hash for $FilePath is $ComputedHash" if ($PSBoundParameters.ContainsKey("Hash")) { if ($ComputedHash -like $Hash) { Write-Host "$FilePath hash matched!" } else { Write-Error "$FilePath hash did not match!" Write-Host "Computed hash of $FilePath was:" Write-Host "$ComputedHash" Write-Host "Expected hash was:" Write-Host "$Hash" if ($AutoRemove) { Write-Host "Removing failed download." try { # This should always remove the file Remove-Item $Path -Force -Confirm:$false -ErrorAction SilentlyContinue Write-Host "Removed failed download." } catch { if ($(Test-Path -Path $Path -ErrorAction SilentlyContinue)) { Write-Host "Failed to remove failed download." } else { Write-Host "Removed failed download." } } } exit 1 } } |