functions/Set-AadConsent.ps1
<#
.SYNOPSIS # Resolve Admin Consent Issues .DESCRIPTION # Resolve Admin Consent Issues when the application registration is in a external directory and it not configured correctly. .PARAMETER Id Identifier for the Enterprise App (ServicePrincipal) we will be consenting to. .PARAMETER ResourceId Identifier for the Resource (ServicePrincipal) we will be consenting permissions to. .PARAMETER UseMsGraph Set permission scopes for https://graph.microsoft.com .PARAMETER UseAadGraph Set permission scopes for https://graph.windows.net .PARAMETER UserId If you set a UserId, then it will use User Consent .PARAMETER Scopes scope permissions .PARAMETER Expires Set the date when these consent scope permissions (OAuth2PermissionGrants) expire. .EXAMPLE Set-AadConsent -Id 'Your App Name' -Scopes 'User.Read Directory.Read.All' -UseMsGraph Applies Admin Consent for the Microsoft Graph permissions User.Read & Directory.Read.All .EXAMPLE Set-AadConsent -Id 'Your App Name' -Scopes 'User.Read Directory.Read.All' -UseMsGraph -UserId john@contoso.com Applies User Consent on user john@contoso.com for the Microsoft Graph permissions User.Read & Directory.Read.All .EXAMPLE Set-AadConsent -Id 'Your App Name' -Scopes 'user_impersonation' -ResourceId 'Custom Api' You can also consent for custom API .NOTES General notes #> function Set-AadConsent { [CmdletBinding(DefaultParameterSetName="All")] param ( [Parameter(mandatory=$true, Position=0, ValueFromPipeline = $true)] [string]$ClientId, [Parameter(mandatory=$true, ParameterSetName = 'UseOtherResource')] [string]$ResourceId, [Parameter(mandatory=$true, ParameterSetName = 'UseMsGraph')] [switch]$UseMsGraph, [Parameter(mandatory=$true, ParameterSetName = 'UseAadGraph')] [switch]$UseAadGraph, [Parameter(mandatory=$false)] [string]$Scopes, [Parameter(mandatory=$false)] [string]$Roles, [string]$UserId, $Expires = (Get-AadDateTime -AddMonths 12) ) # This CmdLet shows output Write-Host "" Write-Host "WARNING - Do not use this as a permanent solution. This is a workaround. " -ForegroundColor Yellow Write-Host "WARNING - Please ensure the Application registration is correctly configured." -ForegroundColor Yellow Write-Host "WARNING - Do not use this within your own Scipts to programmatically consent" -ForegroundColor Yellow Read-Host -Prompt "Press any key to continue or CTRL+C to quit" Write-Host "" $TenantDomain = $Global:AadSupport.Session.TenantId # -------------------------------------------------- # Check if signed in user is Global Admin (As only global admins can perform admin consent) $SignedInUser = Invoke-AadCommand -Command { Param($ObjectId) Get-AzureAdUser -ObjectId $ObjectId } -Parameters $Global:AadSupport.Session.AccountId $SignedInUserObjectId = $SignedInUser.ObjectId $AllDirectoryRoles = Invoke-AadCommand -Command { Get-AzureAdDirectoryRole } $GlobalAdminRoleId = ($AllDirectoryRoles | where { $_.displayName -eq 'Company Administrator' }).ObjectId $CompanyAdmins = Invoke-AadCommand -Command { Param($GlobalAdminRoleId) Get-AzureAdDirectoryRoleMember -ObjectId $GlobalAdminRoleId } -Parameters $GlobalAdminRoleId $isGlobalAdmin = ($CompanyAdmins).ObjectId -contains $SignedInUserObjectId if (-not $isGlobalAdmin) { Write-Host "Your account '$authUserId' is not a Global Admin in $TenantDomain." throw "Exception: GLOBAL ADMIN REQUIRED" } # Set ConsentType $ConsentType = "Admin" if($UserId) { $ConsentType = "User" } # Require ResourceId if (-not $ResourceId -and -not $UseMsGraph -and -not $UseAadGraph) { $ResourceId = Read-Host -Prompt "ResourceId" } # -------------------------------------------------- # GET SERVICE PRINCIPAL Object for app we want to udpate $ClientObjectId = $null $sp = Get-AadServicePrincipal -Id $ClientId if(-not $sp) { throw "'$ClientId' not found in '$TenantDomain'" } Write-Host "Enterprise App (ServicePrincipal) we will be updating" -ForegroundColor Yellow $sp | Select-Object DisplayName, AppId, ObjectId | Format-Table if($sp.count -gt 1) { throw "'$ClientId' query returned more than one result. Please provide a unique Service Principal Identifier" } $ClientObjectId = $sp.ObjectId # ------------------------------------------------ # GET PRINCIPAL ID # Get User to be used as PrincipalId (If ConsentType = User) $Oauth2PrincipalId = $null if ($ConsentType -eq "User") { $User = Invoke-AadCommand -Command { Param($UserId) Get-AzureADUser -ObjectId $UserId } -Parameters $UserId $Oauth2PrincipalId = ($User).ObjectId if (-not $Oauth2PrincipalId) { throw "'$UserId' does not exist in '$TenantDomain'" } } # ------------------------------------------------ # GET RESOURCE ID $ResourceObjectId = $null if ($UseMsGraph) { $resource = Invoke-AadCommand -Command { Get-AadServicePrincipal -Id '00000003-0000-0000-c000-000000000000' } $ResourceObjectId = $resource.ObjectId } elseif ($UseAadGraph) { $resource = Invoke-AadCommand -Command { Get-AadServicePrincipal -Id '00000002-0000-0000-c000-000000000000' } $ResourceObjectId = $resource.ObjectId } elseif ($ResourceId) { $resource = (Get-AadServicePrincipal -Id $ResourceId) $ResourceObjectId = $resource.ObjectId } if (-not $resource) { throw "'$ResourceId' not found in '$TenantDomain'" } if($resource.count -gt 1) { throw "The Resource query returned more than one result. Please provide a unique Service Principal Identifier" } Write-Host "Resource we will be adding permissions from..." -ForegroundColor Yellow $resource | Select-Object DisplayName, AppId, ObjectId | Format-Table # ------------------------------------------------ # GET SCOPES # Get current OAuth2PermissionGrant for Service Principal & Resource $OAuth2PermissionGrant = $null $SpOAuth2PermissionGrants = Invoke-AadCommand -Command { Param($ClientObjectId) Get-AzureADServicePrincipalOAuth2PermissionGrant -All $true -ObjectId $ClientObjectId } -Parameters $ClientObjectId # User Consent if ($Oauth2PrincipalId) { $OAuth2PermissionGrant = $SpOAuth2PermissionGrants | Where-Object {$_.ResourceId -eq $ResourceObjectId -and $_.PrincipalId -eq $Oauth2PrincipalId} # Admin Consent } else { $OAuth2PermissionGrant = $SpOAuth2PermissionGrants | Where-Object {$_.ResourceId -eq $ResourceObjectId -and $_.ConsentType -eq 'AllPrincipals'} } # Out-put current permission grant if ($OAuth2PermissionGrant) { Write-Host "Showing current Permission grant" -ForegroundColor Yellow $OAuth2PermissionGrant | Format-List -property * } else { Write-Host "No OAuth2PermissionGrants for $ClientId" } # ------------------------------------------------ # ROLES SECTION if($Roles) { # ------------------------------------------------ # GET ROLES $CurrentAppRoles = GetAadSpAppRoles -ClientObjectId $ClientObjectId -ResourceObjectId $ResourceObjectId $CurrentAppRoles | Format-List # ------------------------------------------------ # REMOVE ROLES foreach($role in $CurrentAppRoles) { Invoke-AadCommand -Command { Param($Params) Remove-AzureADServiceAppRoleAssignment -ObjectId $Params.ObjectId -AppRoleAssignmentId $Params.AppRoleAssignmentId } -Parameters @{ ObjectId = $ClientObjectId AppRoleAssignmentId = $role.RoleAssignedId } } # ------------------------------------------------ # ADD ROLES $SortedAppRoles = $resource.AppRoles | Sort-Object Value $AddRoles = $Roles.Split(" ") foreach($role in ($AddRoles)) { $RoleId = ($SortedAppRoles | where {$_.Value -eq $role}).Id if($RoleId) { Invoke-AadCommand -Command { Param($Params) New-AzureADServiceAppRoleAssignment -ObjectId $Params.ClientObjectId -Id $Params.RoleId -ResourceId $Params.ResourceObjectId -PrincipalId $Params.ClientObjectId } -Parameters @{ ClientObjectId = $ClientObjectId RoleId = $RoleId ResourceObjectId = $ResourceObjectId } } else { Write-Host "'$RoleId' not found on $($resource.DisplayName)" -ForegroundColor Yellow } } # ------------------------------------------------ # VERIFY ROLES GetAadSpAppRoles -ClientObjectId $ClientObjectId -ResourceObjectId $ResourceObjectId | Format-List } # ------------------------------------------------ # BUILD NEW PERMISSION GRANT #Build the permission grant if($Scopes -ne $null) { $newPermissionGrant = @{} $newPermissionGrant.Add("startTime", [System.DateTime]::UtcNow.AddMinutes(-5).ToString("o")) $newPermissionGrant.Add("expiryTime", $Expires) $newPermissionGrant.Add("scope", [string]::Join(' ', $scopes)) if(!$OAuth2PermissionGrant) { $newPermissionGrant.Add("clientId", $ClientObjectId) $newPermissionGrant.Add("resourceId", $ResourceObjectId) if ($Oauth2PrincipalId) { $newPermissionGrant.Add("principalId", $Oauth2PrincipalId) $newPermissionGrant.Add("consentType", "Principal") } else { $newPermissionGrant.Add("consentType", "AllPrincipals") } } $newPermissionGrant = $newPermissionGrant | ConvertTo-Json # ------------------------------------------------ # GET ACCESS TOKEN FOR AAD GRAPH $AccessToken = GetTokenForAadGraph # ------------------------------------------------ #Create the admin permission grant via graph api if ($OAuth2PermissionGrant) { $uri = "https://graph.windows.net/$TenantDomain/oauth2PermissionGrants/$($OAuth2PermissionGrant.ObjectId)/?api-version=1.6" Invoke-WebRequest -Uri $uri -Headers @{ "Authorization" = "Bearer " + $AccessToken } -Method Patch -Body $newPermissionGrant -ContentType "application/json" -Verbose | Format-List -Force } else { $uri = "https://graph.windows.net/$TenantDomain/oauth2PermissionGrants?api-version=1.6" Invoke-WebRequest -Uri $uri -Headers @{ "Authorization" = "Bearer " + $AccessToken } -Method Post -Body $newPermissionGrant -ContentType "application/json" -Verbose | Format-List -Force } $AccessToken = $null } # ------------------------------------------------ # VERIFY UPDATE Write-Host "Now showing current permission grant" -ForegroundColor Yellow $newOAuth2PermissionGrantResponse = Invoke-AadCommand -Command { Param($ClientObjectId) Get-AzureADServicePrincipalOAuth2PermissionGrant -All $true -ObjectId $ClientObjectId } -Parameters $ClientObjectId $newOAuth2PermissionGrant = $newOAuth2PermissionGrantResponse | where {$_.ResourceId -eq $ResourceObjectId -and $_.PrincipalId -eq $Oauth2PrincipalId} $newOAuth2PermissionGrant | Format-List if ($OAuth2PermissionGrant.scope -ne $newOAuth2PermissionGrant.scope) { Write-Host "SUCCESS!" -ForegroundColor Yellow } else { Write-Host "No changes occurred!" -ForegroundColor RED } } |