Leveraging the Azure Service Management REST API with Azure Active Directory and PowerShell / List Azure Administrators

The Azure Service Management REST API can be a great compliment to the Azure PowerShell module when automating certain Azure cloud tasks for which there's not yet a defined set of PowerShell cmdlets.  In previous articles, we've leveraged this API for specific scenarios, such as:

Authenticating with Azure AD

However, in each of our previous articles, we've used management certificates to authenticate to our Azure subscription when calling the Azure Service Management REST API. Azure Active Directory is being used by many organizations for centralized authentication to Azure via the Azure Management Portal, Azure PowerShell using the Add-AzureAccount cmdlet, and to other cloud-based applications (over 2,400 third-party apps as of the date of this article).  This prompted me to consider leveraging Azure AD for Azure API authentication as an alternative to management certificates.

, Azure AD and the Azure API

In this article, we'll step through the process of authenticating to the Azure Service Management REST API using Azure Active Directory via PowerShell.  Leveraging these capabilities together gives us a consistent authentication and scripting experience, along with the extensibility that the Azure API provides.

Along the way, we'll also show a useful example for keeping track of the administrators and co-administrators for your Azure subscription.

Azure AD Authentication Library

The Azure AD Authentication Library (ADAL) for .NET allows us to easily authenticate users to cloud or on-premises Active Directory instances and obtain the necessary access tokens for securing our API calls. In fact, the ADAL .NET assemblies are invoked by the Add-AzureAccount cmdlet when authenticating to Azure AD from within a script using the Azure PowerShell cmdlets.  As such, the latest version of the Azure PowerShell module also installs a copy of the ADAL .NET assemblies.  

Since we'll be using the ADAL assemblies to authenticate to Azure AD for access to the Azure API directly, we'll first need to manually load the necessary DLLs at the start of our script.

# Load ADAL Assemblies

$adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services
\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"

$adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services
\Microsoft.IdentityModel.Clients.ActiveDirectory.
WindowsForms.dll"

[System.Reflection.Assembly]::LoadFrom($adal)

[System.Reflection.Assembly]::LoadFrom($adalforms)

Azure AD Tenant Name

Next, we'll need to define our Azure AD Tenant Name, so that our script can direct ADAL to authenticate against the appropriate Azure AD instance.  The Azure AD Tenant Name is the name located after the @ symbol in your Azure AD sign-in name, also known as a User Principal Name (UPN) .  For example, if your Azure AD sign-in name is admin@contoso.onmicrosoft.com, then contoso.onmicrosoft.com is your Azure AD Tenant Name.

# Set Azure AD Tenant name

$adTenant = "contoso.onmicrosoft.com"

Tip! Be sure to specify the exact name of your Azure AD Tenant in the PowerShell snippet above.

Azure AD Application Details

When acquiring an access token for authenticating to an application, we'll need to specify a few unique application details so that Azure AD can construct an appropriate token.  In particular, we'll need to specify the application's unique Client ID, Redirect URI, and Application ID URI.  You can read more about the basics of registering an application in Azure AD here to setup a new application with these values.

Normally, we'd register these per-application values with Azure AD when developing a custom application, but since Azure PowerShell already has well-known values that are registered with Azure AD, we'll use those values instead for our PowerShell script.

# Set well-known client ID for Azure PowerShell

$clientId = "1950a258-227b-4e31-a9cf-717495945fc2"

# Set redirect URI for Azure PowerShell

$redirectUri = "urn:ietf:wg:oauth:2.0:oob"

# Set Resource URI to Azure Service Management API

$resourceAppIdURI = "https://management.core.windows.net/"

Authenticate and Acquire Token

Now, we're ready to authenticate against our Azure AD tenant and acquire the token for accessing the Azure Service Management REST API via PowerShell.

# Set Authority to Azure AD Tenant

$authority = "https://login.windows.net/$adTenant"

# Create Authentication Context tied to Azure AD Tenant

$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.
AuthenticationContext" -ArgumentList $authority

# Acquire token

$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")

When the last line in the above snippet executes, you'll be prompted to authenticate to Azure AD if you've not recently signed in.

Click to zoom in ...

Tip! The user account that you're signing in with in the snippet above will be accessing the Azure Service Management REST API.  As such, this user account requires co-administrator access to your Azure subscription.  You can read more about adding a co-administrator to your Azure subscription here.

Call the Azure API

We've successfully authenticated to Azure AD and acquired a token. We're ready to build and send our request to the Azure Service Management REST API. To do this, we'll need to ensure that we're including an authorization header with our encoded token on our request to the Azure API.

# Create Authorization Header

$authHeader = $authResult.CreateAuthorizationHeader()

# Set HTTP request headers to include Authorization header

$requestHeader = @{
"x-ms-version" = "2013-08-01";
"Authorization" = $authHeader
}

Tip! Note that the x-ms-version request header is a required header for Azure API calls.  The specific value to be submitted for this header varies based on when each operation was added to the API.  In addition, some operations may require additional request headers, URI parameters, or a request body to be submitted with your request.  Be sure to check the Azure Service Management REST API Reference for the details that each operation requires before calling this API.

Continuing with our example, we'll have our script call the List Subscription User Accounts operation via the Azure Service Management API.  This operation can be used to return the list of administrators and co-administrators for a given Azure subscription, which is useful for keeping track of who has admin access to Azure.

# Set Azure subscription ID

$subscriptionId = "Enter-your-Azure-subscription-ID"

# Call Azure Service Management REST API to list Azure administrators

$azureMgmtUri = "https://management.core.windows.net/$subscriptionId/principals"

$response = Invoke-RestMethod -Uri $azureMgmtUri -Method Get -Headers $requestHeader

$response.Principals.Principal |
Select-Object -Property Role, Email

The above snippet will display the list of administrators and co-administrators of your Azure subscription in the following format:

Role Email
---- -----
ServiceAdministrator admin@contoso.onmicrosoft.com
CoAdministrator admin2@contoso.onmicrosoft.com
CoAdministrator admin3@contoso.onmicrosoft.com

This script provides just one example of many scripted scenarios that are possible by leveraging Azure AD, the Azure Service Management REST API and the Azure PowerShell module together.