Public/TenantConnection/Connect-CustomerExchange.ps1

function Connect-CustomerExchange {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$CustomerTenantId,
        [Parameter()]
        [bool]$Retry
    )
    # Get SAM tokens if not already available
    begin {
        if (!$SAMTokens) {
            $SAMTokens = Get-SAMTokens
        }  
    }
    
    # Generate a token for MS graph, and connect with it.
    process {
        try {
            # Try to re-use existing connections
            $ConnectionInformation = Get-ConnectionInformation -ErrorAction SilentlyContinue
            if ($ConnectionInformation.DelegatedOrganization -eq $Global:Tenant.DefaultDomainName -and $Global:ExchangeToken -and $Global:ExchangeToken.expirationDateTime -gt (Get-Date)) {
                Write-Host "Re-using existing EXO connection..." -ForegroundColor DarkGray
                return
            }
            else {
                Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue
            }
        }
        catch {
            throw "Failed to disconnect from Exchange Online: $_"
        }

        try {
            $Global:ExchangeToken = New-CustomPartnerAccessToken -Scopes 'https://outlook.office365.com/.default' -TenantId $CustomerTenantId
        }
        catch {
            throw "Failed to generate a token for Exchange Online: $_"
        }
        if ($Global:ExchangeToken) {
            if($Global:Tenant.CustomerId -ne $CustomerTenantId) {
                try {
                    $Global:Tenant = Get-Tenants -TenantId $CustomerTenantId
                } catch {
                    throw "Failed to get customer information: $_"
                }
            }
            try {
                if($Global:Tenant.DefaultDomainName -notlike "*.onmicrosoft.com") {
                    Connect-CustomerGraph -CustomerTenantId $CustomerTenantId
                    $Global:Tenant.DefaultDomainName = Get-MgDomain | Where-Object { $_.IsInitial -eq $true } | Select-Object -ExpandProperty Id
                }
                Connect-ExchangeOnline -AccessToken $Global:ExchangeToken.access_token -ShowBanner:$false -DelegatedOrganization $Global:Tenant.DefaultDomainName -AppId "fa997c67-0d57-4882-bf3d-dfb16c40495c"
            }
            catch {
                if ($Retry -eq $true) {
                    throw "Failed to connect to Exchange Online: $_"
                    return
                }
                Write-Host "Failed to connect to Exchange Online - perhaps they have not consented to our application correctly? Trying.." -ForegroundColor Yellow
                Set-SAMConsent -CustomerTenantId $CustomerTenantId
                Connect-CustomerExchange -CustomerTenantId $CustomerTenantId -Retry:$true
            }
        }
    }
}