Contexte
Dans le cadre de mon poste actuel, une partie de mon quotidien est la gestion des comptes et des habilitations Active Directory : créations, départs, revues d’accès, détection des comptes inactifs. Ce sont des tâches répétitives, sensibles, et faciles à mal faire sous pression. J’ai construit cet outil pour formaliser et automatiser ce que je fais déjà à la main, avec la rigueur que je voudrais voir appliquée partout : validation des données avant toute écriture dans l’annuaire, traçabilité complète, et des rapports de conformité qui servent vraiment à quelque chose plutôt que de dormir dans un dossier.
Ce que fait l’outil
- Cycle de vie des comptes : création à partir de modèles (utilisateur standard, administrateur, compte de service, contractuel…), modification, désactivation, suppression avec archivage, création en masse depuis un CSV.
- Audit : comptes, groupes, permissions, comptes inactifs, comptes privilégiés — chaque exécution produit une liste de non-conformités classées par niveau de risque.
- Rapports de conformité RGPD, SOX et ISO 27001, avec un score pondéré par criticité, exportables en HTML, CSV, JSON ou Excel, et envoyables par email sur demande.
- Tests automatisés (Pester) et intégration continue (GitHub Actions) : analyse statique du code et tests unitaires à chaque push.
Un bug qui aurait rendu tous les rapports inutilisables
En relisant le projet pour le rendre présentable, j’ai découvert que toutes les fonctions d’audit construisaient leurs lignes de résultat avec de simples hashtables PowerShell (@{...}) plutôt que des [PSCustomObject]. Or Export-Csv, Export-Excel et ConvertTo-Html -Property n’exposent les clés d’une hashtable comme colonnes que si elle est typée ainsi — sinon ils affichent les propriétés internes de l’objet (Count, Keys, Values) au lieu des données attendues. Concrètement : tous les rapports HTML, CSV et Excel auraient eu des colonnes vides ou fausses à l’usage réel. Seul le JSON s’en sortait, parce que ConvertTo-Json traite les dictionnaires différemment. Je ne l’ai détecté qu’en écrivant un test pour la fonction de génération de rapport HTML — exactement le genre de bug qu’une relecture de code, même attentive, ne voit pas, et qu’un test révèle immédiatement.
D’autres corrections faites dans la même passe : une fonction d’envoi d’email qui aurait toujours échoué (un paramètre obligatoire pour Send-MailMessage n’était jamais renseigné), un fichier de configuration jamais fourni en exemple qui faisait planter les quatre scripts d’entrée dès le premier lancement, et un export au format PDF qui retombait silencieusement en JSON sans prévenir.
Ce que j’en retiens
- Un code qui parse n’est pas un code qui fonctionne. La relecture attrape les fautes de syntaxe ; seule l’exécution, ou un test qui la simule, révèle qu’une hashtable et un
PSCustomObjectne se comportent pas pareil face àExport-Csv. - La configuration fait partie du livrable. Un outil qui ne démarre pas au premier
git cloneparce qu’un fichier essentiel est ignoré par git sans modèle associé n’est pas prêt, même si le code métier est correct. - Un paramètre qui échoue silencieusement est pire qu’une erreur explicite.
-OutputFormat PDFqui génère un.jsonsans avertissement, ou un envoi d’email qui ne part jamais sans message clair, coûtent plus de temps à déboguer qu’une exception visible.
Suite
- Industrialiser la génération de PDF (actuellement un repli vers HTML, faute de dépendance externe).
- Étendre la couverture Pester aux fonctions qui nécessitent un domaine Active Directory réel, avec des mocks.
- Ajouter une revue d’accès périodique automatisée, au-delà du rapport ponctuel.