Dans un script PowerShell, if, elseif et else permettent de choisir les commandes à exécuter selon l’état d’un serveur, la valeur d’une variable ou la présence d’un fichier.
La syntaxe tient en quelques lignes, mais les détails comptent : les conditions se placent entre parenthèses, les blocs entre accolades et les comparaisons utilisent des opérateurs comme -eq ou -lt, pas ==.
Ces structures servent autant à vérifier un prérequis avant une sauvegarde qu’à déclencher une alerte lorsque l’espace disque devient faible. Dans une tâche planifiée, elles peuvent aussi décider si le script doit poursuivre ou rendre un code d’erreur exploitable.
Les exemples ci-dessous s’appuient sur un scénario courant d’administration Windows : contrôler des valeurs, tester des chemins et surveiller un volume. L’objectif est de rendre la syntaxe conditionnelle lisible et de limiter les surprises en production.
En bref
- if évalue une première condition ; elseif examine d’autres cas ; else traite le cas restant.
- Utilisez les opérateurs de comparaison PowerShell, comme -eq, -ne, -gt et -like.
- Combinez des tests avec -and et -or, en parenthésant les conditions complexes.
- Testez les fichiers et dossiers avec Test-Path, et retournez un code de sortie explicite pour les scripts automatisés.
Syntaxe de l’instruction if en PowerShell
Une condition est une expression dont PowerShell peut déterminer si le résultat est vrai ou faux. Le script s’appuie sur cette valeur pour choisir un bloc de commandes. Par exemple, un contrôle d’âge peut distinguer un utilisateur majeur, un cas intermédiaire et un utilisateur mineur.

La structure de base est la suivante : if ($condition) { commandes }. Les parenthèses entourent le test et les accolades délimitent le code exécuté si le résultat est vrai. Contrairement à Bash, PowerShell n’utilise ni then, ni fi, ni les crochets de test de la forme [ … ].
Dans la forme complète, elseif ajoute une condition de repli et else traite tous les cas qui n’ont satisfait aucun des tests précédents. Le bloc else ne porte pas de condition : il doit se trouver à la fin. Il reste facultatif, tout comme les blocs elseif.
Un exemple simple suffit à voir le déroulement :
$age = 17
if ($age -ge 18) { Write-Output « Majeur » }
elseif ($age -ge 16) { Write-Output « Presque majeur » }
else { Write-Output « Mineur » }
PowerShell teste les branches dans l’ordre. Dès qu’une condition est vraie, son bloc s’exécute et les branches suivantes sont ignorées.
Ici, une valeur de 17 ne déclenche pas le premier bloc, mais satisfait le second. L’ordre des tests a donc un effet direct : si la condition la plus générale arrive trop tôt, elle peut empêcher les cas plus précis d’être traités.
Les commandes n’ont pas besoin d’être limitées à l’affichage d’un message. Un bloc peut appeler une fonction, créer un dossier, lancer un contrôle de service ou contenir une autre structure de contrôle de flux. Dans un script de déploiement, on peut par exemple vérifier un prérequis au début, puis arrêter immédiatement l’exécution si le chemin de sortie est absent.

Pour un seul test, évitez d’ajouter systématiquement un else vide. Une branche inutile rend le code plus long sans clarifier son comportement. La bonne syntaxe n’est pas seulement celle qui fonctionne : c’est celle qui permet au collègue chargé de dépanner le script à deux heures du matin de comprendre rapidement quel chemin sera exécuté.
Opérateurs de comparaison et tests sur les chaînes
Les opérateurs de comparaison forment le cœur des conditions PowerShell. Pour tester l’égalité, utilisez -eq ; pour une différence, -ne. Les comparaisons numériques utilisent notamment -lt et -le pour « inférieur à » et « inférieur ou égal », puis -gt et -ge pour « supérieur à » et « supérieur ou égal ».
| Besoin | Opérateur PowerShell | Exemple |
|---|---|---|
| Égalité | -eq | $etat -eq « Actif » |
| Différence | -ne | $code -ne 0 |
| Inférieur ou égal | -le | $libre -le 20 |
| Recherche avec motif | -like | $nom -like « SRV-* » |
| Expression régulière | -match | $texte -match « ^d+$ » |
Un piège classique consiste à écrire ==, par habitude d’un autre langage. Cet opérateur n’est pas l’opérateur d’égalité PowerShell : utilisez -eq. Le signe = sert à affecter une valeur à une variable, comme dans $etat = « Actif », et non à comparer deux valeurs.
Pour les chaînes, -like permet de rechercher un motif avec les caractères génériques, tandis que -match s’appuie sur une expression régulière. Par exemple, $nom -like « SRV-* » teste si le nom commence par « SRV- ». Pour vérifier qu’une chaîne ne contient que des chiffres, $texte -match « ^d+$ » est plus adapté.
Les comparaisons de chaînes sont insensibles à la casse par défaut. Si cette distinction est nécessaire, ajoutez le préfixe c à l’opérateur : -ceq pour une égalité sensible à la casse ou -clike pour un motif. Les versions préfixées par i, comme -ieq, indiquent explicitement une comparaison insensible à la casse. Dans un environnement Windows classique, le comportement par défaut convient souvent ; dans un traitement où la casse fait partie de l’identifiant, mieux vaut l’indiquer clairement.
Pour les tableaux, -contains vérifie si une collection contient une valeur, et -in exprime le test dans l’autre sens. Ainsi, $services -contains « web » vérifie la présence de « web » dans la collection. Choisir l’opérateur en fonction du type de comparaison rend le code plus lisible qu’une conversion improvisée en chaîne.
Dans les scripts de gestion Windows, le résultat d’une condition peut aussi guider une procédure liée aux stratégies. Pour replacer ces contrôles dans leur contexte, la page sur la définition des GPO informatiques explique le rôle des stratégies de groupe, qui peuvent notamment distribuer des paramètres aux postes.
Conditions multiples avec les opérateurs logiques
Une condition n’est pas obligée de tester une seule valeur. Les opérateurs logiques -and, -or et -not permettent de combiner des critères. Avec -and, toutes les expressions doivent être vraies ; avec -or, une seule condition vraie suffit. -not inverse le résultat d’un test.
Pour alerter lorsque l’espace libre passe sous un seuil et que le détail des contrôles est demandé, on peut écrire : if (($libre -lt 20) -and $Detail) { … }. Les parenthèses rendent le regroupement explicite. Elles deviennent particulièrement utiles dès qu’une condition mélange plusieurs opérateurs, même si PowerShell peut interpréter certaines expressions sans elles.
Pour accepter deux noms de serveur dans le même bloc, une condition avec -or évite de dupliquer le code :
if (($nom -eq « SRV-WEB-01 ») -or ($nom -eq « SRV-WEB-02 »)) {
Write-Output « Serveur web autorisé »
}
Si plusieurs valeurs possibles doivent être comparées, répéter une longue série de -or finit par nuire à la lecture. Une collection associée à -contains peut être plus claire. Et lorsqu’une cascade contient de nombreux cas distincts, l’instruction switch mérite d’être envisagée : elle exprime souvent mieux une sélection entre plusieurs valeurs précises que dix branches elseif.
Les valeurs « fausses » méritent une attention particulière. $false, $null, le nombre zéro, une chaîne vide et un tableau vide sont évalués comme faux dans un test direct. Ce comportement est pratique, mais peut créer un défaut si zéro est une valeur valide : un compteur égal à zéro ne signifie pas nécessairement qu’il manque.
Pour comparer une variable à $null, placez cette valeur à gauche : if ($null -eq $chemin) { … }. Si la variable est une collection, écrire $chemin -eq $null peut faire traiter l’opération comme un filtre sur ses éléments au lieu d’un test global. Ce détail paraît mineur, jusqu’au jour où une collection vide fait passer une validation qui devait arrêter le script.
Enfin, un test peut recevoir directement le résultat d’une commande. if (Test-Path -Path $chemin) entre dans le bloc si le chemin existe. Pour distinguer un fichier d’un dossier, ajoutez -PathType Leaf ou -PathType Container. Cette méthode est plus nette que de comparer explicitement le résultat à $true.
Exemples de scripts : fichier, disque et code de sortie
Un cas fréquent consiste à vérifier qu’un dossier de sortie existe avant de lancer une exportation. Il vaut mieux traiter cette erreur au début et quitter proprement que d’envelopper tout le script dans un grand bloc conditionnel. Cette pratique, souvent appelée « sortir tôt », garde le chemin normal d’exécution lisible.
Le contrôle peut prendre cette forme : if (-not (Test-Path -Path $Dossier -PathType Container)) { Write-Error « Dossier absent »; exit 1 }. Si le script doit créer lui-même le dossier, une autre approche est plus adaptée : if (-not (Test-Path $Dossier -PathType Container)) { New-Item -Path $Dossier -ItemType Directory | Out-Null }. Le second script devient rejouable : son exécution ne dépend pas du fait que le dossier ait déjà été créé manuellement.
Voici un autre exemple, cette fois pour surveiller l’espace libre d’un lecteur. Le seuil est passé en paramètre : une tâche planifiée peut donc l’ajuster sans modifier le corps du script. La commande Get-CimInstance interroge les informations du système, puis le calcul transforme les octets disponibles en pourcentage.
param([string]$Lettre = « C: », [int]$SeuilPourcent = 20)
$disque = Get-CimInstance -ClassName Win32_LogicalDisk -Filter « DeviceID=’$Lettre' »
if ($null -eq $disque) { Write-Error « Lecteur introuvable »; exit 1 }
$pourcentLibre = [math]::Round(($disque.FreeSpace / $disque.Size) * 100, 1)
if ($pourcentLibre -lt $SeuilPourcent) { Write-Output « Alerte : $pourcentLibre % libre »; exit 1 }
elseif ($pourcentLibre -lt 40) { Write-Output « Surveillance : $pourcentLibre % libre » }
else { Write-Output « État normal : $pourcentLibre % libre » }
exit 0
Dans un script destiné à une tâche planifiée, les messages affichés ne remplacent pas un code de sortie. Le planificateur ou l’outil de supervision peut exploiter exit 0 pour signaler une réussite et une valeur différente de zéro pour signaler un échec. Réservez donc les codes et messages à des situations cohérentes, plutôt que de renvoyer zéro après une erreur détectée.
Il faut aussi distinguer $? et $LASTEXITCODE. En PowerShell, $? est un booléen lié à la réussite de la commande précédente, alors que $LASTEXITCODE contient le code de sortie du dernier programme externe lancé. Cette différence surprend les personnes qui viennent de Bash, où $? correspond à un code numérique. Si un script appelle un exécutable comme un outil de sauvegarde tiers, vérifiez le code avec $LASTEXITCODE.
Pour examiner un processus lorsque son nom est incertain, le résultat d’une commande peut aussi servir de test, avec une gestion d’erreur adaptée. Un outil comme Process Explorer de Microsoft peut compléter l’investigation lorsqu’il faut examiner les processus et leurs relations au-delà d’un simple contrôle PowerShell.
Erreurs fréquentes et choix entre if et switch
La première erreur consiste à transposer mécaniquement la syntaxe d’un autre langage. En Bash, un test peut prendre la forme [ « $n » -eq 5 ] et la structure comporte then et fi. En PowerShell, le test s’écrit directement entre parenthèses : if ($n -eq 5) { … }. Les opérateurs numériques ne changent pas selon que la valeur comparée est une chaîne ou un nombre, mais il faut tout de même veiller aux types et aux conversions implicites.
Une autre erreur est de construire une cascade elseif dont les conditions se recouvrent. Si la première branche teste $valeur -gt 0, une branche suivante qui teste $valeur -gt 10 ne sera jamais atteinte pour les valeurs supérieures à 10. Classez les critères du plus spécifique au plus général, puis testez les valeurs limites : zéro, seuil exact, valeur immédiatement au-dessus et valeur manquante.
Ne confondez pas non plus « commande sans résultat » et « commande en échec ». Les commandes PowerShell produisent des objets dans le flux de sortie, et un test conditionnel peut évaluer la présence d’un résultat. En cas d’erreur, le comportement dépend du type d’erreur et des paramètres utilisés. Pour un contrôle qui ne doit pas interrompre l’affichage, -ErrorAction SilentlyContinue peut être approprié, mais il ne faut pas l’ajouter partout : masquer une erreur utile rend le diagnostic plus difficile.
Quand les cas deviennent nombreux, switch est une alternative plus lisible. Il convient bien à une sélection par valeur, par exemple lorsqu’un statut peut être « En ligne », « En maintenance » ou « Arrêté ». Pour des plages numériques, des tests combinant plusieurs variables ou des décisions ordonnées, if reste généralement le meilleur outil. Ce n’est pas une question de mode : choisissez la structure qui rend les règles visibles au premier coup d’œil.
Avant de lancer un script en production, testez chaque branche avec des valeurs contrôlées. Dans un environnement de test, faites varier les paramètres et vérifiez à la fois le message, l’action exécutée et le code de sortie. Un test de disque peut sembler anodin, mais une erreur de seuil ou de chemin peut déclencher des alertes inutiles ou laisser passer un volume saturé.
Pour les scripts qui administrent des postes, cette discipline évite de confondre une condition de contrôle avec une politique de configuration. Un test PowerShell peut décider quoi faire pendant l’exécution ; une GPO, elle, sert à déployer et maintenir des paramètres sur un parc. Les deux mécanismes sont complémentaires, mais ils ne remplacent pas l’un l’autre.
Pour pratiquer, écrivez un test qui refuse un chemin absent, puis une variante qui le crée automatiquement. Ajoutez ensuite deux seuils de disque et vérifiez que le cas limite se retrouve dans la bonne branche. Cette petite série de tests révèle vite les erreurs d’ordre et de logique.
Faut-il toujours ajouter un bloc else ?
Non. Utilisez else seulement lorsqu’une action doit être exécutée si toutes les conditions précédentes sont fausses. Un bloc if seul ou suivi de elseif est valide.
Peut-on écrire == pour comparer deux valeurs en PowerShell ?
Non. L’égalité se teste avec -eq. Le signe = sert à affecter une valeur à une variable.
Comment tester si un chemin est un dossier ?
Utilisez Test-Path -Path $Chemin -PathType Container. Pour tester un fichier, utilisez -PathType Leaf.
Quelle différence entre $?, $LASTEXITCODE et exit ?
$? indique sous forme booléenne si la dernière commande PowerShell a réussi. $LASTEXITCODE contient le code du dernier exécutable externe. exit termine le script en renvoyant un code de sortie.