Skip to content

Instantly share code, notes, and snippets.

@snydergd
Last active November 3, 2022 13:45
Show Gist options
  • Save snydergd/a8ff2a3e3d61cca86fdd9faf1f7e892f to your computer and use it in GitHub Desktop.
Save snydergd/a8ff2a3e3d61cca86fdd9faf1f7e892f to your computer and use it in GitHub Desktop.
download-docker-info.ps1
param(
[Parameter(Mandatory=$true)]$image,
$tag = "latest",
$registry = "registry.hub.docker.com",
$outputFolder = "C:\temp\dockerStuff"
)
try {
invoke-restmethod "https://$registry/v2/$image/manifests/$tag"
} catch {
$match = [regex]::Matches($_.Exception.Response.Headers['WWW-Authenticate'], 'Bearer([ ,](?<name>[^=]+)="(?<value>[^"]+)")+')
$keys = @{}
$names = $match.groups | ? 'name' -eq 'name' | % captures
$values = $match.groups | ? 'name' -eq 'value' | % captures
0..$($names.count-1) | % { $keys[$names[$_].value] = $values[$_].value}
$keys
$url = $keys['realm'] + "?service=" + $keys["service"] + "&scope=" + $keys["scope"]
echo $url
$cred = Get-Credential
$token = invoke-restmethod $url -UseBasicParsing -Headers @{
"Authorization" = "Basic $([convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($cred.GetNetworkCredential().UserName + ":" + $cred.GetNetworkCredential().Password)))"
} | % token
$token
}
$manifest = Invoke-WebRequest "https://$registry/v2/$image/manifests/$tag" -UseBasicParsing -Headers @{
"Authorization" = "Bearer $token"
"Accept" = @(
"application/vnd.oci.image.index.v1+json",
"application/vnd.docker.distribution.manifest.v1+prettyjws",
"application/json",
"application/vnd.oci.image.manifest.v1+json",
"application/vnd.docker.distribution.manifest.v2+json",
"application/vnd.docker.distribution.manifest.list.v2+json"
) -join ","
}
[System.text.encoding]::ASCII.getString($manifest.content) | convertfrom-json | convertto-json -depth 20
$manifest.headers
$manifestListDigest = $manifest.headers.'Docker-Content-Digest'
$manifestList = Invoke-WebRequest "https://$registry/v2/$image/manifests/$manifestListDigest" -UseBasicParsing -Headers @{
"Authorization" = "Bearer $token"
}
$manifestList.headers
if ($manifestList.headers['Content-Type'] -eq "application/vnd.docker.distribution.manifest.v2+json") {
$manifest = [System.text.encoding]::ASCII.getString($manifestList.content) | convertfrom-json
} else {
throw "Unkown response type (maybe a list) for tag manifest"
}
$manifest | convertto-json -depth 20
rm -recurse -force $outputFolder
mkdir $outputFolder
$configDigest = $manifest.config.digest
[System.Text.Encoding]::UTF8.getString($(Invoke-WebRequest "https://$registry/v2/$image/blobs/$configDigest" -Headers @{
"Authorization" = "Bearer $token"
}).content) | convertfrom-json | convertto-json -depth 20 > "$outputFolder\config.json"
0..$($manifest.layers.count-1) | % {
$blobDigest = $manifest.layers[$_].digest
Invoke-WebRequest "https://$registry/v2/$image/blobs/$blobDigest" -Headers @{
"Authorization" = "Bearer $token"
} -outfile "$outputFolder\layer$_.tar.gz"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment