Created
February 8, 2018 20:38
-
-
Save psignoret/9f40a6621ac1bbf80a3184c57f5fdee1 to your computer and use it in GitHub Desktop.
Add or remove application permissions to a client application.
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
<# | |
.SYNOPSIS | |
Grants (or removes) application permissions (app role assignments) to a client application. | |
.PARAMETER ClientId | |
The AppId or one of the ServicePrincipalNames of the client service principal. | |
.PARAMETER Permissions | |
A hashtable where the key is an identifier for the resource (either the AppId or one of the | |
ServicePrincipalNames) and the value is the space-separated list of app roles desired. | |
.PARAMETER RemoveAll | |
Instead of adding permissions, this removes *all* application permissions granted to the client. | |
.EXAMPLE | |
PS C:\> .\Manage-AzureADPSAppRoleAssignments.ps1 -ClientId "2e5e4fad-5332-43fc-9293-6a349df34883" -Permissions @{"https://graph.microsoft.com" = "Directory.Read.All Sites.ReadWrite.All"} | |
Grants application permissions Microsoft Graph API. | |
.EXAMPLE | |
PS C:\> .\Manage-AzureADPSAppRoleAssignments.ps1 -ClientId $client_id -RemoveAll | |
Removes all application permissions previously granted to a client | |
#> | |
param( | |
[Parameter(Mandatory = $true)] | |
[string] $ClientId, | |
[Hashtable] $Permissions, | |
[switch] $RemoveAll | |
) | |
# Parameter validation | |
if ((-not ($Permissions -or $RemoveAll)) -or ($Permissions -and $RemoveAll)) { | |
throw "Either -Permissions or -RemoveAllPermissions must be passed, but not both." | |
} | |
# Get tenant details to test that Connect-AzureAD has been called | |
try { | |
$tenant_details = Get-AzureADTenantDetail | |
} catch { | |
throw "You must call Connect-AzureAD before running this script." | |
} | |
Write-Verbose ("TenantId: {0}, InitialDomain: {1}" -f ` | |
$tenant_details.ObjectId, ` | |
($tenant_details.VerifiedDomains | Where-Object { $_.Initial }).Name) | |
# Get the client ServicePrincipal object | |
$client_filter = "servicePrincipalNames/any(c:c eq '{0}')" -f $ClientId | |
$client = Get-AzureADServicePrincipal -Filter $client_filter | |
if ($client.Count -lt 1) { | |
throw ("ServicePrincipal not found for client '{0}'" -f $ClientId) | |
} elseif ($client.Count -gt 1) { | |
throw ("Multiple ServicePrincipal ojects found for client '{0}'" -f $ClientId) | |
} | |
# Get all existing app role assignments for the client | |
$existingAppRoleAssignments = Get-AzureADServiceAppRoleAssignedTo -ObjectId $client.ObjectId | |
if (-not $RemoveAll) { | |
# Ensure an app role assignment exists for each desired permission | |
$permissions.Keys | ForEach-Object { | |
$resource_id = $_ | |
$scopes = $permissions[$_] | |
# Get the resource ServicePrincipal object and exisitng app role assignments to it | |
$resourceFilter = "servicePrincipalNames/any(c:c eq '{0}')" -f $resource_id | |
$resource = Get-AzureADServicePrincipal -Filter $resourceFilter | |
$existingPermissions = $existingAppRoleAssignments ` | |
| Where-Object { $_.ResourceId -eq $resource.ObjectId } ` | |
| Select-Object -ExpandProperty Id | |
if ($resource.Count -eq 1) { | |
$scopes.Split(" ") | ForEach-Object { | |
$scope = $_ | |
# Find the matching AppRole on the resource ServicePrincipal object | |
$appRole = $resource.AppRoles ` | |
| Where-Object { $_.AllowedMemberTypes -contains "Application" } ` | |
| Where-Object { $_.Value -eq $scope } | |
if ($appRole) { | |
if ($existingPermissions -and $existingPermissions -contains $appRole.Id) { | |
# Don't try to add an app role assignment that already exists. | |
Write-Output ("Permission '{0}' for '{1}' already exists. Skipping." -f ` | |
$appRole.Value, $resource.DisplayName) | |
} else { | |
Write-Output ("Granting permission '{0}' for '{1}'..." -f ` | |
$appRole.Value, $resource.DisplayName) | |
$appRoleAssignment = New-AzureADServiceAppRoleAssignment ` | |
-ObjectId $client.ObjectId ` | |
-PrincipalId $client.ObjectId ` | |
-ResourceId $resource.ObjectId ` | |
-Id $appRole.Id | |
} | |
} else { | |
Write-Warning ("AppRole with value '{0}' not found for resource '{1}'" -f ` | |
$scope, $resource.DisplayName) | |
} | |
} | |
} elseif ($resource.Count -gt 1) { | |
# AppId and ServicePrincipalNames should be unique, so this would be unexpected. | |
Write-Error ("More than one ServicePrincipal found for resource '{0}'" -f $resource_id) | |
} else { | |
# AppId and ServicePrincipalNames should be unique, so this would be unexpected. | |
Write-Error ("ServicePrincipal object not found for resource '{0}'" -f $resource_id) | |
} | |
} | |
} else { | |
# Remove *all* of the client's app role assignments | |
$existingAppRoleAssignments | ForEach-Object { | |
Write-Output ("Removing permission '{0}' for '{1}'..." -f $_.Id, $resource.DisplayName) | |
Remove-AzureADServiceAppRoleAssignment -ObjectId $client.ObjectId ` | |
-AppRoleAssignmentId $_.ObjectId | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment