20/09/2024

Les structures conditionnelles : Switch

I. Présentation

Dans ce chapitre, nous allons apprendre à utiliser les structures conditionnelles basées sur l'instruction Switch, en PowerShell ! Le Switch s'avère très pratique lorsque l'on a besoin d'exécuter une action différente ou d'affecter une valeur différente à une variable en fonction d'une valeur en entrée, et qu'il y a une multitude de valeurs possibles. Dans ce cas précis, l'utilisation de Switch sera beaucoup plus efficace et adaptée qu'un enchaînement de conditions dans un bloc "if-elseif-else" : ceci va permettre d'alléger le code et d'améliorer sa lisibilité.

Concrètement, une instruction Switch va prendre une expression en entrée et comparer la valeur de cette expression à une liste de cas (déclarés par vos soins). S'il y a une correspondance totale ou partielle (selon la configuration du switch), le bloc de code associé sera exécuté. Dans le cas où, il n'y a aucune correspondance trouvée, un bloc de code par défaut peut être exécuté.

II. Premiers pas avec Switch

Pour bien comprendre l'intérêt du bloc d'instruction Switch, nous allons le comparer aux conditions "if-elseif-else" pour commencer. Il est très fréquent que l'on cherche à exécuter une action différente en fonction de la valeur d'une variable. Lorsque l'on utilise une variable au sein d'une boucle (dans un "ForEach", par exemple), il y a des chances pour que la valeur de la variable soit différente d'un tour de boucle à l'autre : on doit gérer les différents cas de figure.

Dans ce cas, nous pouvons utiliser if-elseif-else pour exécuter des actions différentes en fonction de la valeur testée.

Ce qui donne :

# Structure générale if-elseif-else
If("<condition 1>")
   {
     # bloc de code (instructions)
   }
ElseIf("<condition 2>")
   {
     # bloc de code (instructions)
   }
ElseIf("<condition 3>")
   {
     # bloc de code (instructions)
   }
ElseIf("<condition 4>")
   {
     # bloc de code (instructions)
   }
Else
   {
     # bloc de code (instructions)    
   }

Où la condition pourrait être "ma valeur = 1", "ma valeur = 2", etc… Lorsque nous souhaitons agir en fonction de la valeur d'une variable, nous pouvons nous appuyer sur un switch. De ce fait, le bloc "if-elseif-else" évoqué précédemment deviendrait :

Switch ("<valeur à tester>")
{
    "<condition 1>" { "bloc de code (instructions)" }
    "<condition 2>" { "bloc de code (instructions)" }
    "<condition 3>" { "bloc de code (instructions)" }
    "<condition 4>" { "bloc de code (instructions)" }
    Default { "bloc de code (instructions)" }
}

Où la valeur à tester pourrait être "1", "2", etc.. et la condition, simplement chaque valeur. De façon officielle, nous pouvons décrire la syntaxe de cette façon :

switch -paramètre  (<valeur>) {
    "Chaîne" | Nombre | Variable | { Expression } {  Bloc de code à exécuter }
    default { Bloc de code à exécuter }
}

Pour que ce soit plus évocateur, prenons un exemple concret.

Nous allons définir la variable $NomLogiciel qui contiendra le nom d'un logiciel que l'on saisira dans la console PowerShell (valeur récupérée avec Read-Host). Ensuite, on va tester cette valeur à l'aide d'un switch. Par exemple, si la valeur est "notepad", nous allons exécuter l'application notepad.exe sur la machine, tandis que si la valeur est "powershell", nous allons ouvrir une console PowerShell sur la console, etc... On voit bien qu'une action différente est exécutée en fonction de la valeur en entrée. Puis, comme action par défaut (si l'on ne trouve pas le logiciel demandé, par exemple), nous allons simplement indiquer "Désolé, je n'ai pas trouvé ce logiciel".

Ce qui donne :

# Exemple n°1
$NomLogiciel = Read-Host -Prompt "Quel logiciel souhaitez-vous lancer ?"

switch ($NomLogiciel)
{
    "notepad" { Start-Process notepad.exe }
    "powershell" { Start-Process powershell.exe }
    "calc" { Start-Process calc.exe }
    "regedit" { Start-Process regedit.exe }
    Default { "Désolé, je n'ai pas trouvé ce logiciel" }
}

Ainsi, si nous exécutons ce bout de code et que l'on indique "notepad", l'application s'exécute sur la machine locale :

PowerShell - Switch - Exemple 1

Par contre, si nous indiquons une valeur non gérée, c'est l'instruction dans "Default" qui s'exécutera :

PowerShell - Switch - Exemple Default

En l'état actuel, il est à noter qu'il doit y avoir une correspondance exacte entre la valeur à tester et les valeurs déclarées dans le Switch pour que cela fonctionne. Autrement dit, si nous indiquons "notepa", le switch ne fera pas la correspondance avec "notepad", et donc le bloc de code associé ne sera pas exécuté. Toutefois, Switch ne tient pas compte de la casse par défaut.

III. Switch : tester deux valeurs

Dans ce premier exemple, nous avons vu qu'il était possible de tester une valeur. Sachez que dans un switch, on peut tester plusieurs valeurs : pas en même temps, mais tour à tour. Ainsi, nous pourrions adapter l'exemple précédent pour demander le nom d'un second logiciel.

Ce qui donne :

# Exemple n°2A
$NomLogiciel1 = Read-Host -Prompt "Quel logiciel souhaitez-vous lancer ?"
$NomLogiciel2 = Read-Host -Prompt "Quel logiciel souhaitez-vous lancer ?"

switch ($NomLogiciel1,$NomLogiciel2)
{
    "notepad" { Start-Process notepad.exe }
    "powershell" { Start-Process powershell.exe }
    "calc" { Start-Process calc.exe }
    "regedit" { Start-Process regedit.exe }
    "powershell_ise" { Start-Process powershell_ise.exe }
    Default { "Désolé, je n'ai pas trouvé ce logiciel" }
}

Lors de l'exécution, nous pouvons constater que PowerShell demande bien deux noms de logiciels et que le résultat sera différent pour chaque valeur.

PowerShell - Switch - Deux valeurs à tester

Ci-dessus, nous avons vu qu'il était possible d'indiquer plusieurs valeurs en entrée. Cela est aussi valide pour les valeurs à comparer dans notre bloc switch. Par exemple, si nous souhaitons ouvrir PowerShell ISE si l'utilisateur précise "powershell_ise" ou "ise", nous pouvons l'écrire de cette façon pour accepter plusieurs valeurs pour un même bloc de code :

# Exemple n°2B
$NomLogiciel = Read-Host -Prompt "Quel logiciel souhaitez-vous lancer ?"

Switch ($NomLogiciel)
{
    "notepad" { Start-Process notepad.exe }
    "powershell" { Start-Process powershell.exe }
    "calc" { Start-Process calc.exe }
    "regedit" { Start-Process regedit.exe }
    {"ise","powershell_ise"} { Start-Process powershell_ise.exe }
    Default { "Désolé, je n'ai pas trouvé ce logiciel" }
}

IV. Les paramètres de Switch : wildcard, break, regex, etc.

Jusqu'ici, nous avons vu une utilisation très simple de switch : définir une valeur à tester et comparer cette valeur à celles définies dans le switch. Comme je le disais précédemment, cela fonctionne uniquement lorsqu'il y a une réelle correspondance. Pour aller plus loin, switch prend en charge plusieurs paramètres :

  • -Wildcard : permet l'utilisation de caractères wildcard comme "*" et "?" dans les valeurs du switch, pour permettre de faire une correspondance partielle. Pour rappel, "*" permet de remplacer tous les caractères et il peut y avoir plusieurs caractères, tandis que "?" permet de remplacer un seul caractère.
  • -Regex : permet l'utilisation d'expressions régulières dans les valeurs du switch. Utile pour créer des modèles de correspondance complexe (voir ce tutoriel sur les RegEx).
  • -CaseSensitive : permet d'activer la sensibilité à la casse pour la comparaison des valeurs
  • -File : permet de récupérer les valeurs à partir d'un fichier pour effectuer la comparaison

Dans l'exemple ci-dessous, le paramètre "-wildcard" est utilisé pour déclarer les valeurs "N?TEPAD" et "note*" à la place de "notepad" qui était utilisée auparavant. La syntaxe du switch est très légèrement différente, mais cela va influencer son fonctionnement.

# Exemple n°3
$NomLogiciel = "notepad"

switch -Wildcard ($NomLogiciel)
{
    "N?TEPAD" { Start-Process notepad.exe }
    "note*" { Start-Process notepad.exe }
    "calc" { Start-Process calc.exe }
    "regedit" { Start-Process regedit.exe }
    Default { "Désolé, je n'ai pas trouvé ce logiciel" }
}

Si le nom du logiciel est "notepad", que va-t-il se passer ?

Le logiciel sera ouvert deux fois ! Oui, deux fois !

En effet, il y a une première correspondance entre "notepad" et "N?TEPAD", donc le bloc de code associé sera exécuté : notepad.exe sera lancé sur la machine. Puis, il y a une seconde correspondance entre "notepad" et "note*", donc notepad.exe sera lancé une seconde fois.

Intéressant, car cela signifie que toutes les valeurs sont testées : quand on trouve une correspondance, on continue à tester, on ne sort pas du switch ! Contrairement à un bloc conditionnel "if-elseif-else" ! Voilà une différence notable.

Toutefois, nous pouvons ajuster la syntaxe de notre bloc switch pour en sortir à partir du moment où l'on trouve la correspondance avec une valeur. Dans ce cas, nous ajoutons un "break" dans le bloc de code de chaque valeur.

Ce qui donne :

# Exemple n°4
$NomLogiciel = "notepad"

switch -Wildcard ($NomLogiciel)
{
    "NOTEPAD" { Start-Process notepad.exe ; break }
    "note*" { Start-Process notepad.exe ; break }
    "calc" { Start-Process calc.exe ; break }
    "regedit" { Start-Process regedit.exe ; break }
    Default { "Désolé, je n'ai pas trouvé ce logiciel" }
}

Avec cette nouvelle syntaxe, et toujours en utilisant la valeur "notepad", l'application notepad.exe sera exécutée une seule fois !

Remarque : si nous souhaitons utiliser une expression régulière, il suffit d'indiquer le pattern en tant que valeur dans la liste du switch (au même titre que "NOTEPAD", "note*", etc...).

V. Switch - Exemple complet

Pour terminer, voici un exemple plus complet pour vous montrer que nous pouvons exécuter des blocs de code plus complexe dans un switch : il n'y a pas réellement de restriction, comme c'est le cas dans un bloc conditionnel "if-elseif-else".

Dans l'exemple ci-dessous, la variable $Logiciels contient une liste de logiciels et le switch contient les instructions d'installation de chaque logiciel. Ainsi, si $Logiciels est égal à "Firefox", alors le script va installer Firefox sur la machine (en récupérant la source en local).

# Exemple n°5
$Logiciels = @("Firefox","7-Zip")

switch($Logiciels)
{
    "Firefox" {

                $Installeur = "C:\PS\Firefox.msi"
                If(Test-Path $Installeur)
                    {
                       Write-Host "L'installation de Firefox ESR va débuter" -ForegroundColor Green
                       Start-Process $Installeur -ArgumentList "/quiet" -Wait
                    }
                Else
                    {
                       Write-Host "Package MSI de Firefox introuvable ($Installeur)" -ForegroundColor Red
                    }
              }

    "7-ZIP" {
                $Installeur = "C:\PS\7z-x64.msi"
                If(Test-Path $Installeur)
                    {
                       Write-Host "L'installation de 7-Zip va débuter" -ForegroundColor Green
                       Start-Process $Installeur -ArgumentList "/quiet" -Wait
                    }
                Else
                   {
                       Write-Host "Package MSI de 7-Zip introuvable ($Installeur)" -ForegroundColor Red
                   }
             }
           
    Default { "Désolé, je n'ai pas trouvé ce logiciel" }
}

VI. Conclusion

Suite à la lecture de ce chapitre, vous êtes en mesure de mettre en pratique le "switch" dans vos scripts PowerShell ! Le "switch" est capable de répondre à de nombreux besoins, que ce soit des besoins simples (comparaison de valeurs) ou des besoins complexes (utilisation de wildcard, regex) en déclarant un ensemble de valeurs. En complément de vos valeurs, pensez à déclarer et ajouter du code dans le cas "Default" de manière à traiter tous les autres cas.

Désormais, nous allons commencer à étudier le principe des boucles avec PowerShell.


livre pour apprendre PowerShell
author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

1 commentaire sur “Les structures conditionnelles : Switch

  • Il y a vraisemblablement une erreur sur le test de valeurs multiples :

    {« ise », »powershell_ise »} { Start-Process powershell_ise.exe } ne fonctionne pas, il faut utiliser {« ise », »powershell_ise » -eq $_} { Start-Process powershell_ise.exe }

    Sinon merci bien pour ce site plein d’informations utiles

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.