microsoft/hve-core
Publicmirrored fromhttps://github.com/microsoft/hve-coreAvailable
scripts/lib/Get-VerifiedDownload.ps1
124lines · modecode
| 1 | <# |
| 2 | .SYNOPSIS |
| 3 | Downloads and verifies artifacts using SHA256 checksums. |
| 4 | |
| 5 | .DESCRIPTION |
| 6 | Securely downloads files from URLs and verifies their integrity using |
| 7 | SHA256 checksums before saving or extracting. |
| 8 | |
| 9 | .PARAMETER Url |
| 10 | URL to download from. |
| 11 | |
| 12 | .PARAMETER ExpectedSHA256 |
| 13 | Expected SHA256 checksum of the file. |
| 14 | |
| 15 | .PARAMETER OutputPath |
| 16 | Path where the downloaded file will be saved. |
| 17 | |
| 18 | .PARAMETER Extract |
| 19 | Extract the archive after verification. |
| 20 | |
| 21 | .PARAMETER ExtractPath |
| 22 | Destination directory for extraction. |
| 23 | |
| 24 | .EXAMPLE |
| 25 | Get-VerifiedDownload -Url "https://example.com/tool.tar.gz" -ExpectedSHA256 "abc123..." -OutputPath "./tool.tar.gz" |
| 26 | |
| 27 | .EXAMPLE |
| 28 | Get-VerifiedDownload -Url "https://example.com/tool.tar.gz" -ExpectedSHA256 "abc123..." -OutputPath "./tool.tar.gz" -Extract -ExtractPath "./tools" |
| 29 | #> |
| 30 | |
| 31 | [CmdletBinding()] |
| 32 | param( |
| 33 | [Parameter(Mandatory = $true)] |
| 34 | [string]$Url, |
| 35 | |
| 36 | [Parameter(Mandatory = $true)] |
| 37 | [string]$ExpectedSHA256, |
| 38 | |
| 39 | [Parameter(Mandatory = $true)] |
| 40 | [string]$OutputPath, |
| 41 | |
| 42 | [Parameter(Mandatory = $false)] |
| 43 | [switch]$Extract, |
| 44 | |
| 45 | [Parameter(Mandatory = $false)] |
| 46 | [string]$ExtractPath |
| 47 | ) |
| 48 | |
| 49 | $ErrorActionPreference = 'Stop' |
| 50 | |
| 51 | if ($Extract -and -not $ExtractPath) { |
| 52 | $ExtractPath = Split-Path -Path $OutputPath -Parent |
| 53 | if (-not $ExtractPath) { |
| 54 | $ExtractPath = $PWD.Path |
| 55 | } |
| 56 | Write-Verbose "ExtractPath not specified, defaulting to: $ExtractPath" |
| 57 | } |
| 58 | |
| 59 | $tempFile = [System.IO.Path]::GetTempFileName() |
| 60 | |
| 61 | try { |
| 62 | Write-Host "Downloading: $Url" |
| 63 | Invoke-WebRequest -Uri $Url -OutFile $tempFile -UseBasicParsing |
| 64 | |
| 65 | Write-Host "Verifying SHA256: $ExpectedSHA256" |
| 66 | $actualHash = (Get-FileHash -Path $tempFile -Algorithm SHA256).Hash |
| 67 | |
| 68 | if ($actualHash -ne $ExpectedSHA256.ToUpper()) { |
| 69 | throw "Checksum verification failed!`nExpected: $ExpectedSHA256`nActual: $actualHash" |
| 70 | } |
| 71 | |
| 72 | if ($Extract -and $ExtractPath) { |
| 73 | Write-Host "Extracting to: $ExtractPath" |
| 74 | if (-not (Test-Path $ExtractPath)) { |
| 75 | New-Item -ItemType Directory -Path $ExtractPath -Force | Out-Null |
| 76 | } |
| 77 | |
| 78 | switch -Regex ($Url) { |
| 79 | '\.zip$' { |
| 80 | Write-Verbose "Extracting ZIP archive to $ExtractPath" |
| 81 | Expand-Archive -Path $tempFile -DestinationPath $ExtractPath -Force |
| 82 | } |
| 83 | '\.(tar\.gz|tgz)$' { |
| 84 | $tarCmd = Get-Command -Name 'tar' -ErrorAction SilentlyContinue |
| 85 | if (-not $tarCmd) { |
| 86 | throw "tar command not available for .tar.gz extraction" |
| 87 | } |
| 88 | Write-Verbose "Extracting tar.gz archive to $ExtractPath" |
| 89 | tar -xzf $tempFile -C $ExtractPath |
| 90 | if ($LASTEXITCODE -ne 0) { |
| 91 | throw "tar extraction failed with exit code $LASTEXITCODE" |
| 92 | } |
| 93 | } |
| 94 | '\.tar$' { |
| 95 | $tarCmd = Get-Command -Name 'tar' -ErrorAction SilentlyContinue |
| 96 | if (-not $tarCmd) { |
| 97 | throw "tar command not available for .tar extraction" |
| 98 | } |
| 99 | Write-Verbose "Extracting tar archive to $ExtractPath" |
| 100 | tar -xf $tempFile -C $ExtractPath |
| 101 | if ($LASTEXITCODE -ne 0) { |
| 102 | throw "tar extraction failed with exit code $LASTEXITCODE" |
| 103 | } |
| 104 | } |
| 105 | default { |
| 106 | throw "Unsupported archive format for '$Url'. Supported: .zip, .tar.gz, .tgz, .tar" |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | else { |
| 111 | $outputDir = Split-Path -Parent $OutputPath |
| 112 | if ($outputDir -and -not (Test-Path $outputDir)) { |
| 113 | New-Item -ItemType Directory -Path $outputDir -Force | Out-Null |
| 114 | } |
| 115 | Move-Item -Path $tempFile -Destination $OutputPath -Force |
| 116 | } |
| 117 | |
| 118 | Write-Host "Download verified and complete" -ForegroundColor Green |
| 119 | } |
| 120 | finally { |
| 121 | if (Test-Path $tempFile) { |
| 122 | Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue |
| 123 | } |
| 124 | } |
| 125 | |