faitza.com
faitza.com
> blog_tech

Connexion Exchange Online en PowerShell — pourquoi pas l'API REST ?

Calcul... #powershell #exchange-online #microsoft-365 #oauth2

Pourquoi pas l'API REST ?

Toutes les APIs Microsoft ne fonctionnent pas de la même façon. Microsoft Graph, Azure Resource Manager, Azure DevOps ou Key Vault exposent des endpoints REST classiques : on obtient un Bearer token via Get-Faitza_Modul_Headers, on appelle Invoke-RestMethod, c'est fini.

Exchange Online est une exception. Certes, Microsoft Graph expose quelques endpoints pour les boîtes mail (/users/{id}/messages, /users/{id}/mailFolders…), mais ils ne couvrent qu'une fraction des opérations d'administration Exchange. Des fonctionnalités essentielles comme :

  • Créer ou convertir une boîte partagée (New-Mailbox, Set-Mailbox -Type Shared)
  • Gérer les délégations (Add-MailboxPermission, Add-RecipientPermission)
  • Administrer les règles de transport, les connecteurs, les politiques de rétention
  • Lister l'ensemble des boîtes avec leurs propriétés Exchange natives

…ne sont disponibles que via les cmdlets du module ExchangeOnlineManagement. Il n'existe pas d'endpoint REST équivalent pour ces opérations. Une connexion au module est donc toujours obligatoire pour administrer Exchange Online en PowerShell.

Graph vs Exchange Online Management

Microsoft Graph convient pour lire des emails, gérer des calendriers ou des contacts depuis une application. Le module ExchangeOnlineManagement est indispensable pour toute administration Exchange : boîtes partagées, délégations, quotas, audit logs Exchange, règles de flux de messagerie.

Le module ExchangeOnlineManagement

Le module officiel s'installe depuis la PowerShell Gallery :

Install-Module -Name ExchangeOnlineManagement -Scope CurrentUser -Force

La connexion standard se fait via Connect-ExchangeOnline. En environnement interactif, une fenêtre de login s'ouvre. En environnement automatisé, on passe un token Bearer obtenu depuis Azure CLI via le paramètre -AccessToken — c'est ce que fait Connect-Faitza_Modul_ExchangeOnline.

La ressource OAuth2 attendue pour Exchange Online est https://outlook.office365.com/. Elle est différente de la ressource Graph : un token Graph ne fonctionnera pas ici.

Connect-Faitza_Modul_ExchangeOnline

La fonction est définie dans Faitza_Function/Faitza_Modul/Faitza_Modul.ps1, aux côtés de Get-Faitza_Modul_Headers. Elle encapsule le flux complet : import silencieux du module, détection d'une session existante (idempotent), récupération du token via Azure CLI, connexion.

function Connect-Faitza_Modul_ExchangeOnline {
    [CmdletBinding()]
    param(
        [string]$organization = "faitza.onmicrosoft.com",
        [switch]$deco
    )

    Write-Host "$($PSStyle.Background.Red)>>> Connect-Faitza_Modul_ExchangeOnline <<<$($PSStyle.Reset)"

    try {
        if ($deco) {
            Disconnect-ExchangeOnline -Confirm:$false -ErrorAction SilentlyContinue | Out-Null
            Write-Host "Déconnexion Exchange effectuée."
            return
        }

        # Import silencieux du module pour éviter les warnings
        $oldErrPref = $ErrorActionPreference
        $ErrorActionPreference = 'SilentlyContinue'
        try { Import-Module ExchangeOnlineManagement -ErrorAction SilentlyContinue } catch {}
        $ErrorActionPreference = $oldErrPref

        # Vérification de session existante — idempotent
        if (Get-ConnectionInformation -ErrorAction SilentlyContinue) {
            Write-Host "Déjà connecté à Exchange Online."
            return "Connect : OK"
        }

        # Token obtenu via Azure CLI (ressource outlook.office365.com)
        $Token = az account get-access-token `
            --resource "https://outlook.office365.com/" `
            --query accessToken -o tsv

        if ([string]::IsNullOrWhiteSpace($Token)) {
            throw "Le jeton retourné par Azure CLI est vide."
        }

        Connect-ExchangeOnline `
            -Organization $organization `
            -AccessToken  $Token `
            -ShowBanner:$false `
            -ErrorAction Stop

        $domain = Get-AcceptedDomain | Where-Object { $_.Default -eq $true }
        Write-Host "$($PSStyle.Foreground.BrightGreen)Connexion Exchange réussie : $($domain.Name)$($PSStyle.Reset)"
        return "Connect : $($domain.Name)"

    } catch {
        throw "Erreur connexion ExchangeOnline : $_"
    } finally {
        Write-Host "$($PSStyle.Background.Red)<<< Connect-Faitza_Modul_ExchangeOnline >>>$($PSStyle.Reset)"
    }
}

Points clés :

  • Import silencieuxExchangeOnlineManagement affiche des warnings à l'import. La fonction coupe temporairement $ErrorActionPreference pour les supprimer.
  • IdempotenceGet-ConnectionInformation détecte si une session Exchange est déjà active. Si c'est le cas, la fonction sort immédiatement sans reconnecter.
  • Token via Azure CLIaz account get-access-token retourne un token pour la ressource outlook.office365.com. Ce token est passé directement à Connect-ExchangeOnline.
  • Switch -deco — Déconnecte proprement la session Exchange en fin de script.

Utilisation

En début de script Exchange, on appelle la fonction une fois. Toutes les cmdlets Exchange sont ensuite disponibles dans la session jusqu'à la déconnexion.

# Connexion
Connect-Faitza_Modul_ExchangeOnline

# Cmdlets Exchange disponibles dès maintenant
$mailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails SharedMailbox
$mailboxes | Select-Object DisplayName, PrimarySmtpAddress

# Déconnexion en fin de script
Connect-Faitza_Modul_ExchangeOnline -deco

Voir l'article Exchange Online — boîtes partagées, délégations et automatisation pour des exemples complets avec Get-Faitza_Exchange_SharedMailbox, Add-Faitza_Exchange_MailboxDelegation, etc.

Liens Microsoft

Pièges

Token Graph ≠ token Exchange

La ressource pour Exchange Online est https://outlook.office365.com/, pas https://graph.microsoft.com. Un token obtenu avec Get-Faitza_Modul_Headers -resource "graph" sera rejeté par Connect-ExchangeOnline.

Droits nécessaires sur le compte de service

Le compte ou la Managed Identity utilisé doit avoir le rôle Exchange approprié dans Microsoft 365 (ex. Exchange Administrator ou un rôle RBAC Exchange personnalisé). Un token valide ne suffit pas si le compte n'a pas les permissions Exchange.

Déconnecter en fin de script

Toujours appeler Connect-Faitza_Modul_ExchangeOnline -deco en fin de script pour libérer la session Exchange côté serveur. Les sessions abandonnées consomment des ressources et peuvent atteindre les limites de connexion simultanées.

// Commentaires

Aucun commentaire pour l'instant.