Creating Azure AD Application using Powershell
NOTE: This writeup does not use the latest AZ PowerShell module. I will correct this when I find the time.
Azure AD Application
Azure AD has something called Application registrations. These are often used to integrate with external services and can provide functionality like Single Sign-On to your companies Twitter account. There’s a large selection of applications you can choose from in the Azure Portal, but this post will cover how to create your own application registration using Powershell.
In this scenario, we are creating an app that can access Azure Activity Logs, used by our on-premises Splunk environment. Since I am doing this across 300 tenants the manual approach isn’t feasible.
High-level overview
- Create the app using Powershell
- Assign the required API access to the new app
- Create access key
- Create new Azure AD Service Principal for our app (SPN)
- Assign ‘Reader’ role to subscription
Create the app using Powershell
This is the easiest part. Azure Powershell has a pretty simple Cmdlet that let’s you create a new application, New-AzureADApplication. The required steps is to Import AzureRM modules and AzureAD modules. After that, connect to Azure AD using
Connect-AzureAD -Credential -TenantId "domain.onmicrosoft.com"
Now you can run New-AzureAdApplication to create a new app, this example shows the required fields.
New-AzureADApplication -DisplayName "Adatum App Demo" -IdentifierUris "https://localhost/AdatumAppDemo" -HomePage "https://localhost/Adatum"
and in return
ObjectId AppId DisplayName
-------- ----- -----------
2cd0a284-7b9e-4 34ecfd2a-8f78-38c4a8b0 Adatum App Demo
In the Azure portal we can see our new app registration, but it does not have a service principal and no API access. If you would have gone through the steps creating the app in the portal it self SPN and a “read basic profile” API permission would be added to your app by default.
Assign required API access
This is where I spent the most time. In order to assign permissions to our Azure AD Application we will need to write a bit of code. Applications can be assigned Application Permissions and Delegated permissions. According to the documentation New-AzureAdApplication Cmdlet takes a parameter “RequiredResourceAccess”. This again wan’t something of ‘Microsoft.Open.AzureAD.Model.RequiredResourceAccess’ as a generic list. Using my favourite search engine I found that I also needed to construct this object and add multiple objects (the permissions) to it.
Luckily my friend Jan Vidar Elven (MVP) had an example. A sligthly different approach, but here’s what I did. My app needed access to Azure Service Management API, manually I added this via the portal and explored the JSON manifest to see what GUIDs was added. Later I found a better solution, exploring the Service Principal (API’s) using Get-AzureADServicePrincipal.
Get-AzureADServicePrincipal -All $true | Where-Object {$_.DisplayName -eq "Windows Azure Service Management API"}
which will return something like this.
ObjectId AppId DisplayName
28a1249a-c5bb-4c7b-b94d-064ca5bb1952 797f4846-ba00-4fd7-ba43-dac1f8f63013 Windows Azure Service Management API
Then I could start to build my permission object
## Azure Management API
$AzureMgmtPrincipal = Get-AzureADServicePrincipal -All $true | Where-Object {$_.DisplayName -eq "Windows Azure Service Management API"}
$AzureMgmtAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$AzureMgmtAccess.ResourceAppId = $AzureMgmtPrincipal.AppId
If you had used this object with the ‘RequiredResourceAccess’ parameter now, the app would have assigned Windows Azure Service Management API, but no permissions. Just to be clear, this is the permissions I am talking about
You can explore the same permissions using
$AzureMgmtPrincipal.AppRoles
for application permissions and $AzureMgmtPrincipal.Oauth2Permissions
for delegated permissions. Azure Management only have one delegated permission
PS C:> $AzureMgmtPrincipal.Oauth2Permissions
AdminConsentDescription : Allows the application to access the Azure Management Service API acting as users in the organization.
AdminConsentDisplayName : Access Azure Service Management as organization users (preview)
Id : 41094075-9dad-400e-a0bd-54e686782033
IsEnabled : True
Type : User
UserConsentDescription : Allows the application to access Azure Service Management as you.
UserConsentDisplayName : Access Azure Service Management as you (preview)
Value : user_impersonation
Who doesen’t love GUIDs?
Now add this permission to a new ‘microsoft.open.azuread.model.resourceAccess’ object
$AzureSvcMgmt = New-Object -TypeName "microsoft.open.azuread.model.resourceAccess" -ArgumentList "41094075-9dad-400e-a0bd-54e686782033", "Scope"
before you add that permission object to the ‘resource access object’ created earlier.
$AzureMgmtAccess.ResourceAccess = $AzureSvcMgmt
If you where adding multiple permissions, repeat the above. After you completed this step, our first object $AzureMgmtAccess
have an app ID assigned (Azure management api) with the corresponding Resource access object(s)
ResourceAppId ResourceAccess
797f4846-ba00-4fd7-ba43-dac1f8f63013 {class ResourceAccess {...
Now you can re-run our first command but add the permission parameter (delete the app created earlier or change the identifier)
New-AzureADApplication -DisplayName "Adatum App Demo" -IdentifierUris "https://localhost/AdatumAppDemo" -HomePage "https://localhost/Adatum" RequiredResourceAccess @($AzureMgmtAccess)
Check your portal now 🙂
Application Access Key
We have to create an access key for us to programmatically logging in via the application. Depending on your scenario, you might want to create multiple keys, but in this example I am sticking with one. Just like in the Azure portal you will specify the validity time for your key. The example below will add a key wich expire in one year.
New-AzureADApplicationPasswordCredential -ObjectId $AdatumDemoApp.ObjectId -CustomKeyIdentifier "Access Key" -EndDate (get-date).AddYears(1)
If you want the key to not be activated immediately, set the appropriate date time by using StartDate parameter.
Create new Azure AD service principal
For our application to access within our tenant, we need to assign a new service principal. The security principle will allow us to access the subscription (or other resources for that matter.) You can read more about security principals for users and services here, Application and service principal objects in Azure Active Directory (Azure AD)
To create the service principal in via Powershell, run the following: New-AzureADServicePrincipal -AppId -Tags @("WindowsAzureActiveDirectoryIntegratedApp")
Pay attention to that tag. It is required if you want the app to show under app integrations in the Azure AD portal view. Documented here
RBAC / IAM subscription access
The app I am creating is used to read Azure activity logs. To be allowed to read these logs, the app must be assigned ‘Read’ permission on the subscription level. To assign a new role, use the New-AzureRmRoleAssignment cmdlet, using ObjectID, RoleDefinitionName and Scope as input parameters.
New-AzureRmRoleAssignment -ObjectId 'SPN objectId' -RoleDefinitionName "Reader" -Scope "/subscriptions/$SubScriptionId"
PS: When you put the complete script together, you will find that the SPN is create async in Azure Resource Manager. Meaning that you will get the output, but the principal isn’t created. To get around this in our provisioning I created a while loop. Not the prettiest you will find, but works for now.
while ($addRole.DisplayName -ne $AzureSplunkAdApp.DisplayName ) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for SPN to create"
$addRole = New-AzureRmRoleAssignment -ObjectId $AzureSplunkAdAppAppSPN.ObjectId -RoleDefinitionName "Reader" -Scope "/subscriptions/$SubScriptionId"
}
Final script
I have put together a complete script that will create this demo application. No error handling and your risk 🙂