Last active
May 10, 2021 17:59
-
-
Save hbulens/ba4a5812af7ff8fd1d8fa88ff2346691 to your computer and use it in GitHub Desktop.
Create an Azure AD App with application permissions using PowerShell. Courtesy of https://stackoverflow.com/a/61458391/1842261
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param ( | |
[Parameter(mandatory = $false, HelpMessage = "The name of the Azure AD App.")] | |
[string] $appName = "dime-scheduler", | |
[Parameter(mandatory = $true, HelpMessage = "The id of the Azure tenant ")] | |
[string] $tenantId, | |
[Parameter(mandatory = $true, HelpMessage = "The name of the Azure tenant ")] | |
[string] $tenantName, | |
[Parameter(mandatory = $false, HelpMessage = "The permission set")] | |
[string[]] $applicationPermissions = @('Calendars.ReadWrite', 'MailBoxSettings.ReadWrite', 'User.Read.All') | |
) | |
If (-not(Get-InstalledModule AzureAD -ErrorAction SilentlyContinue)) { | |
Install-Module AzureAD -Confirm:$False -Force -AllowClobber | |
} | |
Import-Module AzureAD | |
$global:appId = $null; | |
$global:clientSecretKey = $null; | |
Function CreateAzureAdApp { | |
param ( | |
[string] $displayName, | |
[string] $tenantName | |
) | |
$app = Get-AzureADApplication -SearchString $displayName | |
if (!$app) { | |
Write-Host "Azure AD App '$displayName' does not exist yet. Creating..." | |
$app = New-AzureADApplication -DisplayName $displayName ` | |
-Homepage "https://localhost" ` | |
-ReplyUrls "https://localhost" ` | |
-IdentifierUris ('https://{0}/{1}' -f $tenantName, $displayName) | |
# Create SPN for App Registration | |
Write-Host "Creating SPN for app registration '$displayName'" | |
# Create a password (spn key) | |
$clientSecret = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId -CustomKeyIdentifier "Dime.Scheduler" -EndDate (get-date).AddYears(20) | |
$global:clientSecretKey = $clientSecret.Value | |
# Create a service principal for the app | |
# This is necessary to be able to grant the application the required permissions | |
$spForApp = New-AzureADServicePrincipal -AppId $app.AppId -PasswordCredentials @($clientSecret) | |
} | |
else { | |
Write-Host "Azure AD App '$displayName' already exists. No action needed." | |
$date = Get-Date -Format "yyyyMMdd" | |
$customIdentifier = "Dime.Scheduler-$date" | |
$clientSecret = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId -CustomKeyIdentifier $customIdentifier -EndDate (get-date).AddYears(20) | |
$global:clientSecretKey = $clientSecret.Value | |
} | |
$global:appId = $app.AppId | |
return $app | |
} | |
Function GrantApplicationPermissions { | |
param | |
( | |
[string] $targetServicePrincipalName, | |
$appPermissionsRequired, | |
$childApp, | |
$spForApp | |
) | |
$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$($targetServicePrincipalName)'" | |
# Iterate Permissions array | |
Write-Host "Retrieving role assignments objects" | |
$roleAssignments = @() | |
Foreach ($appPermission in $appPermissionsRequired) { | |
$roleAssignment = $targetSp.AppRoles | Where-Object { $_.Value -eq $appPermission } | |
$roleAssignments += $roleAssignment | |
} | |
$resourceAccessObjects = New-Object 'System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]' | |
foreach ($roleAssignment in $roleAssignments) { | |
$resourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" | |
$resourceAccess.Id = $roleAssignment.Id | |
$resourceAccess.Type = 'Role' | |
$resourceAccessObjects.Add($resourceAccess) | |
} | |
$requiredResourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess" | |
$requiredResourceAccess.ResourceAppId = $targetSp.AppId | |
$requiredResourceAccess.ResourceAccess = $resourceAccessObjects | |
# Set the required resource access | |
Set-AzureADApplication -ObjectId $childApp.ObjectId -RequiredResourceAccess $requiredResourceAccess | |
Start-Sleep -s 1 | |
# Grant the required resource access | |
foreach ($roleAssignment in $roleAssignments) { | |
$roleAssignmentValue = $roleAssignment.Value | |
Write-Host "Granting admin consent for App Role: $roleAssignmentValue" | |
try { | |
New-AzureADServiceAppRoleAssignment -ObjectId $spForApp.ObjectId -Id $roleAssignment.Id -PrincipalId $spForApp.ObjectId -ResourceId $targetSp.ObjectId | |
Start-Sleep -s 1 | |
} | |
catch { | |
if ( $_.Exception.Message -like '*Permission being assigned already exists on the object*') { | |
Write-Host "Permission $roleAssignmentValue already exists" | |
} | |
else { | |
Write-Error $_.Exception.Message | |
} | |
} | |
} | |
} | |
Write-Output "" | |
Write-Output "" | |
Write-Output "*" | |
Write-Output "**" | |
Write-Output "***" | |
Write-Output "****" | |
Write-Output "*****" | |
Write-Output "******" | |
Write-Output "*******" | |
Write-Output "********" | |
Write-Output "*********" | |
Write-Output "**********" | |
Write-Output "***********" | |
Write-Output "************" | |
Write-Output "" | |
Write-Output "_____ _ _____ _ _ _" | |
Write-Output "| __ \(_) / ____| | | | | | |" | |
Write-Output "| | | |_ _ __ ___ ___ | (___ ___| |__ ___ __| |_ _| | ___ _ __" | |
Write-Output "| | | | | '_ ` _ \ / _ \ \___ \ / __| '_ \ / _ \/ _` | | | | |/ _ \ '__|" | |
Write-Output "| |__| | | | | | | | __/_ ____) | (__| | | | __/ (_| | |_| | | __/ |" | |
Write-Output "|_____/|_|_| |_| |_|\___(_)_____/ \___|_| |_|\___|\__,_|\__,_|_|\___|_|" | |
Write-Output "" | |
Write-Output "" | |
Write-Output "" | |
Write-Output "************" | |
Write-Output "***********" | |
Write-Output "**********" | |
Write-Output "*********" | |
Write-Output "********" | |
Write-Output "*******" | |
Write-Output "******" | |
Write-Output "*****" | |
Write-Output "****" | |
Write-Output "***" | |
Write-Output "**" | |
Write-Output "*" | |
Write-Output "" | |
Write-Output "" | |
# Connect | |
Connect-AzureAD -TenantId $tenantId | |
# Create Azure AD App | |
$app = CreateAzureAdApp -displayName $appName -tenantName $tenantName | |
# Add application permissions | |
$spForApp = Get-AzureADServicePrincipal -Filter ("appId eq '{0}'" -f $app.AppId) | |
GrantApplicationPermissions ` | |
-targetServicePrincipalName 'Microsoft Graph' ` | |
-appPermissionsRequired $applicationPermissions ` | |
-childApp $app ` | |
-spForApp $spForApp | |
Write-Host "" | |
Write-Host "" | |
Write-Host "******************" | |
Write-Host "Copy the application id to complete the installation of Dime.Scheduler" | |
Write-Host $global:appId | |
Write-Host "******************" | |
Write-Host "Copy the client secret to complete the installation of Dime.Scheduler" | |
Write-Host "WARNING: once you close this window, you won't be able to recover the client secret." | |
Write-Host $global:clientSecretKey | |
Write-Host "******************" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment