Add messages to an Azure Storage Queue via PowerShell and the Rest API

PowerShell Azure functions are great, however if you’re running hundreds of them concurrently, they can have issues loading and using PowerShell modules.

To get around this issue, we’re using the Azure Storage Queue Rest API to send our messages, instead of the PowerShell modules.

There’s documentation on how to use these REST APIs here.

It took me a while to get these to authenticate correctly, I was constantly receiving the following message:

Invoke-RestMethod : AuthenticationFailedServer failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

If you’re having this issue, here’s a PowerShell function that should help, as it can be difficult to correctly sign the Authorization header:

$storageAccount = "storageAccountName"
$accesskey = "storageAccountKey"

function UploadToQueue($QueueMessage,$QueueName){
    $method = "POST"
    $contenttype = "application/x-www-form-urlencoded"
    $version = "2017-04-17"
    $resource = "$QueueName/messages"
    $queue_url = "https://$storageAccount.queue.core.windows.net/$resource"
    $GMTTime = (Get-Date).ToUniversalTime().toString('R')
    $canonheaders = "x-ms-date:$GMTTime`nx-ms-version:$version`n"
    $stringToSign = "$method`n`n$contenttype`n`n$canonheaders/$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 = "text/xml"
    }
    $QueueMessage = [Text.Encoding]::UTF8.GetBytes($QueueMessage)
    $QueueMessage =[Convert]::ToBase64String($QueueMessage)
    $body = "<QueueMessage><MessageText>$QueueMessage</MessageText></QueueMessage>"
    $item = Invoke-RestMethod -Method $method -Uri $queue_url -Headers $headers -Body $body -ContentType $contenttype
}

UploadToQueue -QueueMessage "hello" -QueueName "testing"

Was this article helpful?

Related Articles