Comment générer un rapport des équipes Teams avec PowerShell ?

I. Présentation

Dans ce tutoriel, nous allons utiliser PowerShell pour générer un rapport complet sur les équipes Teams de votre tenant Office 365 : liste des équipes, des canaux, des propriétaires, du nombre de membres, etc.

Depuis plus d'un an maintenant, Microsoft Teams est devenu un outil incontournable pour de nombreux établissements scolaires et de nombreuses entreprises. Néanmoins, savez-vous combien il y a d'équipes Teams sur votre tenant Office 365 ? Savez-vous qui sont les propriétaires des équipes Teams ? Connaissez-vous la liste des canaux présents dans chaque équipe Teams ? Est-ce qu'il y a des équipes Teams qui contiennent des invités ? Etc... Tout autant de questions que l'on peut se poser.

Je vous propose de créer un script PowerShell qui va nous permettre de générer un rapport Teams (dans un fichier CSV) avec les informations suivantes :

  • Nom de l'équipe Teams
  • Date de création de l'équipe
  • Liste des canaux de l'équipe
  • Liste des propriétaires de l'équipe
  • Nombre de membres dans l'équipe
  • Nombre d'invités dans l'équipe
  • Type d'accès pour cette équipe

Si vous êtes prêt, on va commencer à scripter... J'en profite pour mentionner ces deux articles qui pourraient vous intéresser :

Comment gérer ses équipes Teams avec PowerShell ?

Comment créer des équipes Teams en masse ?

II. Prérequis

Pour exécuter ce script, vous avez besoin de PowerShell bien sûr, mais surtout de deux modules PowerShell spécifiques :

  • Exchange Online Management
Install-Module -Name ExchangeOnlineManagement
  • Microsoft Teams
Install-Module -Name MicrosoftTeams

Nous allons exploiter des commandes de ces deux modules. Il faudra ensuite initier une connexion sur ces deux services à l'aide d'un compte Administrateur du tenant Office 365 :

Connect-ExchangeOnline
Connect-MicrosoftTeams

III. Script PowerShell - Rapport Teams

Nous allons y aller par étape pour que vous puissiez bien comprendre ce que l'on fait, et en fin d'article je vais vous mettre le code complet du script PowerShell.

A. Récupérer la liste de toutes les équipes Teams

Notre point de départ, ce sera la liste de toutes les équipes Teams du tenant que l'on va stocker dans la variable $TeamList. On gardera seulement deux propriétés : le nom d'affichage de l'équipe (DisplayName) et l'identifiant unique (GroupID)

$TeamList = Get-Team | Select-Object DisplayName,GroupID

Pour ma part, j'ai quatre équipes :

B. Une boucle Foreach pour traiter chaque équipe Teams

Pour chaque équipe contenue dans $TeamList, nous allons devoir récupérer des informations. Du coup, on va utiliser une boucle Foreach pour traiter chaque ligne de l'objet $TeamList.

Foreach ($Team in $TeamList)
{
 <traitement>
}

Maintenant, nous allons remplir la partie "<traitement>" pour récupérer les informations que l'on souhaite. Pour commencer, on peut déjà stocker en variable le nom de l'équipe et l'identifiant unique : deux informations que l'on connaît déjà.

# GUID Equipe
$TeamGUID = $($Team.GroupId).ToString()

# Nom de l'équipe
$TeamName = $Team.DisplayName

C. Date de création de l'équipe Teams

Dans la variable $TeamCreationDate, nous allons stocker la date de création de l'équipe Teams. Pour récupérer cette information avec PowerShell, il faut ruser un petit peu... Lorsqu'une équipe Teams est créée, il y a un groupe unifié Office 365 qui est créé automatiquement (et un site SharePoint aussi, d'ailleurs).

Grâce à la commande Get-UnifiedGroup et au GUID de l'équipe Teams, on va pouvoir récupérer la valeur de la propriété WhenCreated : elle contient la date et l'heure de création de ce groupe, et donc de l'équipe. Il y a une alternative, récupérer la date et l'heure au format UTC, dans ce cas il faudrait utiliser "WhenCreatedUTC".

# Date de création de l'équipe
$TeamCreationDate = Get-UnifiedGroup -Identity $TeamGUID | Select -ExpandProperty WhenCreated

D. Liste des canaux de l'équipe Teams

Seconde information que l'on va récupérer : la liste des canaux de l'équipe Teams. Cette fois-ci, c'est le cmdlet Get-TeamChannel que l'on va utiliser et on va cibler l'équipe grâce à son identifiant unique. On récupérera seulement le nom d'affichage de chaque canal.

Voici comment obtenir cette information et la stocker dans $TeamChannels :

# Canaux de l'équipe
$TeamChannels = (Get-TeamChannel -GroupId $TeamGUID).DisplayName

E. Liste des propriétaires de l'équipe Teams

Pour récupérer la liste des propriétaires de l'équipe, on va utiliser Get-TeamUser. Cette commande permet de lister aussi bien les propriétaires, que les membres et les invités. Ce qui nous oblige à appliquer un filtre supplémentaire sur la propriété "Role" qui est égale à "Owner" lorsqu'il s'agit d'un propriétaire.

# Propriétaires de l'équipe
$TeamOwner = (Get-TeamUser -GroupId $TeamGUID | Where{$_.Role -eq 'Owner'}).User

F. Nombre de membres dans l'équipe Teams

Toujours avec le même cmdlet, nous allons pour récupérer le nombre de membres présent dans l'équipe Teams. J'ai pris la décision de seulement compter le nombre de membres plutôt que de récupérer la liste nominative, mais c'est possible aussi.

Cette fois-ci, le filtre "Role" doit être égal à "Member" et on s'appuiera sur Count pour compter le nombre de membres. De cette façon, nous ne comptons pas les propriétaires dans la liste des membres.

Nous ajoutons une condition "if" pour tester la variable $TeamUserCount qui contient le nombre de membres. Si elle est nulle, c'est-à-dire qu'il n'y a pas de membre dans l'équipe, on force la valeur à 0. C'est un cas de figure possible.

# Nombre de membres dans l'équipe
$TeamUserCount = (Get-TeamUser -GroupId $TeamGUID | Where{$_.Role -eq 'Member'}).Count
if ($TeamUserCount -eq $null){ $TeamUserCount = 0 }

G. Liste des invités de l'équipe Teams

Pour récupérer la liste des invités de l'équipe Teams, toujours sur le même principe sauf que le filtre "Role" doit être égal à "Guest". Pour les invités, je pense que c'est intéressant d'obtenir la liste, cela permettra de voir s'il y a des adresses un peu suspectes dans les invités.

Au-delà du rôle, lorsqu'un utilisateur est membre d'une équipe en tant qu'invité, la propriété "User" n'est pas égale à son adresse e-mail, mais la valeur est formée d'une manière spécifique puisqu'elle contient "#EXT#". Par exemple, pour l'invité "[email protected]", cela donne : teams_it-connect.fr#EXT#@itctech.onmicrosoft.com

Finalement, nous n'avons pas besoin de "#EXT#@itctech.onmicrosoft.com" dans la sortie, alors je vous propose que l'on découpe la valeur pour récupérer uniquement ce qui est avant le premier "#". Pour découper la valeur, on va utiliser la méthode Split() et une boucle Foreach pour traiter chaque ligne, c'est-à-dire chaque compte invité. Ce qui donne :

(Get-TeamUser -GroupId $TeamGUID | Where{$_.Role -eq 'Guest'}).User | Foreach{ $_.Split("#")[0] }

Pour éviter d'avoir une erreur sur la méthode Split() dans le cas où il n'y a pas d'invité dans l'équipe, on va ajouter une condition if : on applique la modification sur la chaîne avec Split() seulement si le résultat de Get-TeamUser n'est pas null après avoir subi notre filtre (Where).

(Get-TeamUser -GroupId $TeamGUID | Where{$_.Role -eq 'Guest'}).User | Foreach{ if($_ -ne $null){ $_.Split("#")[0] } }

La valeur :

teams_it-connect.fr#EXT#@itctech.onmicrosoft.com

Devient :

teams_it-connect.fr

On pourrait remplacer "_" par "@" pour obtenir l'adresse e-mail, mais si l'adresse e-mail d'origine contient déjà "_" on risque de se retrouver avec une adresse e-mail... Bizarre 😁.

Ce qui donne la variable $TeamGuest :

# Liste des invités de l'équipe Teams
$TeamGuest = (Get-TeamUser -GroupId $TeamGUID | Where{$_.Role -eq 'Guest'}).User | Foreach{ if($_ -ne $null){ $_.Split("#")[0] } }
if ($TeamGuest -eq $null){ $TeamGuest = 0 }

La condition "if" qui termine le bloc de code ci-dessus va permettre de définir la valeur à 0 dans le cas où il n'y a pas d'invité dans l'équipe.

H. Type d'accès à l'équipe

Certaines équipes sont ouvertes, c'est-à-dire que n'importe qui dans l'organisation peut rejoindre l'équipe, tandis que d'autres sont privées : il faut être ajouté par un propriétaire. Lorsque l'on modifie une équipe, cela correspond à ce champ :

C'est ce que nous allons indiquer comme information dans notre variable $TeamGroupAccessType. Cela tombe bien, la commande Get-UnifiedGroup permet d'obtenir cette information avec sa propriété AccessType.

# Type d'accès à l'équipe Teams
$TeamGroupAccessType = (Get-UnifiedGroup -identity $TeamGUID).AccessType

I. Créer un objet personnalisé pour l'équipe Teams

Nous avons toutes les informations dont on a besoin, il ne reste plus qu'à créer un objet personnalisé : il y aura un champ correspondant à chaque valeur. L'objectif étant de construire notre objet et ensuite d'exporter les valeurs dans un fichier CSV.

La collection d'objets $TeamListReport va contenir un objet personnalisé pour chaque équipe Teams de notre tenant Office 365. Au final, dans l'export CSV nous aurons une ligne par équipe Teams.

# Générer un objet pour cette équipe (cumulatif)
$TeamListReport = $TeamListReport + [PSCustomObject]@{
                                         TeamName = $TeamName;
                                         TeamCreationDate = $TeamCreationDate;
                                         TeamChannels = $TeamChannels -join ', ';
                                         TeamOwners = $TeamOwner -join ', ';
                                         TeamMemberCount = $TeamUserCount;
                                         TeamAccessType = $TeamGroupAccessType;
                                         TeamGuests = $TeamGuest -join ',';
                                     }

Lorsque l'on a "TeamName = $TeamName", il faut savoir que le nom de la colonne dans le CSV ce sera "TeamName" et la valeur correspondra à $TeamName. Tout ça pour vous dire que vous pouvez facilement renommer les colonnes.

Autre précision, quand nous avons " -join ', ' ", cela permet de fusionner les lignes en une seule. Par exemple, s'il y a deux canaux "Général" et "Projet1", au lieu d'avoir la valeur sur deux lignes, nous aurons "Général, Projet1" dans l'export CSV.

J. Exporter le rapport au format CSV

Dernière étape, peut-être la plus facile : exporter $TeamListReport dans un fichier CSV. On va utiliser le cmdlet prévu à cet effet, à savoir Export-Csv. Le fichier sera créé à l'emplacement suivant "C:\TEMP\" (vous pouvez modifier ou sinon créez le dossier s'il n'existe pas) et sera nommé "TeamsReporting.csv".

$TeamListReport | Export-Csv "C:\TEMP\TeamsReporting.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation

Tout est prêt, alors on fait un essai ? 😃😃

IV. Aperçu du rapport Teams

Il est temps de tester le script pour voir à quoi va ressembler notre rapport sur les équipes Teams. Dans mon exemple, voici ce que ça donne en ouvrant le fichier avec Excel :

Rapport Teams PowerShell

Maintenant que vous avez en possession ce script, vous pouvez le faire évoluer pour ajouter ou supprimer de nouvelles colonnes. En tout cas, c'est une base intéressante pour faire un reporting des équipes Teams de son tenant Office 365.

➡ Pour télécharger le script Get-TeamsReport.ps1, rendez-vous sur mon Github : Get-TeamsReport.ps1

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Florian BURNEL

Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.

Nombre de posts de cet auteur : 5501.Voir tous les posts

One thought on “Comment générer un rapport des équipes Teams avec PowerShell ?

  • Bonjour Florian,

    Merci pour ton script, il me permet de faire un 1ere inventaire de mon environnement teams.
    Il me manque une information que je n’arrive pas à extraire proprement depuis le centre d’administration.
    J’ai besoin de connaitre la date de la dernière utilisation/accès de l’équipe Teams ou du site SP correspondant.

    Est ce que par hasard tu saurais m’aider à collecter cette donnée?

    Cordialement

    Damien

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.