PROJET AUTOBLOG


IT-Connect

Site original : IT-Connect

⇐ retour index

Premiers pas avec PowerShell et switch : idéal pour de multiples comparaisons

dimanche 11 juin 2023 à 17:45

I. Présentation

Dans ce tutoriel, nous allons apprendre à utiliser 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".

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. PowerShell : 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, on peut 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 l'on souhaite agir en fonction de la valeur d'une variable, on peut s'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, on peut 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'on exécute une action différente 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 l'on exécute 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 l'on indique une valeur non gérée, c'est l'instruction dans "Default" qui s'exécute :

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 l'on indique "notepa", le switch ne fera pas la correspondance avec "notepad", et donc le bloc de code associé ne sera pas exécuté. Toutefois, on ne tient pas compte de la casse par défaut.

III. PowerShell et 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, on pourrait adapter l'exemple précédent pour demander le nom d'un deuxième 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, on peut 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 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 l'on souhaite ouvrir PowerShell ISE si l'utilisateur précise "powershell_ise" ou "ise", on peut 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. PowerShell et 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 :

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, on peut 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, on ajoute 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 l'on souhaite 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. PowerShell : exécuter des blocs de code avec Switch

Pour terminer, voici un exemple plus complet pour vous montrer que l'on peut 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 cet article, 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.

The post Premiers pas avec PowerShell et switch : idéal pour de multiples comparaisons first appeared on IT-Connect.