Lors d'un offboarding ou d'un changement de rôle, révoquer les licences et les accès ne suffit pas : les réunions Teams organisées par l'utilisateur sortant continuent d'exister sous un organisateur inactif. Gérer ce cas manuellement est chronophage et source d'erreurs, en particulier pour les séries récurrentes. Cet article s'adresse aux administrateurs Exchange Online et Teams qui souhaitent automatiser ce transfert de façon fiable et auditable.
Pourquoi le transfert d'organisateur est un angle mort de l'offboarding
Quand un utilisateur quitte l'organisation, ses réunions récurrentes continuent d'apparaître dans les agendas des participants. Sans intervention, personne ne peut modifier les paramètres, ajouter ou retirer des participants, ni mettre à jour le lien Teams. L'organisateur reste nominalement propriétaire alors que son compte est désactivé ou supprimé.
Microsoft a comblé ce vide en introduisant la cmdlet Invoke-ChangeMeetingOrganizer dans Exchange Online PowerShell. Elle permet de transférer la propriété d'une réunion Teams d'un utilisateur à un autre, sans avoir à annuler et recréer chaque réunion manuellement.
Cependant, cette cmdlet ne dispose d'aucun mécanisme natif de découverte : elle transfère une réunion dont vous lui fournissez l'identifiant, mais ne cherche pas elle-même quelles réunions sont éligibles. C'est précisément ce que comble le script décrit dans cet article.
Le piège des réunions récurrentes avec Get-MgUserDefaultCalendarEvent
La majorité des scripts de transfert de calendrier disponibles reposent sur Get-MgUserEvent ou Get-MgUserDefaultCalendarEvent avec un filtre de dates. Cette approche présente une lacune critique pour les séries récurrentes.
Une série hebdomadaire créée il y a deux ans ne sera pas retournée par un filtre qui cible les événements créés dans les 90 derniers jours, même si elle a des occurrences futures dans cette fenêtre. Résultat : des réunions actives passent à travers les mailles du filet.
Attention aux séries récurrentes
Un filtre de date appliqué à Get-MgUserEvent cible la date de création ou de début de la série, pas ses occurrences futures. Des réunions récurrentes en cours peuvent donc être ignorées silencieusement.
Le script présenté ici utilise à la place Get-MgUserCalendarView, qui retourne les occurrences effectives dans une fenêtre temporelle donnée, puis regroupe les résultats par SeriesMasterId pour identifier les séries complètes. Chaque série n'est traitée qu'une seule fois, même si elle contient des dizaines d'occurrences dans la période.
Prérequis avant d'exécuter le script
Avant de lancer le script, vérifiez les points suivants :
- Rôle Exchange Online :
Organization ManagementouRecipient Management. Ces deux rôles accordent les droits nécessaires àInvoke-ChangeMeetingOrganizer. - Nouvel organisateur : doit obligatoirement disposer d'une boîte aux lettres utilisateur dans le même tenant Exchange Online.
- Types de boîtes aux lettres supportés : boîtes utilisateur uniquement. Les boîtes partagées, de salle et de groupe sont exclues automatiquement.
- Modules PowerShell : Exchange Online Management et Microsoft Graph Calendar. Le script les installe automatiquement s'ils sont absents.
Deux modes d'authentification disponibles
Le script propose deux méthodes d'exécution selon le contexte opérationnel.
Méthode 1 : authentification déléguée (interactive)
Cette méthode convient aux exécutions ponctuelles avec un compte administrateur. Elle requiert que l'application Microsoft Graph dispose de la permission déléguée Calendars.Read.Shared.
1.\ChangeMeetingOrganizer.ps1 -CurrentOrganizer <CurrentOrganizer> -NewOrganizer <NewOrganizer> -TransferPérimètre limité en mode délégué
En authentification déléguée, le script ne peut lire que les calendriers accessibles au compte connecté : boîtes avec accès total (Full Access) ou calendriers explicitement partagés. Pour couvrir l'ensemble du tenant, utilisez la méthode 2.
Méthode 2 : authentification par certificat (non interactive)
Cette méthode est recommandée pour les exécutions planifiées ou les transferts à grande échelle. Elle ne dépend pas des permissions calendrier de l'administrateur connecté et couvre toutes les boîtes aux lettres du tenant.
Enregistrez au préalable une application dans Microsoft Entra et configurez les permissions applicatives suivantes :
- Microsoft Graph :
Calendars.ReadetUser.Read.All - Office 365 Exchange Online :
Exchange.ManageAsApp
1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -Transfer `5 -TenantId <TenantId> `6 -ClientId <ClientId> `7 -CertificateThumbprint <CertificateThumbprint> `8 -Organization <DomainName>L'authentification peut s'appuyer sur un certificat d'une autorité de certification (CA) ou sur un certificat auto-signé.
Capacités avancées du script
Transfert en masse via fichier CSV
Pour traiter plusieurs utilisateurs en une seule exécution, préparez un fichier CSV avec deux colonnes : CurrentOrganizer et NewOrganizer. Chaque ligne correspond à une paire organisateur actuel / nouvel organisateur, au format UPN.

1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -TenantId <TenantID> `5 -ClientId <ClientID> `6 -CertificateThumbprint <CertificateThumbprint> `7 -Organization <DomainName> `8 -TransferLorsque le paramètre -CurrentOrganizer reçoit le chemin du fichier CSV, le script parcourt chaque paire et effectue les transferts en série.
Fenêtre temporelle personnalisée avec -DaysAhead
Par défaut, le script découvre les réunions dont la prochaine occurrence tombe dans les 365 jours suivant l'exécution. Pour des réunions annuelles ou des jalons long terme, ce délai peut être insuffisant.
Le paramètre -DaysAhead permet d'étendre cette fenêtre. Par exemple, -DaysAhead 730 couvre les deux prochaines années :
1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -Transfer `5 -DaysAhead 730Exclusion des réunions imminentes avec -MinimumLeadHours
Transférer une réunion qui démarre dans l'heure peut déclencher des notifications inattendues pour les participants. Le paramètre -MinimumLeadHours permet d'ignorer les réunions dont le démarrage est trop proche. Les réunions exclues sont consignées avec le statut Skipped dans le rapport CSV pour un traitement ultérieur.
1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -Transfer `5 -MinimumLeadHours 24Inclure les rendez-vous personnels
Par défaut, le script ignore les événements sans participants (rendez-vous personnels, blocs de concentration). Pour les inclure lors d'une migration de boîte complète, utilisez -IncludeAppointmentsWithoutAttendees :
1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -Transfer `5 -IncludeAppointmentsWithoutAttendeesCombinaison de filtres
Les paramètres sont cumulables. Pour transférer uniquement les réunions démarrant au minimum dans 24 heures et dont la prochaine occurrence tombe dans les 500 prochains jours :
1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -Transfer `5 -MinimumLeadHours 24 `6 -DaysAhead 500Mode rapport et sorties générées
Le script fonctionne en mode rapport par défaut : il analyse les calendriers et identifie les réunions éligibles sans effectuer aucun transfert. Ce mode permet de valider le périmètre avant toute action.
L'ajout du paramètre -Transfer déclenche les transferts effectifs. Le script demande alors de saisir TRANSFER pour confirmer l'opération.

À chaque exécution, un rapport CSV est généré avec le détail de chaque réunion traitée :
- Organisateur actuel et nouvel organisateur
- Sujet et type de réunion
- Présence d'un lien Teams (réunion en ligne)
- Heure de début en UTC
- Liste des participants
- Statut :
Success,SkippedouFailed - Raison de l'échec le cas échéant
- Identifiant de l'événement

Réunions Teams récurrentes : limite à connaître
Pour les séries récurrentes associées à une réunion Teams en ligne, le transfert met à jour l'organisateur dans le calendrier Exchange, mais ne change pas la propriété de la réunion Teams sous-jacente. Le nouvel organisateur doit mettre à jour la série avec de nouveaux paramètres Teams pour en prendre le contrôle complet.
Planification avec le Planificateur de tâches Windows
Pour les environnements où de nouvelles réunions peuvent apparaître régulièrement sous un ancien organisateur, une exécution planifiée évite les vérifications manuelles récurrentes.
Configurez une tâche dans le Planificateur de tâches Windows (Task Scheduler) avec le paramètre -Unattended, qui supprime toutes les invites interactives et permet une exécution silencieuse en arrière-plan :
1.\ChangeMeetingOrganizer.ps1 `2 -CurrentOrganizer <CurrentOrganizer> `3 -NewOrganizer <NewOrganizer> `4 -TenantId <TenantID> `5 -ClientId <ClientID> `6 -CertificateThumbprint <CertificateThumbprint> `7 -Organization <DomainName> `8 -Transfer `9 -UnattendedEmplacement des rapports en mode planifié
Lorsque le script est exécuté via le Planificateur de tâches, les rapports CSV sont sauvegardés dans C:\Windows\System32. Prévoyez un emplacement de sortie personnalisé si ce répertoire ne correspond pas à votre politique de gestion des logs.
Ce qu'il faut retenir avant lundi matin
Le script ChangeMeetingOrganizer.ps1 comble les lacunes de Invoke-ChangeMeetingOrganizer utilisée seule : il assure la découverte des réunions éligibles, gère correctement les séries récurrentes via Get-MgUserCalendarView et SeriesMasterId, et produit un rapport d'audit exploitable.
Pour démarrer efficacement :
- Commencez systématiquement par une exécution sans
-Transferpour valider le périmètre détecté. - Utilisez la méthode 2 (certificat) dès que vous devez couvrir plus d'une poignée de boîtes aux lettres ou automatiser le processus.
- Intégrez le paramètre
-MinimumLeadHours 24dans vos procédures d'offboarding pour éviter les notifications de dernière minute. - Si votre organisation gère des réunions annuelles ou pluriannuelles, ajustez
-DaysAheaden conséquence, la valeur par défaut de 365 jours peut être insuffisante.
Si la gestion des identités et des accès lors des transitions d'utilisateurs est un sujet récurrent dans votre environnement, combiner ce script avec une procédure d'offboarding automatisée dans Microsoft Entra apporte une couverture plus complète du cycle de vie des comptes.


