Private/Consent/Set-ApplicationRoles.ps1

function Set-ApplicationRoles {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string]$CustomerTenantId
    )

    try {
        # Connect and verify required permissions
        Connect-CustomerGraph -CustomerTenantId $CustomerTenantId -FlowType "Delegated" -Force
        $GraphContext = Get-MgContext

        while (!$GraphContext.Scopes.Contains("RoleManagement.ReadWrite.Directory")) {
            Write-ModuleLog -Message "RoleManagement.ReadWrite.Directory permission is missing in the token, re-connecting until we have it." -Level Info -Component 'ApplicationConsent'
            Disconnect-Graph -ErrorAction SilentlyContinue | Out-Null
            Start-Sleep -Seconds 10
            Connect-CustomerGraph -CustomerTenantId $CustomerTenantId -FlowType "Delegated" -Force
            $GraphContext = Get-MgContext
        }

        # Get Service Principal and Customer details
        $ServicePrincipalList = Get-MgServicePrincipal -All
        $ServicePrincipal = $ServicePrincipalList | Where-Object { $_.AppId -eq $script:PartnerCredentials.ApplicationId }
        $Customer = Get-MgOrganization

        # Assign "Compliance Administrator" role
        $ComplianceAdministratorRole = Get-MgDirectoryRole | Where-Object { $_.DisplayName -eq "Compliance Administrator" }
        $ComplianceAdministrators = Get-MgDirectoryRoleMemberAsServicePrincipal -DirectoryRoleId $ComplianceAdministratorRole.Id -ErrorAction Stop
        if ($ComplianceAdministrators.Id -notcontains $ServicePrincipal.Id) {
            New-MgDirectoryRoleMemberByRef -DirectoryRoleId $ComplianceAdministratorRole.Id -BodyParameter @{"@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($ServicePrincipal.Id)" } -ErrorAction Stop
            Write-ModuleLog -Message "Assigning Compliance Administrator role to service principal" -Level Info -Component 'ApplicationConsent'
        }

        # Assign "Exchange Administrator" role
        $ExchangeAdministratorRole = Get-MgDirectoryRole | Where-Object { $_.DisplayName -eq "Exchange Administrator" }
        $ExchangeAdministrators = Get-MgDirectoryRoleMemberAsServicePrincipal -DirectoryRoleId $ExchangeAdministratorRole.Id -ErrorAction Stop
        if ($ExchangeAdministrators.Id -notcontains $ServicePrincipal.Id) {
            New-MgDirectoryRoleMemberByRef -DirectoryRoleId $ExchangeAdministratorRole.Id -BodyParameter @{"@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($ServicePrincipal.Id)" } -ErrorAction Stop
            Write-ModuleLog -Message "Assigning Exchange Administrator role to service principal" -Level Info -Component 'ApplicationConsent'
        }

        Write-ModuleLog -Message "Successfully configured application permissions for $($Customer.DisplayName)" -Level Info -Component 'ApplicationConsent'

        # Cleanup connection
        if ($GraphContext) {
            Disconnect-Graph -ErrorAction SilentlyContinue | Out-Null
        }
    }
    catch {
        Write-ModuleLog -Message "Failed to set up application roles: $($_.Exception.Message)" -Level Error -Component 'ApplicationConsent' -ErrorRecord $_ -ThrowError
    }
}