Using Azure REST interface with Postman and PowerShell Az module

I recently got the need to access Azure through its REST interface and thought that it was a good opportunity to acquaint myself with the fairly new PowerShell Az module. The Az module will replace AzureRM, introducing shorter commands, higher stability, and cross platform support. Now before rushing of and installing the Az module uninstall AzureRM first, installing both will render your system unusable and will be a pain to clean up.

My original motivation for this was accessing reports generated by the Azure API Management (APIM). This can be achieved by turning the Management REST API in the APIM instance and generating a SAS token, however that only allows you to access the older versions of the API reference. The Microsoft docs refers to the 2019-01-01 version of the REST API and to access that you need to use OAuth2 instead. In this post however I will only go so far as to list a resource group.

So let’s get cracking. First we need to login

> Connect-AzAccount

This will bring up a dialog to enter your Azure credentials and create a session. If you have multiple subscriptions tied to your account you want to set which subscription you are working on through the Set-AzContext

> Get-AzSubscriptions
 Name                                         Id                                   TenantId                             State
 ----                                         --                                   --------                             -----
 Visual Studio Enterprise – MPN               xxxxxxxx-xxxx-xxxx-xxxx-e95e0cf9d2e2 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Enabled
 byBrick Development Prod (Pay-As-You-Go)     xxxxxxxx-xxxx-xxxx-xxxx-c8c933d123a8 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Enabled
 byBrick Development Dev/Test (Pay as you go) xxxxxxxx-xxxx-xxxx-xxxx-4d668f535f61 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Enabled
> Set-AzContext -SubscriptionId "xxxxxxxx-xxxx-xxxx-xxxx-e95e0cf9d2e2"

In order to to get an OAuth2 token to interact with Azure we are going to create a Service Principal that can is kind of similar to a batch account in Windows. The service principal can be scoped to a specific region and given an appropriate role. In this example I’m first creating a resource group and then adding the service principal to that group with a Reader role. It’s important to store the result from the New-AzADServicePrincipal call as this contains a Secret, if this is not stored the service principal has to be reset to generate a new one.

> $rg = New-AzResourceGroup -Name example-rg -Location northeurope
> $sp = New-AzADServicePrincipal -DisplayName "example-sp" -Role Reader -Scope $rg.ResourceId
> $sp

 Secret                : System.Security.SecureString
 ServicePrincipalNames : {xxxxxxxx-xxxx-xxxx-xxxx-25360bb5073e, http://example-sp}
 ApplicationId         : xxxxxxxx-xxxx-xxxx-xxxx-25360bb5073e
 ObjectType            : ServicePrincipal
 DisplayName           : example-sp
 Id                    : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

The Secret is a System.Security.SecureString and we kind of have to know that secret in order for us to get our token; there are more or less hacky ways of achieving this, below is the way I took

> $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp.Secret)
> [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
> [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)

Now we have all information we need and it is time to break out Postman. The address, to request the token from, is<TenantId>/oauth2/token. This is a POST request, the body of the message should be form data and contain grant_type, client_id, client_secret, and optionally a resource

OAuth2 Token with Postman

the client_id is the ApplicationId of the service principal and the client_secret is the Secret we extracted from the same service principal.

Let’s finish up and see if our shiny new token actually works. To list all resource groups for a specific subscriptions we call the endpoint<SubscriptionId>/resourceGroups?api-version=2019-05-10 . To get the authorization for this call we set the authorization type to Bearer Token and paste in the access_token we got in the response to our last call

List Resource Groups

Since the service principal was only scoped to the resource group we created this will be the only group listed.

The REST API interface of Azure is plentiful and can be quite useful for extracting information from Azure components. An example of this is my original problem with fetching the reports from APIM, simply by adding the header Accept: test/csv to the REST request the response was formatted in CSV instead of JSON ready to use in Excel.

Below are some useful resources that related to this article

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: