Use Powershell to get blob from Azure Storage without using the Azure PowerShell module - azure

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?

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

Related

How to use maxresult and nextmarker parameter in Azure File Share List REST API

I am trying to list all the shares present in Storage Account using List Share REST API (https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares#Authorization). but I am having issues with Authorization header with marker parameter. I guess problem is with $stringtosign variable under $nextmarker If Statement.
$StorageAccount = "XXXXX"
$Accesskey = "XXXXXXX==";
$Version="2019-12-12"
$SharePropObj = #()
$date = [System.DateTime]::UtcNow.ToString("R",[Globalization.CultureInfo]::InvariantCulture)
$stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`n"+
"x-ms-date:$date`nx-ms-version:$version`n" +
"/$storageAccount/`ncomp:list`nmaxresults:5000"
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)
$headers=#{"x-ms-date"=$date;
"x-ms-version"= $version;
"Authorization"= "SharedKey $($storageAccount):$signature";
"ContentType"="application/xml"
}
$URI = "https://$storageAccount.file.core.windows.net/?comp=list&maxresults=5000"
Try {
$response = Invoke-RestMethod $URI -Method 'GET' -Headers $headers
}Catch {
"Error Occurred. $_.exception.message"
}
If ($response){
[xml]$Result = [xml]($response -replace '',"")
$Shareprops = $Result.EnumerationResults.ChildNodes.share | %{
$share = $_.Name
$Quota = $_.properties.Quota
"$share,$Quota"
}
$SharePropCol = "ShareName,Quota"
$SharePropObj += #($SharePropCol,($Shareprops | where {$_.length -gt 1})) | ConvertFrom-Csv -Delimiter ","
$SharePropObj
$NextMarker = $Result.EnumerationResults.NextMarker.Split("/")[-1]
if ($NextMarker){
#Write-Error "Data for some shares are missed"
#$SharePropObj = #()
$date = [System.DateTime]::UtcNow.ToString("R",[Globalization.CultureInfo]::InvariantCulture)
$stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`n"+
"x-ms-date:$date`nx-ms-version:$version`n" +
"/$storageAccount/`ncomp:list`nmaxresults:5000`nmarker:$NextMarker"
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)
$headers=#{"x-ms-date"=$date;
"x-ms-version"= $version;
"Authorization"= "SharedKey $($storageAccount):$signature";
"ContentType"="application/xml"
}
$URI = "https://$storageAccount.file.core.windows.net/?comp=list&maxresults=5000&marker=$NextMarker"
$response1 = Invoke-RestMethod $URI -Method 'GET' -Headers $headers
[xml]$Result = [xml]($response1 -replace '',"")
$Shareprops = $Result.EnumerationResults.ChildNodes.share | %{
$share = $_.Name
$Quota = $_.properties.Quota
"$share,$Quota"
}
$SharePropCol = "ShareName,Quota"
$SharePropObj += #($SharePropCol,($Shareprops | where {$_.length -gt 1})) | ConvertFrom-Csv -Delimiter ","
$SharePropObj
}
}
Please change the following code of yours:
1.for $NextMarker, please change this line of code
$NextMarker = $Result.EnumerationResults.NextMarker.Split("/")[-1]
to
$NextMarker = "/$storageAccount/" + $Result.EnumerationResults.NextMarker.Split("/")[-1]
in the if ($NextMarker){} code block -> for the $stringToSign, please place the marker:$NextMarker prior to maxresults:5000. Change it like below:
$stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`n"+
"x-ms-date:$date`nx-ms-version:$version`n" +
"/$storageAccount/`ncomp:list`nmarker:$NextMarker`nmaxresults:5000".
3.in the if ($NextMarker){} code block -> for $URI, please also place the marker=$NextMarker prior to maxresults=5000. Change it like below:
$URI = "https://$storageAccount.file.core.windows.net/?comp=list&marker=$NextMarker&maxresults=5000"
I have tested it and it works fine. Please let me know if you still have the issue.

MAC Signature Not Same Error While Accessing Storage REST API

I trying to call the storage REST API using powershell but facing errors. PFB details-
Script
$version = "2017-04-17"
$storageAccount = "{storageAccountName}"
$accesskey= “{storageAccountAccessKey}"
$resource = "?comp=list"
$storage_url = "https://$storageAccount.blob.core.windows.net/$resource"
$GMTTime = (Get-Date).ToUniversalTime().toString('R')
$stringToSign = "GET`nx-ms-date:$GMTTime`nx-ms-version:2017-04-17`n/$storageAccount/$resource"
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)
$headers = #{
'x-ms-date' = $GMTTime
'Authorization' = "SharedKeyLite " + $storageAccount + ":" + $signature
'x-ms-version' = $version
}
Invoke-RestMethod -Method GET -Uri $storage_url -Headers $headers
Error Message
Invoke-RestMethod : AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the
signature.
RequestId:ee5459f7-501e-004b-0426-46de36000000
Time:2020-06-19T10:45:36.7846714ZThe MAC signature found in the HTTP request <signature>' is not the same as any computed signature.
Server used following string to sign: 'GET
x-ms-date:Fri, 19 Jun 2020 10:37:00 GMT
x-ms-version:2017-04-17
/<storageAccount>/?comp=list'.
Can someone please help me understand what is missing here.
Documentation being followed for authorization- https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key
Please use the following code:
$version = "2017-04-17"
$storageAccount = "{storageAccountName}"
$accesskey= “{storageAccountAccessKey}"
$resource = "?comp=list"
$storage_url = "https://$storageAccount.blob.core.windows.net/$resource"
$GMTTime = (Get-Date).ToUniversalTime().toString('R')
$ContentMd5 = ""
$ContentType = ""
$CanonicalizedHeaders = "x-ms-date:$GMTTime`nx-ms-version:$version`n"
$CanonicalizedResource = "/$storageAccount/$resource"
$stringToSign = "GET`n$ContentMd5`n$ContentType`n`n$CanonicalizedHeaders$CanonicalizedResource"
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)
$headers = #{
'x-ms-date' = $GMTTime
'Authorization' = "SharedKeyLite " + $storageAccount + ":" + $signature
'x-ms-version' = $version
}
Invoke-RestMethod -Method GET -Uri $storage_url -Headers $headers

Powershell HTTP Post to Service Bus Queue returns 401

Trying to submit a message to a service bus queue I have set up, and keep getting a 401 Unauthorized return.
I've tried configuring the SAS token myself using this method
$ResourceGroupName = 'myResourceGroup'
$NameSpaceName = "serviceBusNameSpace"
$QueueName = "myQueueName"
$PolicyName = "RootManageSharedAccessKey"
$body = "test message"
$Namespace = (Get-AzServiceBusNamespace -ResourceGroupName $ResourceGroupName -Name $namespacename).Name
$key = (Get-AzServiceBusKey -ResourceGroupName $ResourceGroupName -Namespace $namespacename -Name $PolicyName).PrimaryKey
$origin = [DateTime]"1/1/1970 00:00"
$Expiry = (Get-Date).AddMinutes(5)
#compute the token expiration time.
$diff = New-TimeSpan -Start $origin -End $Expiry
$tokenExpirationTime = [Convert]::ToInt32($diff.TotalSeconds)
#Create a new instance of the HMACSHA256 class and set the key to UTF8 for the size of $Key
$hmacsha = New-Object -TypeName System.Security.Cryptography.HMACSHA256
$hmacsha.Key = [Text.Encoding]::UTF8.GetBytes($Key)
$scope = "https://$Namespace.servicebus.windows.net/"
#create the string that will be used when cumputing the hash
$stringToSign = [Web.HttpUtility]::UrlEncode($scope) + "`n" + $tokenExpirationTime
#Compute hash from the HMACSHA256 instance we created above using the size of the UTF8 string above.
$hash = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
#Convert the hash to base 64 string
$signature = [Convert]::ToBase64String($hash)
$fullResourceURI = "https://$Namespace.servicebus.windows.net/$QueueName"
#create the token
$token = [string]::Format([Globalization.CultureInfo]::InvariantCulture, `
"SharedAccessSignature sr={0}sig={1}&se={2}&skn={3}", `
[Web.HttpUtility]::UrlEncode($fullResourceURI), `
[Web.HttpUtility]::UrlEncode($signature), `
$tokenExpirationTime, $PolicyName)
$headers = #{ "Authorization" = "$token"; "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" }
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$headers.Add("BrokerProperties", "{}")
#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing
I've also tried generating it through a built in cmdlet in Az.ServiceBus
$ResourceGroupName = 'myResourceGroup'
$NameSpaceName = "serviceBusNameSpace"
$QueueName = "myQueueName"
$PolicyName = "RootManageSharedAccessKey"
$body = "test message"
$expiry = (Get-Date).AddHours(2)
$authRule = Get-AzServiceBusAuthorizationRule -ResourceGroupName $ResourceGroupName -Namespace $NamespaceName
$token = New-AzServiceBusAuthorizationRuleSASToken -AuthorizationRuleId $authRule.Id -KeyType Primary -ExpiryTime $Expiry
$headers = #{ "Authorization" = "SharedAccessSignature $($token.SharedAccessSignature)"; "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" }
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$headers.Add("BrokerProperties", "{}")
#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing
Both give me a 401 unauthorized error
Invoke-WebRequest : The remote server returned an error: (401) Unauthorized.
At line:9 char:17
+ ... $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method Pos ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I'm not sure what else to do. Is there a setting I need to configure for my queue within the azure portal?
Have found solution. UTC time was originally expiring token before even sending, in addition to malformed SAS signature
Final code edit below
$key = (Get-AzServiceBusKey -ResourceGroupName $ResourceGroupName -Namespace $namespacename -Name $PolicyName).PrimaryKey
$origin = [DateTime]"1/1/1970 00:00"
$Expiry = (Get-Date).AddMinutes(20)
$Expiry = $Expiry.ToUniversalTime()
#compute the token expiration time.
$diff = New-TimeSpan -Start $origin -End $Expiry
$tokenExpirationTime = [Convert]::ToInt32($diff.TotalSeconds)
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$scope = "https://$Namespace.servicebus.windows.net/$QueueName"
#create the string that will be used when cumputing the hash
$stringToSign = [Web.HttpUtility]::UrlEncode($scope) + "`n" + $tokenExpirationTime
#Create a new instance of the HMACSHA256 class and set the key to UTF8 for the size of $Key
$hmacsha = New-Object -TypeName System.Security.Cryptography.HMACSHA256
$hmacsha.Key = [Text.Encoding]::UTF8.GetBytes($Key)
#Compute hash from the HMACSHA256 instance we created above using the size of the UTF8 string above.
$hash = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
#Convert the hash to base 64 string
$signature = [Convert]::ToBase64String($hash)
#create the token
$token = [string]::Format([Globalization.CultureInfo]::InvariantCulture, `
"SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", `
[Web.HttpUtility]::UrlEncode($scope), `
[Web.HttpUtility]::UrlEncode($signature), `
$tokenExpirationTime, $PolicyName)
$headers = #{ "Authorization" = "$token"}
$headers.Add("Content-Type", "application/atom+xml;type=entry;charset=utf-8")
#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing
I have made some changes in your script and it is working fine.
$ResourceGroupName = 'myResourceGroup'
$Namespace = "serviceBusNameSpace"
$QueueName = "myQueueName"
$PolicyName = "RootManageSharedAccessKey"
$body = "test message"
$key = (Get-AzServiceBusKey -ResourceGroupName $ResourceGroupName -Namespace $Namespace -Name $PolicyName).PrimaryKey
$origin = [DateTime]"1/1/1970 00:00"
$Expiry = (Get-Date).AddMinutes(5)
#compute the token expiration time.
$diff = New-TimeSpan -Start $origin -End $Expiry
$tokenExpirationTime = [Convert]::ToInt32($diff.TotalSeconds)
#Create a new instance of the HMACSHA256 class and set the key to UTF8 for the size of $Key
$hmacsha = New-Object -TypeName System.Security.Cryptography.HMACSHA256
$hmacsha.Key = [Text.Encoding]::UTF8.GetBytes($Key)
#create the string that will be used when cumputing the hash
$stringToSign = [Web.HttpUtility]::UrlEncode($Namespace) + "`n" + $tokenExpirationTime
#Compute hash from the HMACSHA256 instance we created above using the size of the UTF8 string above.
$hash = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
#Convert the hash to base 64 string
$signature = [Convert]::ToBase64String($hash)
#create the token
$token = [string]::Format([Globalization.CultureInfo]::InvariantCulture, `
"SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}", `
[Web.HttpUtility]::UrlEncode($Namespace), `
[Web.HttpUtility]::UrlEncode($signature), `
$tokenExpirationTime, $PolicyName)
$headers = #{ "Authorization" = "$token"; "Content-Type" = "application/atom+xml;type=entry;charset=utf-8" }
$uri = "https://$Namespace.servicebus.windows.net/$QueueName/messages"
$headers.Add("BrokerProperties", "{}")
#Invoke-WebRequest call.
Invoke-WebRequest -Uri $uri -Headers $headers -Method Post -Body $body -UseBasicParsing
The changes which I have made are:
You don't need to create scope variable. You need to pass the $Namespace to stringToSign.
You don't need to use Get-AzServiceBusNamespace to get namespace name as you are already taking this as user input.
See post edit.
Token expiration time wasn't converted to UTC, making it always expired, in addition to not having the SaS token configuration string formed correctly.

Unauthorized access while accessing Azure Cosmos DB to get specific document using Query in power shell

With reference to below link, i am trying to modify Github sample to get specific document by
providing query option in Body.
Link:
https://learn.microsoft.com/en-us/rest/api/cosmos-db/querying-cosmosdb-resources-using-the-rest-api
Github Sample:
https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/PowerShellRestApi/PowerShellScripts/ReadItem.ps1
I had modified code like below:
Add-Type -AssemblyName System.Web
Function Generate-MasterKeyAuthorizationSignature {
[CmdletBinding()]
param (
[string] $Verb,
[string] $ResourceId,
[string] $ResourceType,
[string] $Date,
[string] $MasterKey,
[String] $KeyType,
[String] $TokenVersion
)
$keyBytes = [System.Convert]::FromBase64String($MasterKey)
$sigCleartext = #($Verb.ToLower() + "`n" + $ResourceType.ToLower() + "`n" + $ResourceId + "`n" + $Date.ToString().ToLower() + "`n" + "" + "`n")
Write-Host "sigCleartext = " $sigCleartext
$bytesSigClear = [Text.Encoding]::UTF8.GetBytes($sigCleartext)
$hmacsha = new-object -TypeName System.Security.Cryptography.HMACSHA256 -ArgumentList (, $keyBytes)
$hash = $hmacsha.ComputeHash($bytesSigClear)
$signature = [System.Convert]::ToBase64String($hash)
$key = [System.Web.HttpUtility]::UrlEncode('type=' + $KeyType + '&ver=' + $TokenVersion + '&sig=' + $signature)
return $key
}
Function Get-Document {
[string] $endpoint = "https://testcosmos.documents.azure.com/"
[string] $MasterKey = "masterkey=="
[string] $databaseId = "testdb"
[string] $containerId = "containercollection1"
$KeyType = "master"
$TokenVersion = "1.0"
$date = Get-Date
$utcDate = $date.ToUniversalTime()
$xDate = $utcDate.ToString('r', [System.Globalization.CultureInfo]::InvariantCulture)
$itemResourceType = "docs"
$itemResourceId = $null
$itemResourceLink = $null
# $itemResourceId = "dbs/" + $databaseId + "/colls/" + $containerId
$itemResourceLink = "dbs/" + $databaseId + "/colls/" + $containerId + "/docs/"
$itemResourceId = "dbs/" + $databaseId + "/colls/" + $containerId
$verbMethod = "POST"
$requestUri = "$endpoint$itemResourceLink"
$authKey = Generate-MasterKeyAuthorizationSignature -Verb $verbMethod -ResourceId $itemResourceId -ResourceType $itemResourceType -Date $xDate -MasterKey $MasterKey -KeyType $KeyType -TokenVersion $TokenVersion
$itemResourceId
$itemResourceLink
$requestUri
$header = #{
"x-ms-documentdb-isquery" = "True";
"authorization" = "$authKey";
"x-ms-version" = "2018-12-31";
"Cache-Control" = "no-cache";
"x-ms-date" = "$xDate";
}
$queryJson = #"
{
"query": "SELECT * FROM TestCollection c WHERE c.userid = 2",
"parameters": [ ]
}
"#
try {
$result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method
$verbMethod -ContentType "application/query+json" -Body $queryJson -
ErrorAction Stop
Write-Host "Read item response = "$result
}
catch {
# Dig into the exception to get the Response details.
# Note that value__ is not a typo.
Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "Exception Message:" $_.Exception.Message
Write-Host $_.Exception|format-list -force
}
}
Get-Document
Error:
Response status code does not indicate success: 400 (Bad Request)
I believe the issue is with your $itemResourceId variable.
Please change it to:
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId
and you should not get this 401 error.
If you notice, I removed /docs from this.
Also, I found this useful link that you may find helpful: https://github.com/Azure/azure-cosmos-dotnet-v2/blob/master/samples/rest-from-.net/Program.cs. This will tell you exactly what the values that should be used to calculate authorization header for commonly used operation.
UPDATE
Please add the following to your request headers:
"x-ms-documentdb-query-enablecrosspartition" = "True";
Here's the complete code that worked for me:
Add-Type -AssemblyName System.Web
Function Generate-MasterKeyAuthorizationSignature{
[CmdletBinding()]
param (
[string] $Verb,
[string] $ResourceId,
[string] $ResourceType,
[string] $Date,
[string] $MasterKey,
[String] $KeyType,
[String] $TokenVersion
)
$keyBytes = [System.Convert]::FromBase64String($MasterKey)
$sigCleartext = #($Verb.ToLower() + "`n" + $ResourceType.ToLower() + "`n" + $ResourceId + "`n" + $Date.ToString().ToLower() + "`n" + "" + "`n")
Write-Host "sigCleartext = " $sigCleartext
$bytesSigClear = [Text.Encoding]::UTF8.GetBytes($sigCleartext)
$hmacsha = new-object -TypeName System.Security.Cryptography.HMACSHA256 -ArgumentList (, $keyBytes)
$hash = $hmacsha.ComputeHash($bytesSigClear)
$signature = [System.Convert]::ToBase64String($hash)
$key = [System.Web.HttpUtility]::UrlEncode('type='+$KeyType+'&ver='+$TokenVersion+'&sig=' + $signature)
return $key
}
$endpoint = "https://account-name.documents.azure.com:443/"
$MasterKey = "account-key=="
$KeyType = "master"
$TokenVersion = "1.0"
$date = Get-Date
$utcDate = $date.ToUniversalTime()
$xDate = $utcDate.ToString('r', [System.Globalization.CultureInfo]::InvariantCulture)
$databaseId = "DatabaseId"
$containerId = "ContainerId"
$itemResourceType = "docs"
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs"
$verbMethod = "POST"
$requestUri = "$endpoint$itemResourceLink"
$authKey = Generate-MasterKeyAuthorizationSignature -Verb $verbMethod -ResourceId $itemResourceId -ResourceType $itemResourceType -Date $xDate -MasterKey $MasterKey -KeyType $KeyType -TokenVersion $TokenVersion
$queryJson = "{`"query`": `"SELECT * FROM test c WHERE c.id = 1 `", `"parameters`": []}"
$header = #{
"authorization" = "$authKey";
"x-ms-version" = "2018-12-31";
"Cache-Control" = "no-cache";
"x-ms-date" = "$xDate";
"Accept" = "application/json";
"User-Agent" = "PowerShell-RestApi-Samples";
"x-ms-documentdb-query-enablecrosspartition" = "True";
}
try {
$result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod -Body $queryJson -ContentType "application/query+json"
Write-Host "Read item response = "$result
return "ReadItemSuccess";
}
catch {
# Dig into the exception to get the Response details.
# Note that value__ is not a typo.
Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "Exception Message:" $_.Exception.Message
echo $_.Exception|format-list -force
}

Can I list all items of an Azure table(Azure Table Storage) just by PartitionKey?

I tried to use the below uri for REST call, but getting error(403 Forbidden)
https://$storageAccount.table.core.windows.net/$tableName()?$filter=PartitionKey%20eq%20'Key1'
Is there other way? Please help.
According to my test, we can use share key to call the Azure table rest api
$accesskey="<storage account key>"
$storageAccount = "<account name>"
$version = "2017-04-17"
$resource = "table name"
$key="Jim"
$table_url = "https://$storageAccount.table.core.windows.net/$($resource)?`$filter=PartitionKey%20eq%20'$($key)'"
# create share key
$GMTTime = (Get-Date).ToUniversalTime().AddYears(1).toString('R')
$stringToSign = "$GMTTime`n/$storageAccount/$resource"
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)
$headers = #{
'x-ms-date' = $GMTTime
"Authorization" = "SharedKeyLite " + $storageAccount + ":" + $signature
"x-ms-version" = $version
"Accept" = "application/json"
}
$item = Invoke-RestMethod -Method GET -Uri $table_url -Headers $headers -ContentType application/json
$item.value
Update
Regarding how to create sas token via Azure Portal, please refer to the following steps
Create sas token
Test
GET https://myaccount.table.core.windows.net/mytable()
?$filter=<>
&sv=2019-02-02&ss=t&srt=o&sp=r&se=2020-03-27T13:01:24Z&st=2020-03-27T05:01:24Z&spr=https&sig=OFUNXShu6kTojIp3SU...TkG%2BXAVZXJ8sqc%3D

Resources