Introduction
Exchange bénéficie d'un grand nombre de cmdlet Powershell très abouties et permettant de configurer et d'administrer l'intégralité d'une infrastructure de messagerie. Aussi, celles-ci sont très utiles dans le cas de scripts de provisionning. J'ai rencontré une erreur lorsque je cherchais à créer et à configurer un grand nombre de boites aux lettres de ressources.
Contexte
L'environnement dans lequel j'ai découvert ce problème est une forêt mono domaine Active Directory avec une infrastructure Exchange 2010 SP3 dans laquelle il y avait plusieurs contrôleurs de domaine dans le même site Active Directory que la totalité des serveurs de messagerie.
Plus globalement, cette erreur pourra être rencontrée dès qu'un serveur Exchange pourra être amené à interroger plus d'un contrôleur de domaine.
Erreur rencontrée
Dans un script de provisionning de boîtes aux lettres, on cherche à les créer mais aussi à les configurer. Si l'on souhaite configurer une boite aux lettres tout de suite après sa création alors on obtient une erreur similaire à celle ci-dessous (“ObjectNotFoundException”) :
Cela peut se retrouver en exécutant l'exemple suivant :
Une ou plusieurs opérations de modification (de type Set-…) vont échouer avec le message d'erreur cité précédemment.
Explication
Suite à cette erreur, il est logique de penser que cela est dû à l'interrogation de différents contrôleurs de domaine qui n'ont pas encore répliqué entre eux (Une réplication intra site peut prendre quelques secondes).
Aussi, on peut se dire qu'il suffit alors de spécifier le paramètre DomainController pour corriger le problème en l'indiquant sur toutes les commandes et en définissant un contrôleur de domaine unique qui traitera toutes les opérations.
Cependant, cela ne corrigera pas le problème. Microsoft en donne l'explication dans les fiches Technet des cmdlets :http://technet.microsoft.com/en-us/library/dd335046.aspx.
Le paramètre DomainController ne concerne que le contrôleur de domaine qui va écrire les modifications dans Active Directory. Cependant, un autre contrôleur de domaine peut être utilisé pour lire l'objet avant d'écrire les changements sur celui spécifié en paramètre.
Aussi, pour une cmdlet de type Get-… (lecture), le paramètre DomainController sera bien le contrôleur de domaine sur lequel l'objet sera lu (cela sera utile pour mettre en place l'une des solutions proposées).
Solution
Pour résoudre ce problème, il faut donc attendre que la réplication ait eu lieu sur la totalité des contrôleurs de domaine du site Active Directory de l'infrastructure Exchange. Pour cela, nous avons trois solutions.
Solution 1 :
Il est possible de séparer la création des boîtes aux lettres et leurs configurations. Cette solution oblige donc a réaliser le provisioning en plusieurs phases.
Solution 2 :
On peut définir un délai entre l'opération de la cmdlet de création et la cmdlet de configuration via un Start-Sleep par exemple. Cependant, cette solution ne garantit pas que les opérations vont toutes se dérouler correctement. Il faudra sans doute que le délai soit important pour que le provisioning ait un taux de réussite élevé et donc augmenter considérablement le temps d'exécution du script.
Solution 3 :
La dernière solution est une combinaison des deux précédentes puisqu'elle permet de n'avoir qu'une seule phase de provisioning tout en ayant un temps d'exécution relativement rapide.
Cette solution consiste à implémenter une boucle de test de l'opération à réaliser sur le même contrôleur de domaine via la cmdlet de lecture (Get-…).
Exemple :
Il est possible d'ajouter une courte pause entre chaque test afin de ne pas surcharger le processus sans pour autant trop pénaliser le temps d'exécution du script. Le paramètre ErrorAction permet d'alléger l'affichage car on connait déjà l'erreur que l'on va rencontrer.
Il ne vous reste plus qu'à choisir la solution que vous préférez.