Code/Function/Public/Add-MGApplicationAPIPermission.ps1

Function Add-MGApplicationAPIPermission {
    <#
        .SYNOPSIS
        This function adds API permission to azure ad application.
 
        .DESCRIPTION
        This function adds API permission to a azure ad application. It also automatically grants the permission.
 
        .PARAMETER ApplicationId
        ID of the application which will get new permissions.
 
        .PARAMETER ApplicationAPIPermissionId
        ID of the new permission. You can find those permissions with this command: Find-MgGraphPermission
 
        .PARAMETER APIPermissionType
        Type of API Permission. Role is used by default.
 
        .PARAMETER Wait
        The wait parameter must be used in loops and scripts.
        If you do not use this parameter the function will exceed before the new permissions are set in azure ad.
        Otherwise the new permissions aren't set successfully.
 
        .INPUTS
        String
        Switch
 
        .OUTPUTS
        None
 
        .EXAMPLE
        Add-MGApplicationAPIPermission -ApplicationId $Application.Id -ApplicationAPIPermissionId $_.Id -Wait $true
 
        .LINK
        https://github.com/gisp497/psgisp
    #>

    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory = $true,
            HelpMessage = 'ID of the application which will get new permissions.'
        )]
        [String]$ApplicationId,
        [Parameter(
            Mandatory = $true,
            HelpMessage = 'ID of the new permission. You can find those permissions with this command: Find-MgGraphPermission'
        )]
        [String]$ApplicationAPIPermissionId,
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'Type of API Permission. Role is used by default.'
        )]
        [ValidateSet('Role', 'Scope')]
        [String]$APIPermissionType = 'Role',
        [Parameter(
            Mandatory = $false,
            HelpMessage = 'help message'
        )]
        [Switch]$Wait = $false
    )
    Begin {
        #check authentication status
        if($null -eq (Get-MgContext)){
            Throw 'First authenticate to Microsoft Graph!'
        }

        #Get Application existing Permisisons
        $Application = Get-MgApplication -ApplicationId $ApplicationId

        #Get Service Principal for App Role
        $MGServicePrincipal = Get-MgServicePrincipal -All -Property Id,DisplayName,AppId,Approles | Where-Object{$_.AppRoles.Id -eq $ApplicationAPIPermissionId}
        if ($null -eq $MGServicePrincipal) {
            Throw ('The Application API Permissions Id: ' + $ApplicationAPIPermissionId + ' cannot be found. This function can only use Application Permission Type')
        }
        
        #Get Service Principal of App $Application
        $ApplicationServicePrincipal = Get-MgServicePrincipal -All | Where-Object {$_.AppId -eq $Application.AppId}
    }
    Process {
        #############################################
        ######Add API permission to application######
        #############################################
        #create new permissions
        $NewResourceAccess = @(
            @{  
                ResourceAppId = $MGServicePrincipal.AppId; 
                ResourceAccess = @( 
                    @{ 
                        id = $ApplicationAPIPermissionId;  
                        type = $APIPermissionType; 
                    }
                ) 
            }
        )

        ## Get the existing permissions of the application
        $ExistingResourceAccess = $Application.RequiredResourceAccess

        #If the permission is already setted do nothiung
        if ($null -ne ($ExistingResourceAccess | Where-Object {$_.ResourceAccess.Id -eq $ApplicationAPIPermissionId})) {
            Write-Warning ('Permission ' + $ApplicationAPIPermissionId + ' does already exist')
        }
        #if no permissions are setted
        elseif($null -eq $ExistingResourceAccess.ResourceAppId){
            #Update Application settings
            Update-MgApplication -ApplicationId $Application.Id -RequiredResourceAccess $NewResourceAccess
        }
        #If this specific permission is not setted already
        else {
            #set loop for all existing permissions
            $ExistingResourceAccess | ForEach-Object{
                #check the current serviceprincipal is the same es the new permission
                if($_.ResourceAppId -ne $MGServicePrincipal.AppId) {
                    #add existing permission to hashtable and afterwards to $NewResourceAccess Variable
                    $NewResourceAccessVar = @{  
                        ResourceAppId = $_.ResourceAppId; 
                        ResourceAccess = @() 
                    }
                    $_.ResourceAccess | ForEach-Object {
                        $NewResourceAccessVar.ResourceAccess += @{ 
                            id = $_.Id;  
                            type = $_.type; 
                        }
                    }
    
                    #add new created hashtable to $NewResourceAccess Hashtable
                    $NewResourceAccess += $NewResourceAccessVar
                }else {
                    #add existing permission for the same serviceprincipal
                    $_.ResourceAccess | ForEach-Object {
                        ($NewResourceAccess | Where-Object {$_.ResourceAppId -eq $MGServicePrincipal.AppId}).ResourceAccess += @{ 
                            id = $_.Id;  
                            type = $_.type; 
                        }
                    }
                }
            }

            #Update Application settings
            Update-MgApplication -ApplicationId $Application.Id -RequiredResourceAccess $NewResourceAccess
        }

        ################################################
        ######Grant API permission for application######
        ################################################
        #Create hashtable for new ServicePrincipalAppRoleAssignedTo
        $Params = @{
            PrincipalId = $ApplicationServicePrincipal.Id
            ResourceId = $MgServicePrincipal.Id
            AppRoleId = $ApplicationAPIPermissionId
        }
        
        #check if assigment already exists
        if ($null -eq (Get-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $Params.ResourceId | Where-Object {$_.PrincipalId -eq $Params.PrincipalId -and $_.ResourceId -eq $Params.ResourceId -and $_.AppRoleId -eq $Params.AppRoleId})) {
            New-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $MgServicePrincipal.Id -BodyParameter $Params > $null
        }else {
            Write-Warning ('Permission ' + $ApplicationAPIPermissionId + ' is already granted')
        }

        #if Wait parameter is used, wait until new application permission are set before exiting funtion
        while ($true) {
            if ($null -ne (Get-MgApplication -ApplicationId $Application.Id | Where-Object {$_.RequiredResourceAccess.ResourceAccess.Id -eq $ApplicationAPIPermissionId})) {
                Break
            }else {
                Start-Sleep -Seconds 1
            }
        }
    }
    End {
    }
}