...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
# inspired by: # https://stackoverflow.com/questions/53653473/generating-an-sas-token-in-java-to-download-a-file-in-an-azure-data-storage-cont?rq=1 # https://purple.telstra.com.au/blog/loading-and-querying-data-in-azure-table-storage-using-powershell # https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key function Create-Signature( [string] $Operation, [string] $Container, [string] $Blob, [string] $Account, [string] $AccessKey, [string] $Version, [DateTime] $Now, [int] $ContentLength=-1 ) { [Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null if ( $ContentLength -gt -1 ) { $contentLengthValue = $ContentLength } else { $contentLengthValue = '' } $partToSign = "`n" ` + "`n" ` + "`n" ` + $contentLengthValue + "`n" ` + "`n" ` + "`n" ` + "`n" ` + "`n" ` + "`n" ` + "`n" ` + "`n" ` + "`n" ` + "x-ms-blob-type:BlockBlob" + "`n" ` + "x-ms-date:$(Get-Date (Get-Date $Now).ToUniversalTime() -Format 'R')" + "`n" ` + "x-ms-version:$Version" + "`n" switch ( $Operation ) { 'GET' { $stringToSign = 'GET' ` + $partToSign ` + "/$Account/$Container/$Blob" break } 'PUT' { $stringToSign = 'PUT' ` + $partToSign ` + "/$Account/$Container/$Blob" break } 'LIST' { $stringToSign = "GET" ` + $partToSign ` + "/$Account/$Container" + "`n" ` + "comp:list" + "`n" ` + "restype:container" break } default { throw "invalid operation: $Operation" } } $hmac = New-Object System.Security.Cryptography.HMACSHA256 $hmac.key = [Convert]::FromBase64String( $AccessKey ) $signature = $hmac.ComputeHash( [Text.Encoding]::UTF8.GetBytes( $stringToSign ) ) $signature = [Convert]::ToBase64String( $signature ) Write-Debug "container: $Container" Write-Debug "Accoount: $Account" Write-Debug "AccessKey: $AccessKey" Write-Debug "stringToSign: $stringToSign" $signature } function Invoke-BlobRequest( [Uri] $Uri, [string] $Account, [string] $Signature, [DateTime] $Now, [string] $Version, [string] $Method='GET', [string] $FilePath='' ) { $requestParams = @{} $requestParams.Add( 'Uri', $Uri ) $requestParams.Add( 'Method', $Method ) if ( $FilePath ) { $requestParams.Add( 'Infile', $FilePath ) } $requestParams.Add( 'Headers', @{ ` 'x-ms-blob-type' = 'BlockBlob'; ` 'x-ms-date' = "$(Get-Date (Get-Date $Now).ToUniversalTime() -Format 'R')"; ` 'x-ms-version' = $Version; ` 'Authorization' = "SharedKey $($Account):$($Signature)" ` } ` ) Write-Debug ".... Invoke-WebRequest: $Uri" $requestParams.Keys | % { if ( $_ -eq 'Headers' ) { $item = $_ $requestParams.Item($_).Keys | % { Write-Debug "...... Headers $_ : $($requestParams.Item($item).Item($_))" } } else { Write-Debug "...... $_ $($requestParams.Item($_))" } } # run the web service request $response = Invoke-WebRequest @requestParams $response } # ---------- ---------- ---------- # Main # ---------- ---------- ---------- $ownerAccount = '<storage account>' $ownerAccessKey = '<storage account access key>' $requesterAccount = '<requester account>' $version = '2019-10-10' # consider badly synchronized server time and start 3 minutes in the past $now = (Get-Date).ToUniversalTime().AddMinutes(-3) Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# List Blobs in Container" Write-Host "# ++++++++++++++++++++++++++++++" # step 1: create signature $container = 'yade' $signature = Create-Signature -Operation 'LIST' -Container $container -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now Write-Debug "Signature: $signature" # step 2: send web service request $uri = "https://$($ownerAccount).blob.core.windows.net/$($container)?restype=container&comp=list" $response = Invoke-BlobRequest -Uri $uri -Account $requesterAccount -Signature $signature -Now $now -Version $version -Method 'GET' Write-Host "Status Code: $($response.StatusCode)" Write-Host $response.Content Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# Get Blob from Container" Write-Host "# ++++++++++++++++++++++++++++++" # step 1: create signature $container = 'yade' $blob = 'test.txt' $signature = Create-Signature -Operation 'GET' -Container $container -Blob $blob -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now Write-Debug "Signature: $signature" # step 2: send web service request $uri = "https://$($ownerAccount).blob.core.windows.net/$($container)/$($blob)" $response = Invoke-BlobRequest -Uri $uri -Account $requesterAccount -Signature $signature -Now $now -Version $version -Method 'GET' Write-Host "Status Code: $($response.StatusCode)" Write-Host $response.Content Write-Host "`n" Write-Host "# ++++++++++++++++++++++++++++++" Write-Host "# Write Blob to Container" Write-Host "# ++++++++++++++++++++++++++++++" # step 1: create signature $container = 'yade' $filePath = "c:/tmp/some_blob.txt" $blob = (Get-Item $filePath).Name $signature = Create-Signature -Operation 'PUT' -Container $container -Blob $blob -Account $ownerAccount -AccessKey $ownerAccessKey -Version $version -Now $now -ContentLength (Get-Content $filePath -Raw).length Write-Debug "Signature: $signature" # step 2: send web service request $uri = "https://$($ownerAccount).blob.core.windows.net/$($container)/$($blob)" $response = Invoke-BlobRequest -Uri $uri -Account $requesterAccount -Signature $signature -Now $now -Version $version -Method 'PUT' -FilePath $filePath Write-Host "Status Code: $($response.StatusCode)" Write-Host $response.Content |
...