Search code examples
powershellazure-iot-hub

IoT Hub Shared Access Signature in PowerShell


How do I create an IoT Hub Shared Access Signature using PowerShell. My code works when using the signature generated in the Azure IoT Explorer. Assume something is wrong with the signature generation:

$Uri = "$IotHubName.azure-devices.net/devices/$IotDeviceId"
$Expiry = [string](([DateTimeOffset]::Now.ToUnixTimeSeconds())+3600)
$IotHubKeyDecoded = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($IotHubKey)) 
$StringToSign = [System.Web.HttpUtility]::UrlEncode($Uri) + "`n" + $Expiry
$Hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$Hmacsha.key = [Text.Encoding]::ASCII.GetBytes($IotHubKeyDecoded)
$Signature = $Hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($StringToSign))
$Signature = [System.Web.HttpUtility]::UrlEncode([Convert]::ToBase64String($Signature))

I tried using New-AzIotHubSasToken but getting 'Unauthorized':

$SharedAccessSignature = New-AzIotHubSasToken -ResourceGroupName $IotHub.ResourceGroupName -IotHubName $IotHubName -DeviceId $IotDeviceId 
$Headers = @{"Authorization" = $SharedAccessSignature; "Content-Type"="application/json";} 
$Uri = "https://$IotHubName.azure-devices.net/devices/$IotDeviceId/messages/events?api-version=2020-03-13" 
Invoke-RestMethod -Uri $Uri -Headers $Headers -Method Post -Body $JsonBody

Solution

  • I am not sure why you are trying to create a SAS token in that way, but you could use either PowerShell or Azure CLI for that purpose (you must install it first).

    Here you have both examples:

    # PowerShell
    New-AzIotHubSasToken -IotHubName "{IoT Hub Name}" -DeviceId "{Device Id}" -ResourceGroupName "{Resource Group Name}"
    
    # Output
    SharedAccessSignature sr={IoT Hub Name}.azure-devices.net%2fdevices%2f{Device Id}&sig=iuhiAfagvhgd3QtqjukX8upPuWj%2fuJuYn%2bJgeOe6Uwo%3d&se=1604085022
    
    # Azure CLI
    az iot hub generate-sas-token -n {IoT Hub Name} -d {Device Id}
    
    # Output
    {
      "sas": "SharedAccessSignature sr={IoT Hub Name}.azure-devices.net%2fdevices%2f{Device Id}&sig=iuhiAfagvhgd3QtqjukX8upPuWj%2fuJuYn%2bJgeOe6Uwo%3d&se=1604085022"
    }
    

    Remember you must first login and then select the corresponding subscription (in case you have more than one)

    az login
    # Optionally: az account list
    az account set --subscription {subscription id}