0

I've tried this answer but it is for Azure Table Storage, how do I retrive a blob from Azure storage with Powershell but without the use of the Azure Powershell Module? In the documentation it says that I should create a string from

StringToSign = VERB + "\n" +  
           Content-MD5 + "\n" +  
           Content-Type + "\n" +  
           Date + "\n" +  
           CanonicalizedHeaders +   
           CanonicalizedResource;

but when I add those to the function previously mentioned, it still doesn't work, what do I do wrong?

1 Answer 1

0

Turns out there is a little mistake in the docs, you need a newline after CanonicalizedHeaders as well, even if the docs says otherwise. If you read carefully the next code example in the docs they actually have that newline there:

PUT\n\ntext/plain; charset=UTF-8\n\nx-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n/testaccount1/mycontainer/hello.txt

Anyway, here is a fully functioning script to get a blob from Azure Blob Storage:

function GenerateHeader(
    [string]$accountName,
    [string]$accountKey,
    [string]$verb,
    [string]$resource)
{
    $xmsversion = '2015-02-21'
    $xmsdate = Get-Date
    $xmsdate = $xmsdate.ToUniversalTime()
    $xmsdate = $xmsdate.toString('R')

    $newLine = "`n";

    $contentType = 'application/json'

    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Content-Type", $contentType)
    $headers.Add("x-ms-date", $xmsdate)
    $headers.Add("x-ms-version", $xmsversion)

    $canonicalizedHeaders = "x-ms-date:$xmsdate"+$newLine+"x-ms-version:$xmsversion"
    $canonicalizedResource = $resource

    $stringToSign = $verb.ToUpper() + $newLine +`
                $contentMD5 + $newLine +`
                $contentType + $newLine +`
                $dateHeader + $newLine +`
                $canonicalizedHeaders + $newLine +`
                $canonicalizedResource;

    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.key = [Convert]::FromBase64String($accountKey)
    $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
    $signature = [Convert]::ToBase64String($signature)
    $headers.Add("Authorization", "SharedKeyLite " + $accountName + ":" + $signature)

    return $headers
}

$accountName = ''
$accountKey = ''
$container = ''
$fileName = ''

$blobUri = "https://$accountName.blob.core.windows.net/$container/$fileName"
$outputPath = "$PSScriptRoot\$fileName"
$headers = GenerateHeader $accountName $accountKey 'GET' "/$accountName/$container/$fileName"

$webClient = New-Object System.Net.WebClient

foreach ($key in $headers.Keys)
{
    $webClient.Headers.Add($key, $headers[$key])
}

$start_time = Get-Date
$webClient.DownloadFile($blobUri, $outputPath)
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)"
Write-Output $stringToSign
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.