Private/PartnerActions/New-CustomPartnerAccessToken.ps1

function New-CustomPartnerAccessToken() {
    param(
        [Parameter(Mandatory)]
        [String]
        $Scopes,
        [Parameter(Mandatory)]
        [String]
        $CustomerTenantId,
        [Parameter()]
        [bool]$Retry
    )

    begin {
        if (!$SAMTokens) {
            $SAMTokens = Get-SAMTokens
        }  
    }
    process {

        # Connect to the partner center using our application
        $RequestBody = @{
            client_id     = $SAMTokens.ApplicationId
            client_secret = $SAMTokens.ApplicationSecret
            grant_type    = "refresh_token"
            refresh_token = $SAMTokens.RefreshToken
            scope         = $Scopes
        }
        $authEndpoint = "https://login.microsoftonline.com/$($CustomerTenantId)/oauth2/v2.0/token"

        # Get the access token needed for subsequent requests
        try {
            $Response = Invoke-WebRequest -Uri $authEndpoint -Method POST -Body $RequestBody -ContentType 'application/x-www-form-urlencoded'
            $AccessToken = ($Response.Content | ConvertFrom-Json).access_token
        } catch {
            if($_.ErrorDetails.Message -like "*The user or administrator has not consented*" -and !$Retry) {
                Write-Host "Failed to connect due to missing application consent." -ForegroundColor Yellow
                if($Scopes -eq "https://outlook.office365.com/.default") {
                    Connect-CustomerGraph -CustomerTenantId $CustomerTenantId
                    $ExchangeServicePrincipal = Get-MgServicePrincipal -Filter "appId eq '00000002-0000-0ff1-ce00-000000000000'"
                    if(!$ExchangeServicePrincipal) {
                        throw "Failed to find Exchange Online service principal. The customer does not have Exchange Online - and therefore connection is impossible."
                    } else {
                        Write-Host "Found Exchange Online service principal, so we can try to consent to it."
                    }
                }
                Write-Host "Trying to get consent, and then re-trying connection attempt." -ForegroundColor Yellow
                Set-SAMConsent -CustomerTenantId $CustomerTenantId
                New-CustomPartnerAccessToken -Scopes $Scopes -CustomerTenantId $CustomerTenantId -Retry:$true
            } else {
                throw "Failed to get access token: $_"
            }
        }
        
        return $AccessToken 
    }
}