Office 365 et PowerShell : Comment optimiser les performances ?
Sommaire
I. Présentation
Office 365 bénéficie de son lot de cmdlets PowerShell qui permettent de l'administrer en ligne de commande et d'automatiser certaines tâches par script : attribution de licences, création d'utilisateurs, ajout d'utilisateurs dans un groupe, etc... De par sa nature, Office 365 est dans le Cloud, ce qui signifie que votre tenant Office 365 partage ses ressources avec d'autres tenants.
Microsoft ne peut pas se permettre de laisser votre script pénaliser les tenants d'autres clients, notamment lors de l'utilisation de commandes très gourmandes, comme "Get-MailboxFolderStatistics" voire un "Get-MsolUser -All" sur un tenant avec beaucoup d'utilisateurs. Il est donc conseillé d'ajouter des pauses de quelques millisecondes dans vos exécutions pour ne pas dépasser le quota, je vous recommande cette lecture à ce sujet : Office 365 & PowerShell micro-delay
Pour ma part, c'est plutôt la syntaxe des commandes que je voudrais aborder avec vous. Car bien qu'il y ait généralement plusieurs manières d'obtenir une même information, les performances peuvent être vraiment différentes. Vous pourrez bien être surpris. Ceci permettra de vous aider si vos requêtes PowerShell sur Office 365 sont très lentes.
II. Office 365 : Prioriser le filtre par paramètre
Prenons un exemple très simple, je cherche à vérifier l'existence d'un utilisateur avec l'adresse mail "[email protected]" au sein de mon tenant Office 365. Je peux alors imaginer deux syntaxes différentes pour le rechercher.
Première méthode avec la clause "where" habituelle via le pipe :
Get-MsolUser -All | Where{ $_.UserPrincipalName -eq "[email protected]" }
Deuxième méthode :
Get-MsolUser -UserPrincipalName "[email protected]"
Il est à noter que la deuxième solution est possible seulement, car le cmdlet "Get-MsolUser" dispose du paramètre "UserPrincipalName". Figurez-vous que, sur un tenant d'environ 2 500 comptes, la première méthode mettra environ 30 secondes à retourner le résultat de la recherche, alors qu'avec la deuxième méthode il faudra moins d'une demi-seconde.
Ce qu'il faut retenir :
Vous devez impérativement prioriser l'utilisation des filtres via les paramètres du cmdlet en lui-même plutôt que dans une clause "Where", car comme on peut le voir la différence est monstrueuse.
En fait, c'est logique, car dans la première méthode on va récupérer la liste de tous les utilisateurs du tenant pour ensuite rechercher celui qui correspond à "[email protected]" donc plus il y a d'utilisateurs, plus c'est long.
Dans la seconde méthode, on cible directement l'utilisateur donc c'est nettement plus optimisé.
Maintenant, comment faire si je veux rechercher un utilisateur qui a une valeur spécifique pour l'attribut "Office" de son profil par exemple ? Il n'y a pas de paramètre direct dans le cmdlet "Get-MsolUser" pour ce champ, donc comment réaliser ma recherche sans pénaliser les performances ?
On va devoir utiliser la clause Where pour éviter de subir les 30 secondes de temps de réponse (+/- selon le nombre d'utilisateurs de votre tenant), on va ajouter le paramètre "SearchString" à Get-MsolUser. Celui-ci va permettre de rechercher une chaine dans l'adresse mail ou le nom d'affichage (DisplayName) des utilisateurs. Autrement dit, cette méthode va permettre de filtrer déjà les utilisateurs et optimiser les performances.
Avec la commande ci-dessous, bien qu'elle soit très proche de celle vue précédemment avec la clause "Where", on obtiendra un résultat au bout d'une seconde environ.
Get-MsolUser -All -SearchString "Burnel" | Where{ $_.Office -eq "XXXXXX" }
Pour être capable de trouver la meilleure formule, il faut mesurer les performances, c'est ce que nous allons voir.
III. Comment mesurer la durée d'exécution d'une commande ?
Pour faire le meilleur choix, il faut mesurer les performances de vos commandes, c'est comme ça que vous pourrez déterminer quelle est la meilleure méthode. Pour mesurer simplement la durée d'exécution d'une commande, on va s'appuyer sur le cmdlet "Measure-Command".
Voici un exemple simple :
Measure-Command{ Get-MsolUser -UserPrincipalName "[email protected]" }
Le bloc ci-dessus vous donnera la durée d'exécution du bloc script contenu dans les accolades de Measure-Command, ainsi en comparant les résultats des différentes commandes vous pourrez tirer des conclusions.
Je vous propose de reprendre les trois exemples de commandes que l'on a vues précédemment afin de comparer les résultats d'exécution.
S'il y a bien une syntaxe de commande à éviter, c'est bien celle-ci quand on voit le temps de réponse... Sachant que ce sera plus ou moins long selon le nombre d'utilisateurs dans le tenant...
Quant aux deux autres méthodes, qui s'appliquent à des cas de figure différents, on peut voir qu'ils sont nettement plus efficaces et intéressants.
Moins d'une demi-seconde en temps de réponse, je vous recommande d'utiliser ces deux syntaxes / méthodes qui permettent d'avoir des résultats excellents.
Au travers de cet article, j'espère vous avoir sensibilisé à la notion de performances avec PowerShell et Office 365, mais aussi de manière générale pour vos futurs scripts 🙂
N'hésitez pas à donner votre avis.