Pour maîtriser les conditions simples en PowerShell, retenez une règle : if teste une expression, elseif examine un autre cas si le premier échoue, et else définit l’action par défaut. Dans vos scripts, cette structure permet de choisir la bonne opération selon l’état d’un fichier, d’un service ou d’une valeur. Nous allons l’explorer avec des exemples progressifs et un fil conducteur : le poste informatique d’une petite équipe qui automatise ses tâches quotidiennes.
- Écrire une condition claire avec if et des accolades.
- Choisir les bons opérateurs de comparaison et combiner plusieurs tests logiques.
- Organiser les alternatives avec elseif et else, sans rendre le script difficile à relire.
Le but n’est pas d’ajouter des embranchements partout, mais de faire réagir l’automatisation de façon prévisible. Nous verrons aussi comment éviter les pièges liés aux collections, à $null et à l’ordre d’évaluation. Ces réflexes vous aideront à concevoir des structures conditionnelles lisibles, que vous débutiez avec PowerShell ou que vous entreteniez déjà des scripts utilisés chaque semaine.
Comprendre la condition if
Une condition permet à PowerShell d’exécuter un bloc de commandes uniquement quand une expression est vraie. La forme de base est if (condition) { commandes }. Les parenthèses entourent le test, tandis que les accolades délimitent le bloc exécuté. Contrairement à certains langages, PowerShell exige ces accolades même si le bloc ne contient qu’une seule commande. Cette règle rend la structure plus explicite et réduit le risque qu’une modification ultérieure change le comportement du script.
Imaginons que Lina, administratrice d’une petite équipe de création, vérifie chaque matin la présence d’un fichier de sauvegarde. Elle peut écrire : $condition = $true, puis if ($condition) { Write-Output “Sauvegarde détectée” }. Comme la variable contient la valeur booléenne $true, PowerShell exécute la commande située dans le bloc. Si elle contient $false, ce bloc est ignoré et le script continue après l’accolade fermante.
Dans un vrai contrôle, on teste souvent une propriété plutôt qu’une variable préparée à l’avance. Pour vérifier qu’un chemin existe, l’expression Test-Path -Path $chemin renvoie une valeur vraie ou fausse. On peut donc écrire if (Test-Path -Path $chemin) { Write-Output “Le fichier est disponible” }. Cette approche évite de créer une variable intermédiaire lorsque le test est simple et compréhensible.
Tester avant d’agir
Le principe est utile pour éviter une opération inutile ou risquée. Avant de déplacer un rapport, le script de Lina contrôle que le chemin désigne bien un fichier : if (Test-Path -Path $chemin -PathType Leaf) { Move-Item -Path $chemin -Destination $archive }. Le paramètre -PathType Leaf distingue un fichier d’un dossier. Sans cette vérification, le script pourrait produire une erreur ou déplacer un élément qui n’était pas visé.
Une condition peut aussi utiliser directement la sortie d’une commande. Par exemple, if (Get-Process -Name notepad -ErrorAction SilentlyContinue) exécute le bloc si la recherche retourne un processus. Pour une équipe qui vérifie si une application est lancée avant une maintenance, cette écriture évite de convertir le résultat en variable booléenne. Il faut néanmoins garder en tête que PowerShell évalue la sortie : une collection non vide est considérée comme vraie, tandis qu’une sortie vide correspond à une absence de résultat.
Cette distinction compte lors du diagnostic. Si une commande peut renvoyer plusieurs objets, le test ne signifie pas nécessairement qu’un seul objet existe. Il signifie que la commande a produit au moins une valeur exploitable par l’expression conditionnelle. Lorsque l’intention mérite une vérification plus précise, une variable nommée clairement ou un test explicite améliore la lecture. La bonne première condition est celle qui exprime sans détour ce que le script doit décider.
Choisir les bons opérateurs
Les opérateurs de comparaison servent à confronter deux valeurs. En PowerShell, l’égalité s’écrit -eq, et non ==. Pour savoir si deux éléments diffèrent, on emploie -ne. Cette syntaxe est facile à repérer dans un script et évite de confondre comparaison et affectation : le signe = attribue une valeur à une variable, il ne teste pas l’égalité.
Dans l’équipe de Lina, un contrôle peut comparer le nombre de sauvegardes présentes au seuil minimal attendu. Si $nombreSauvegardes vaut 5, l’expression $nombreSauvegardes -eq 5 est vraie. Pour déclencher une alerte dès que le nombre diffère de 5, on choisit $nombreSauvegardes -ne 5. Les opérateurs numériques complètent cette famille : -gt signifie supérieur à, -ge supérieur ou égal à, -lt inférieur à et -le inférieur ou égal à.
| Opérateur | Signification | Exemple |
|---|---|---|
| -eq | Égal à | 5 -eq 5 |
| -ne | Différent de | 5 -ne 3 |
| -gt | Supérieur à | $espace -gt 10 |
| -ge | Supérieur ou égal à | $age -ge 18 |
| -lt | Inférieur à | $charge -lt 80 |
| -le | Inférieur ou égal à | $tentatives -le 3 |
Pour le texte, -like accepte les jokers : * représente zéro ou plusieurs caractères et ? en représente un seul. Une condition comme $nomServeur -like ‘S-*-SQL??’ peut reconnaître un identifiant respectant ce motif. Le motif porte sur la chaîne entière : pour repérer « SQL » n’importe où dans une valeur, écrivez plutôt $nomServeur -like ‘*SQL*’.
Les opérateurs -match et -notmatch servent aux expressions régulières, plus adaptées aux motifs complexes. Par exemple, $nomServeur -match ‘SQLd{2}’ recherche « SQL » suivi de deux chiffres. Les comparaisons de texte sont insensibles à la casse par défaut dans les opérateurs courants ; les variantes préfixées par c, comme -ceq ou -clike, imposent une comparaison sensible à la casse. Les variantes en i rendent cette intention explicite sans tenir compte de la casse.
On peut aussi vérifier le type d’un objet avec -is ou -isnot. Si un paramètre peut contenir soit un nom de service, soit un objet service, le script peut tester son type avant d’appeler Get-Service. Cette précaution est pratique quand les données arrivent de plusieurs sources, car elle permet d’adapter le traitement à la valeur réellement reçue.
Combiner plusieurs tests logiques
Un test simple ne suffit pas toujours. Les opérateurs logiques permettent de combiner des conditions ou d’inverser un résultat. Avec -and, les deux expressions doivent être vraies. Avec -or, une seule expression vraie suffit. L’opérateur -not, que l’on peut remplacer par !, inverse une valeur logique ; dans nos scripts d’administration, nous préférons souvent écrire -not, plus facile à lire lors d’une relecture rapide.
Supposons que Lina réserve une opération aux comptes dont le département est Finance et dont le titre contient « Senior ». Elle peut combiner $utilisateur.Department -eq ‘Finance’ et $utilisateur.Title -match ‘Senior’ avec -and. Le bloc ne s’exécute que si les deux tests réussissent. Pour autoriser une intervention lorsque le compte est dans Finance ou dans Support, -or exprime au contraire une alternative.
La lecture s’effectue de gauche à droite, et -and comme -or peuvent interrompre l’évaluation dès que le résultat est déterminé. Cela aide à protéger un appel qui ne doit être fait que si une valeur existe. Par exemple : if ($null -ne $chemin -and (Test-Path -Path $chemin)). Si $chemin vaut $null, la seconde partie n’est pas évaluée, ce qui évite de transmettre une valeur absente à la commande.
Éviter les conditions ambiguës
Quand l’expression s’allonge, les parenthèses rendent les sous-tests plus faciles à identifier. Il faut également écrire deux expressions complètes autour d’un opérateur logique. La forme $valeur -eq 5 -or 6 ne compare pas correctement la valeur à 5 ou à 6. Il faut écrire $valeur -eq 5 -or $valeur -eq 6, ou choisir une approche adaptée aux collections.
Les collections demandent une attention particulière. Avec 1,2,3,4 -eq 3, PowerShell retourne l’élément qui correspond, ici 3, plutôt qu’une simple valeur booléenne. Dans un if, une sortie non vide est traitée comme vraie. Pour vérifier clairement l’appartenance d’une valeur à une collection, utilisez -contains ou -in : if ($nombres -contains 3) indique directement que la collection contient 3.
Il vaut mieux ne pas utiliser -ne comme raccourci pour vérifier l’absence d’une valeur dans un tableau. Dans une collection, 1,2,3 -ne 4 renvoie les éléments différents de 4 ; comme ils le sont tous, le résultat n’est pas vide et peut être interprété comme vrai. La condition ne répond donc pas à la question « le tableau ne contient-il pas 4 ? ». -notcontains répond à cette intention sans détour.
Pour les expressions longues, nous pouvons répartir les tests sur plusieurs lignes après -and ou -or. Une autre solution consiste à calculer un résultat dans une variable au nom explicite, comme $configurationConforme. Le test final devient alors facile à comprendre et à déboguer. Un nom précis transforme une suite de comparaisons en une règle métier lisible.
Structurer if elseif else
Quand plusieurs issues sont possibles, elseif ajoute des tests successifs et else définit le cas restant. PowerShell évalue les branches de haut en bas : dès qu’une condition est vraie, son bloc s’exécute et les branches suivantes sont ignorées. Il faut donc placer les cas précis avant les cas plus généraux, afin qu’une règle large ne masque pas une règle particulière.
Pour traiter un chemin, Lina distingue trois situations. Si le chemin désigne un fichier, elle l’archive ; s’il existe mais désigne un dossier, elle affiche un avertissement ; s’il n’existe pas, elle signale son absence. La logique peut se lire ainsi : if (Test-Path -Path $chemin -PathType Leaf) { Move-Item … } elseif (Test-Path -Path $chemin) { Write-Warning “Un dossier a été trouvé” } else { Write-Warning “Chemin introuvable” }.
Chaque branche répond à une question différente. Le premier test reconnaît le cas attendu, le second précise une situation proche, et le dernier reçoit tous les cas qui n’ont pas été reconnus. Cette organisation fournit un diagnostic plus utile qu’un message générique. Pour une automatisation utilisée par plusieurs collègues, ce détail facilite la correction : l’utilisateur sait s’il doit fournir un fichier ou vérifier le chemin.
Limiter les blocs imbriqués
On peut écrire des if imbriqués à l’intérieur d’un bloc else. Cette méthode fonctionne, mais plusieurs niveaux d’accolades rendent parfois le chemin d’exécution difficile à suivre. Une chaîne de elseif est souvent plus lisible lorsqu’il s’agit de tester des cas liés au même objet, comme un état de service : « Running », « Stopped » ou une valeur inattendue.
Les erreurs attendues méritent souvent un contrôle en amont. Avant de créer un dossier, le script peut vérifier son existence avec if (-not (Test-Path -Path $dossier)) { New-Item -ItemType Directory -Path $dossier }. L’action n’est réalisée que si le dossier manque. Cette validation évite une erreur prévisible et rend le comportement plus régulier que de laisser chaque exécution échouer sur une ressource déjà présente.
On peut aussi affecter le résultat d’un bloc conditionnel à une variable. Par exemple, une variable $tarif peut recevoir le tarif senior si l’âge est supérieur ou égal à 65, un tarif jeune si l’âge est inférieur ou égal à 13, et zéro dans les autres cas. Chaque branche produit alors une valeur, puis l’ensemble de l’expression if fournit le résultat à la variable. Cette forme est pratique quand le choix porte sur une valeur unique plutôt que sur une série d’actions.
Le mot-clé switch est à envisager lorsque le script compare une même variable à plusieurs valeurs fixes. Si un type d’élément peut être « Component », « Role » ou « Location », switch ($type) permet d’associer directement un bloc à chaque possibilité. La structure reste lisible quand la liste de cas s’allonge, tandis que if, elseif et else conviennent très bien à des tests différents ou à des plages numériques.
Une branche bien ordonnée raconte la règle avant même l’exécution : cas principal, alternatives reconnues, puis réponse par défaut. C’est cette hiérarchie qui rend les décisions du script prévisibles.
Rendre les scripts plus lisibles
Une condition peut être correcte et rester pénible à maintenir. Lorsque plusieurs comparaisons s’accumulent, nous pouvons placer chaque test sur sa propre ligne, puis aligner les opérateurs logiques. Prenons un compte Active Directory qui doit appartenir au département Finance, avoir un titre contenant « Senior » et ne pas utiliser un lecteur personnel déjà configuré. Une expression compacte peut devenir difficile à relire sur un écran étroit ; une version multilignes révèle chaque règle.
Une variable calculée à l’avance clarifie encore l’intention : $accesAValider = $null -ne $utilisateur -and $utilisateur.Department -eq ‘Finance’ -and $utilisateur.Title -match ‘Senior’. Puis if ($accesAValider) { … } sépare la décision de l’action. Le nom de la variable sert de documentation intégrée et permet d’inspecter le résultat pendant le débogage.
Si la validation devient longue, une fonction peut porter la règle. Le script principal appelle alors une fonction au nom explicite, par exemple Test-ConfigurationSecure, et décide quoi faire selon sa réponse. Cette séparation rend les tests plus faciles : on peut vérifier les cas valides et invalides indépendamment de la commande qui intervient ensuite. Elle permet aussi de modifier la règle sans réécrire chaque endroit où elle est utilisée.
Un autre raccourci consiste à affecter une sortie dans la condition, par exemple if ($process = Get-Process -Name notepad -ErrorAction SilentlyContinue) { … }. L’affectation transmet ici un résultat qui peut être évalué par le test. Cette écriture est valide, mais elle peut être confondue avec une comparaison par -eq et surprendre les personnes qui découvrent PowerShell. Pour une équipe, séparer la récupération de la donnée et sa vérification est souvent plus clair : $process = Get-Process …, puis if ($process).
Les conditions servent aussi à construire des paramètres progressivement. Dans un tableau d’arguments destiné à un outil externe, un bloc if ($Debug) peut ajouter des paramètres de journalisation seulement en mode diagnostic. Un autre bloc peut choisir entre un chemin de fichier et une requête saisie directement. La liste finale varie selon les besoins de l’appelant, sans imposer plusieurs versions presque identiques de la commande.
Pour organiser une règle complexe, adoptez une progression simple :
- Définir les données : récupérez les objets nécessaires et vérifiez leur présence.
- Nommer la décision : créez une variable booléenne ou une fonction dont le rôle est évident.
- Traiter les alternatives : utilisez elseif pour les cas connus et else pour un comportement de repli sûr.
- Tester les limites : vérifiez les valeurs égales au seuil, les résultats vides et les types inattendus.
Cette méthode réduit les erreurs de logique, surtout dans l’automatisation qui touche aux comptes, aux fichiers ou aux services. Un bon test ne se contente pas de renvoyer vrai ou faux : il indique clairement pourquoi le script choisit une action. En gardant les conditions courtes, nommées et vérifiables, nous rendons PowerShell plus accessible à toute l’équipe.