代码之家  ›  专栏  ›  技术社区  ›  Oskar

使用Powershell从Azure存储获取blob,而不使用Azure Powershell模块

  •  0
  • Oskar  · 技术社区  · 6 年前

    我试过了 this answer 但它是针对Azure表存储的,如何使用Powershell从Azure存储中检索blob,但不使用Azure Powershell模块?在 documentation 它说我应该从中创建一个字符串

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   Oskar    6 年前

    原来文档中有一个小错误,你需要在之后换行 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