【问题标题】:Use Powershell to get blob from Azure Storage without using the Azure PowerShell module使用 Powershell 从 Azure 存储中获取 blob,而不使用 Azure PowerShell 模块
【发布时间】:2019-02-06 13:33:14
【问题描述】:
我已经尝试过this answer,但它适用于 Azure 表存储,我如何使用 Powershell 但不使用 Azure Powershell 模块从 Azure 存储中检索 blob?在documentation 中,它说我应该从
创建一个字符串
StringToSign = VERB + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedHeaders +
CanonicalizedResource;
但是当我将这些添加到前面提到的功能中时,它仍然不起作用,我做错了什么?
【问题讨论】:
标签:
azure
powershell
azure-blob-storage
【解决方案1】:
事实证明文档中有一个小错误,即使文档另有说明,您也需要在 CanonicalizedHeaders 之后换行。如果您仔细阅读文档中的下一个代码示例,他们实际上在那里有换行符:
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
无论如何,这是一个从 Azure Blob 存储中获取 Blob 的功能齐全的脚本:
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