ThePirateRay/scripts/materialize_private_drive_files.ps1

61 lines
2.1 KiB
PowerShell

[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$Root,
[Parameter(Mandatory = $false)]
[string]$RequestBase64
)
$ErrorActionPreference = 'Stop'
$rootPath = (Resolve-Path -LiteralPath $Root).Path
$rootPrefix = $rootPath.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
function Receive-Artifact {
param([Parameter(Mandatory = $true)]$Item)
$item = $Item
if (-not $item.relative_path -or -not $item.download_url) {
throw 'Each input line must contain relative_path and download_url.'
}
$relativePath = $item.relative_path.Replace('/', [IO.Path]::DirectorySeparatorChar)
$destination = [IO.Path]::GetFullPath((Join-Path $rootPath $relativePath))
if (-not $destination.StartsWith($rootPrefix, [StringComparison]::OrdinalIgnoreCase)) {
throw "Refusing path outside acquisition root: $($item.relative_path)"
}
$parent = Split-Path -Parent $destination
New-Item -ItemType Directory -Path $parent -Force | Out-Null
Invoke-WebRequest -UseBasicParsing -Uri $item.download_url -OutFile $destination
$actualSize = (Get-Item -LiteralPath $destination).Length
if ($null -ne $item.expected_size -and $actualSize -ne [long]$item.expected_size) {
throw "Size mismatch for $($item.relative_path): expected $($item.expected_size), got $actualSize"
}
if ($item.expected_sha256) {
$actualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $destination).Hash.ToLowerInvariant()
if ($actualHash -ne $item.expected_sha256.ToLowerInvariant()) {
throw "SHA-256 mismatch for $($item.relative_path)"
}
}
Write-Output ("OK`t{0}`t{1}" -f $actualSize, $item.relative_path)
}
if ($RequestBase64) {
$json = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($RequestBase64))
Receive-Artifact -Item ($json | ConvertFrom-Json)
exit 0
}
while (($line = [Console]::In.ReadLine()) -ne $null) {
if ($line -eq '__END__') {
break
}
if ([string]::IsNullOrWhiteSpace($line)) {
continue
}
Receive-Artifact -Item ($line | ConvertFrom-Json)
}