Authentication failed. The ‘Authorization’ header is missing – Invoke-WebRequest Azure ARM

While building an automation procedure I had to POST the management API of Azure.

Invoke-WebRequest -Uri https://management.azure.com/subscriptions/pool/xxx/xxxx/xxxx/xxxx -Method POST

When I used the Invoke-WebRequest without Authentication it failed. The error that you will get when you do not have Authentication headers set can be found below.

Invoke-WebRequest: {"error":{"code":"AuthenticationFailed","message":"Authentication failed. The 'Authorization' header is missing."}}

In order to authenticate with azure you can get an access-token using az cli.

az account get-access-token

The output will look like the below output:

{
  "accessToken": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxVG-hTDHECYJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-B5FA9l9RvqOls3iaDDYw5O86acvLIwxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-ixxxxxxxxxxxxxxxxx3eoeKlxZfxxxxxxxxxxfGW2O6oA",
  "expiresOn": "2022-05-05 14:51:08.000000",
  "subscription": "a23eef11-f200-4722-866c-248ca45142f6",
  "tenant": "1efa646f-3fc3-4554-bd8c-651879a2b110",
  "tokenType": "Bearer"
}

You should take the output of the token and use it on your call.

For example using POSTMAN you should place your token under the Authorization tab. You will then be able to get the result from Azure ARM api.

InvalidAuthenticationToken “message”:”The access token is invalid.” – Powershell

$token =  az account get-access-token | ConvertFrom-Json
$mytoken =  $token.accesstoken
$headers = @{ Authorization = "Bearer $token.accesstoken" }
echo $headers
Invoke-RestMethod -Method Get -Uri "https://management.azure.com/subscriptions/xxxxx/resourceGroups/resource-group/providers/Microsoft.Sql/servers/sql-server?api-version=2020-11-01-preview" -Headers $headers -UseBasicParsing

This is an error occuring on powershell as the $token.accesstoken is not correctly parsed. In order to resolve either use a new variable and assign the value on it ($mytoken)

$headers = @{ Authorization = "Bearer $mytoken" }

Start multiple VMs using parameters with Azure DevOps pipeline

In this article I will explain how one can start multiple VMs on Azure using a pipeline automation. The steps you need to follow:

First create a service connection with your subscription. You should navigate to service connections -> azure resource manager and then select service principal (automatic)

You will then have to select the scope* the subscription or resource group this service connection will access.

In my scenario I added a friendly name of the subscription as Azure Subscription Service Connection

trigger: none
pr: none
parameters:
– name: vms
type: object
default: ["ubuntu1","windows-1"]
pool:
vmImage: ubuntu-latest
jobs:
– job: startvmjob
displayName: Start VMs
steps:
– checkout: none
– ${{ each vm in parameters.vms }}:
– task: AzureCLI@2
displayName: starting vm ${{vm}}
inputs:
azureSubscription: 'Azure Subscription Service Connection'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
$vmrequest = az vm list | ConvertFrom-Json | Where-Object {$_.Name -Match "${{vm}}"}
az vm start –resource-group $vmrequest.resourcegroup –name $vmrequest.name

When you run the pipeline you will need to provide the VM names. You can also run this pipeline on a schedule using a cron task. My vms are ubuntu1, windows-1

By running the pipeline

Then by navigating on Azure you can notice the VM as started.

Video tutorial on YouTube:

Authenticate to Azure management API using az cli

A quick an easy way to authenticate on Azure management API is to use az cli get-access-token command and use this as a Bearer token on your API calls.

Given that you want to access https://management.azure.com/subscriptions/api you can use:

$token =  az account get-access-token | ConvertFrom-Json

You can then get the access token with $token.accesstoken

Finally you can use this token as a Bearer token on your API calls

$headers = @{ Authorization = "Bearer $token.accesstoken" }