- 05/23/2020
- 18 minutes pour lire
-
- j
- x
- t
- D
- s
Comme beaucoup d’autres langues, PowerShell est consolidés pour conditionnellement de l’exécution de code dans yourscripts. L’une de ces déclarations est L’instruction If., Aujourd’hui, nous allons plonger dans l’un desles commandes les plus fondamentales de PowerShell.
Remarque
La version originale de cet article est parue sur le blog écrit par @KevinMarquette. L’équipe de PowerShell remercie Kevin d’avoir partagé ce contenu avec nous. Veuillez consulter son blog atPowerShellExplained.com.
exécution conditionnelle
vos scripts doivent souvent prendre des décisions et effectuer une logique différente en fonction de ces décisions.C’est ce que je veux dire par exécution conditionnelle., Vous avez une instruction ou une valeur à évaluer, puisexécutez une section de code différente en fonction de cette évaluation. C’est exactement ce que fait l’instruction if
.
if
Voici un exemple de base de la balise if
instruction:
$condition = $trueif ( $condition ){ Write-Output "The condition was true"}
La première chose que le if
déclaration n’est d’évaluer l’expression entre parenthèses. S’il évalue $true
, il exécute le scriptblock
dans les accolades., Si la valeur était $false
, alors itwould sauter sur ce scriptblock.
dans l’exemple précédent, l’instruction if
évaluait simplement la variable $condition
. C’était $true
et aurait exécuté la commande Write-Output
dans le scriptblock.
dans certaines langues, vous pouvez placer une seule ligne de code après l’instruction if
et elle getsexecuted. Ce n’est pas le cas dans PowerShell. Vous devez fournir un scriptblock
complet avec des accolades pour fonctionner correctement.,
opérateurs de comparaison
l’utilisation la plus courante de l’instructionif
consiste à comparer deux éléments entre eux. PowerShell aopérateurs spéciaux pour différents scénarios de comparaison. Lorsque vous utilisez un opérateur de comparaison, la valuesur le côté gauche est comparée à la valeur sur le côté droit.
-eq pour l’égalité
Le -eq
fait un contrôle d’égalité entre deux valeurs sont égales les unes aux autres.,
$value = Get-MysteryValueif ( 5 -eq $value ){ # do something}
Dans cet exemple, je vais prendre une valeur connue de 5
et en la comparant à mon $value
pour voir si theymatch.
Un possible cas d’utilisation est de vérifier l’état d’une valeur avant de prendre une action sur elle. Vous pouviez obtenir un service et vérifier que l’État était en cours d’exécution avant d’appeler Restart-Service
dessus.
il est courant dans d’autres langages comme C# d’utiliser==
pour l’égalité (ex:5 == $value
) mais cela ne fonctionne pas avec PowerShell., Une autre erreur courante que les gens font est d’utiliser le signe égal (ex: 5 = $value
) qui est réservé pour l’attribution de valeurs à des variables. En plaçant votre valeur connue sur theleft, cela rend cette erreur plus gênante à faire.
cet opérateur (et d’autres) a quelques variantes.,
-
-eq
insensibles à la casse de l’égalité -
-ieq
insensibles à la casse de l’égalité -
-ceq
casse de l’égalité
-ne pas égal
De nombreux opérateurs ont une opérateur de vérifier le résultat inverse. -ne
vérifie que les valeurs ne sont pas égales entre elles.
if ( 5 -ne $value ){ # do something}
l’Utiliser pour s’assurer que l’action s’exécute uniquement si la valeur n’est pas 5
., Un bon cas d’utilisation serait de vérifier si un service était en cours d’exécution avant d’essayer de le démarrer.
les Variations:
-
-ne
casse pas égale à -
-ine
casse pas égale à -
-cne
casse pas égale à
ce sont des inverses des variations de -eq
. Je vais regrouper ces types ensemble lorsque je liste les variationsfor d’autres opérateurs.,
-gt-ge-lt-le pour une valeur supérieure ou inférieure à
Ces opérateurs sont utilisés pour vérifier si une valeur est supérieure ou inférieure à une autre valeur.Le -gt -ge -lt -le
signifie GreaterThan, GreaterThanOrEqual, LessThan et LessThanOrEqual.,mangeur égale ou supérieure, à la casse
-cge
supérieur ou égal, sensible à la casse-lt
moins-ilt
moins de, insensibles à la casse-clt
moins que, sensible à la casse-le
inférieur ou égal-ile
inférieur ou égal à, insensibles à la casse-cle
inférieur ou égal à, sensible à la casseje ne sais pas pourquoi vous devez utiliser la casse et de l’indifférence des options pour ces opérateurs.,
-comme les correspondances de caractères génériques
PowerShell a sa propre syntaxe de correspondance de motifs basée sur des caractères génériques et vous pouvez l’utiliser avec l’opérateur-like
. Ces modèles génériques sont assez basiques.
-
?
correspond à tout caractère unique -
*
correspond à un nombre quelconque de caractères
$value = 'S-ATX-SQL01'if ( $value -like 'S-*-SQL??'){ # do something}
Il est important de souligner que le modèle correspond à l’ensemble de la chaîne. Si vous avez besoin de matchsomething au milieu de la chaîne, vous devez placer le *
aux deux extrémités de thestring.,e »>
les Variations:
-
-like
casse générique -
-ilike
casse générique -
-clike
casse générique -
-notlike
casse génériques pas de correspondance -
-inotlike
casse génériques pas de correspondance -
-cnotlike
casse génériques pas de correspondance
-correspondance d’expression régulière
Le -match
opérateur permet de vérifier une chaîne pour une expression régulière à base de match., Utilisez thiswhen les modèles de caractères génériques ne sont pas assez flexibles pour vous.
$value = 'S-ATX-SQL01'if ( $value -match 'S-\w\w\w-SQL\d\d'){ # do something}
Un modèle regex correspond par défaut n’importe où dans la chaîne. Vous pouvez donc spécifier une sous-chaîne quivous voulez correspondre comme ceci:
$value = 'S-ATX-SQL01'if ( $value -match 'SQL'){ # do something}
Regex est un langage complexe qui lui est propre et qui mérite d’être examiné. Je parle plus de -match
et des nombreuses façons d’utiliser regex dans un autre article.,
Variations:
-
-match
case-insensitive regex -
-imatch
case-insensitive regex -
-cmatch
case-sensitive regex -
-notmatch
case-insensitive regex not matched -
-inotmatch
case-insensitive regex not matched -
-cnotmatch
case-sensitive regex not matched
-is of type
You can check a value’s type with the -is
operator.,
if ( $value -is ){ # do something}
Vous pouvez l’utiliser si vous travaillez avec des classes ou acceptez divers objets sur le pipeline. Vous pouvez avoir un service ou un nom de service comme entrée. Vérifiez ensuite si vous avez un serviceand récupérez le service si vous n’avez que le nom.,
if ( $Service -isnot ){ $Service = Get-Service -Name $Service}
les Variations:
-
-is
type -
-isnot
de type
Collection les opérateurs
Lorsque vous utilisez les opérateurs précédents, avec une seule valeur, le résultat est: $true
ou $false
. Ceci est géré légèrement différemment lorsque vous travaillez avec une collection. Chaque élément de la collection getsevaluated et l’opérateur renvoie chaque valeur évaluée à $true
.,
PS> 1,2,3,4 -eq 33
Cela fonctionne encore correctement dans un if
déclaration. Donc, une valeur est renvoyée par votre opérateur, alors l’instruction entière est $true
.
$array = 1..6if ( $array -gt 3 ){ # do something}
Il y a un petit piège qui se cache dans les détails ici que je dois signaler. Lorsque vous utilisez l’opérateur -ne
de cette façon, il est facile de regarder à tort la logique à l’envers. L’utilisation de -ne
avec acollection renvoie $true
si un élément de la collection ne correspond pas à votre valeur.,
PS> 1,2,3 -ne 4123
Cela peut ressembler à une astuce, mais nous avons opérateurs -contains
et -in
qui gèrent ce moreefficiently. Et -notcontains
fait ce que vous attendez.
-contient
Le -contains
opérateur vérifie la collection pour votre valeur. Dès qu’il trouve une correspondance, ilretourne $true
.
$array = 1..6if ( $array -contains 3 ){ # do something}
c’est le moyen préféré de voir si une collection contient votre valeur., L’utilisation de Where-Object
(ou-eq
) parcourt la liste entière à chaque fois et est significativement plus lente.,
les Variations:
-
-contains
casse match -
-icontains
casse match -
-ccontains
sensible à la casse -
-notcontains
casse pas de correspondance -
-inotcontains
casse pas de correspondance -
-cnotcontains
casse pas de correspondance
en
Le -in
opérateur est comme la balise -contains
opérateur à l’exception de la collection est sur le bouton droit de la main.,
$array = 1..6if ( 3 -in $array ){ # do something}
Variations:
-
-in
case-insensitive match -
-iin
case-insensitive match -
-cin
case-sensitive match -
-notin
case-insensitive not matched -
-inotin
case-insensitive not matched -
-cnotin
case-sensitive not matched
Logical operators
Logical operators are used to invert or combine other expressions.,
-non
Le -not
opérateur retourne une expression de $false
de $true
ou de $true
de $false
. Hereis un exemple où nous voulons effectuer une action lorsque Test-Path
est $false
.
if ( -not ( Test-Path -Path $path ) )
La plupart des opérateurs dont nous avons parlé ont une variante où vous n’avez pas besoin d’utiliser l’opérateur-not
. Mais il y a encore des moments où c’est utile.
!, l’opérateur
Vous pouvez utiliser !
comme un alias pour -not
.
if ( -not $value ){}if ( !$value ){}
Vous pouvez voir !
utilisé plus par des gens qui viennent d’un autre langages tels que le C#. Je préfère taper itout parce que j’ai du mal à voir en regardant rapidement mes scripts.
et
Vous pouvez combiner les expressions avec le -and
opérateur. Lorsque vous faites cela, les deux parties doivent être$true
pour l’ensemble de l’expression $true
.,
if ( ($age -gt 13) -and ($age -lt 55) )
dans cet exemple, $age
doit être égal ou supérieur à 13 pour le côté gauche et inférieur à 55 pour le côté droit. J’ai ajouté des parenthèses supplémentaires pour le rendre plus clair dans cet exemple, mais elles sont facultatives tant que l’expression est simple. Voici le même exemple sans eux.
if ( $age -gt 13 -and $age -lt 55 )
L’évaluation se fait de gauche à droite. Si le premier élément est évalué à $false
, il se ferme tôt etn’effectue pas la bonne comparaison. C’est pratique lorsque vous devez vous assurer qu’une valeur existe avant que vous l’utilisiez., Par exemple, Test-Path
génère une erreur si vous lui donnez un chemin $null
.
if ( $null -ne $path -and (Test-Path -Path $path) )
ou
Le -or
permet de spécifier deux expressions et retourne $true
si l’un d’eux est$true
.
if ( $age -le 13 -or $age -ge 55 )
tout comme avec la balise -and
opérateur, l’évaluation s’effectue de gauche à droite., Sauf que si la première partie est $true
, alors l’instruction entière est $true
et elle ne traite pas le reste de l’expression.
notez également comment la syntaxe fonctionne pour ces opérateurs. Vous avez besoin de deux expressions distinctes. J’ai vu des utilisateurs essayer de faire quelque chose comme ça $value -eq 5 -or 6
sans se rendre compte de leur erreur.
-ou exclusif xor
celui-ci est un peu inhabituel. -xor
ne permet qu’une expression à évaluer de $true
., Donc, si bothitems sont $false
ou les deux éléments sont $true
, l’expression complète est: $false
. Une autre façon de regarder cela est l’expression est seulement $true
lorsque les résultats de l’expression sont différents.
Il est rare que quelqu’un utilise cet opérateur logique et je ne peux pas trouver un bon exemple car je l’utiliserais jamais.
opérateurs bit à bit
Les opérateurs bit à bit effectuent des calculs sur les bits dans les valeurs et produisent une nouvelle valeur en tant que résultat., L’enseignement des opérateurs bit à bit dépasse le cadre de cet article, mais voici la liste thethem.
-
-band
binaire ET -
-bor
binaire OU -
-bxor
OU exclusif binaire -
-bnot
binaire NON -
-shl
maj gauche -
-shr
décalage à droite
PowerShell expressions
Nous pouvons normal d’utilisation de PowerShell à l’intérieur de l’état.,
if ( Test-Path -Path $Path )
Test-Path
renvoie $true
ou $false
lorsqu’il exécute. Cela s’applique également aux commandes qui renvoient d’autres valeurs.
if ( Get-Process Notepad* )
Il est évalué à$true
s’il y a un processus retourné et$false
s’il n’y a rien., Il est parfaitement valide d’utiliser des expressions de pipeline ou d’autres instructions PowerShell comme celle-ci:
if ( Get-Process | Where Name -eq Notepad )
ces expressions peuvent être combinées entre elles avec les opérateurs -and
Et -or
, mais vous pouvez utiliser des parenthèses pour les diviser en sous-expressions.
if ( (Get-Process) -and (Get-Service) )
la Vérification de $null
Ayant un pas de résultat ou un $null
valeur prend la valeur $false
dans le if
déclaration., Lorsque checkingspecifically pour $null
, il est recommandé de placer la balise $null
sur le côté gauche.
if ( $null -eq $value )
Il y a pas mal de nuances lorsqu’il s’agit de$null
valeurs dans PowerShell. Si vous êtes intéressé à plonger plus profondément, j’ai un article sur tout ce que vous vouliez savoir sur null null.
affectation de Variable
j’ai presque oublié d’ajouter celui-ci jusqu’à ce que Prasoon Karunan V me le rappelle.,
if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}
Normalement, lorsque vous affectez une valeur à une variable, la valeur n’est pas répercuté sur le pipeline orconsole. Lorsque vous effectuez une affectation de variable dans une sous-expression, elle est transmise à thepipeline.
PS> $first = 1PS> ($second = 2)2
Voir la façon dont le $first
cession a pas de sortie et le $second
cession n’? Lorsqu’un assignment est effectué dans une instructionif
, il s’exécute comme l’affectation$second
ci-dessus., Voici une cleanexample sur comment vous pourriez l’utiliser:
if ( $process = Get-Process Notepad* ){ $process | Stop-Process}
Si $process
est affectée une valeur, alors l’énoncé est: $true
et $process
arrêté.
assurez-vous de ne pas confondre cela avec-eq
car ce n’est pas une vérification d’égalité. C’est une fonctionnalité plus obscure que la plupart des gens ne réalisent pas fonctionne de cette façon.,
Suppléant chemin d’exécution
Le if
instruction permet de définir une action pour non seulement lorsque l’instruction est $true
, butalso lorsqu’il est $false
. C’est là que l’instruction else
entre en jeu.
else
Le else
instruction est toujours la dernière partie de la if
déclaration lors de son utilisation.
dans cet exemple, nous vérifions le $path
pour nous assurer qu’il s’agit d’un fichier. Si nous trouvons le fichier, nous le déplaçons. Sinon, nous allons écrire un avertissement., Ce type de logique de branchement est très commun.
imbriqué si
les instructionsif
Etelse
prennent un bloc de script, nous pouvons donc placer n’importe quelle commande PowerShell à l’intérieur, y compris une autre instructionif
. Cela vous permet d’utiliser une logique beaucoup plus compliquée.
dans cet exemple, nous testons d’abord le chemin heureux, puis nous agissons dessus. Si cela échoue, nous faisons une autre vérification et de fournir des informations plus détaillées à l’utilisateur.
elseif
Nous ne sommes pas limités à un seul contrôle conditionnel., Nous pouvons enchaînerif
Etelse
statementstogether au lieu de les imbriquer en utilisant l’instructionelseif
.
l’exécution se fait de haut en bas. L’instruction top if
est évaluée en premier. Si c’est $false
, alors il descend au suivant elseif
ou else
dans la liste. Ce dernier else
est l’action par défaut à effectuer si aucune des autres ne renvoie $true
.,
switch
à ce stade, je dois mentionner l’instructionswitch
. Il fournit une syntaxe alternative pour faire des comparaisons multiples avec une valeur. Avec switch
, vous spécifiez une expression et ce résultat est comparé à plusieurs valeurs différentes. Si l’une de ces valeurs correspond, le bloc de code correspondant estexécuté. Jetez un oeil à cet exemple:
$itemType = 'Role'switch ( $itemType ){ 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' }}
Il y a trois valeurs possibles qui peuvent correspondre à la balise $itemType
. Dans ce cas, il correspond à Role
., J’ai utilisé un exemple simple juste pour vous donner une certaine exposition à l’opérateur switch
. Je parle plusà propos de tout ce que vous avez toujours voulu savoir sur la déclaration switch dans un autre article.
Pipeline
le pipeline est une caractéristique unique et importante de PowerShell. Toute valeur qui n’est pas suppressedor affectée à une variable est placée dans le pipeline. Le if
nous fournit un moyen de tirer parti du pipeline d’une manière qui n’est pas toujours évidente.,
$discount = if ( $age -ge 55 ){ Get-SeniorDiscount}elseif ( $age -le 13 ){ Get-ChildDiscount}else{ 0.00}
chaque bloc de script place les résultats les commandes ou la valeur dans le pipeline. Ensuite, nous attribuons le résultat de l’instructionif
à la variable$discount
. Cet exemple aurait pu tout aussi facilementassigné ces valeurs à la variable $discount
directement dans chaque scriptblock. Je ne peux pas dire que j’utilise souvent cela avec l’instruction if
, mais j’ai un exemple où je l’ai utilisé récemment.,
tableau en ligne
j’ai une fonction appelée Invoke-SnowSql qui lance un exécutable avec plusieurs linearguments de commande. Voici un clip de cette fonction où je construis le tableau d’arguments.
Le $Debug
et $Path
variables sont les paramètres de la fonction sont fournies par l’utilisateur final.Je les évalue en ligne dans l’initialisation de mon tableau. Si $Debug
a la valeur true, alors ces valuesfont dans $snowSqlParam
au bon endroit. Il en va de même pour la variable $Path
.,
simplifiez les opérations complexes
Il est inévitable que vous rencontriez une situation qui a beaucoup trop de comparaisons à vérifier et votre instructionIf
défile du côté droit de l’écran.
ils peuvent être difficiles à lire et vous rendre plus enclin à faire des erreurs. Il y a quelques choses que nous pouvons faire à ce sujet.
continuation de la ligne
Il y a des opérateurs dans PowerShell qui vous permettent d’envelopper votre commande à la ligne suivante., Les opérateurs logiques -and
Et -or
sont de bons opérateurs à utiliser si vous souhaitez casser votre expression en plusieurs lignes.
il se passe encore beaucoup de choses, mais placer chaque pièce sur sa propre ligne fait une grande différence.J’utilise généralement cela lorsque j’obtiens plus de deux comparaisons ou si je dois faire défiler vers la droite pour lire l’une des logiques.
pré-calcul des résultats
Nous pouvons retirer cette instruction de l’instructionif
et vérifier uniquement le résultat.
cela semble juste beaucoup plus propre que l’exemple précédent., Vous avez également la possibilité d’utiliser un nom avariable qui explique ce que vous vérifiez vraiment. C’est aussi un exemple de code auto-documenté qui enregistre les commentaires inutiles.
plusieurs instructions if
Nous pouvons diviser cela en plusieurs instructions et les vérifier une à la fois. Dans ce cas, nous utilisons aflag ou une variable de suivi pour combiner les résultats.
j’ai dû inverser la logique pour que la logique du drapeau fonctionne correctement. Chaque évaluation est une instruction individuelle if
., L’avantage de ceci est que lorsque vous déboguez, vous pouvez exactement ce que fait la logique. J’ai pu ajouter une beaucoup meilleure verbosité en même temps.
L’inconvénient évident est que c’est tellement beaucoup plus de code à écrire. Le code est plus complexe à regardercomme il prend une seule ligne de logique et l’explose en 25 lignes ou plus.
en utilisant des Fonctions
Nous pouvons également déplacer toute cette logique de validation dans une fonction. Regardez à quel point cela ressemble à aglance.,
if ( Test-SecureDriveConfiguration -ADUser $user ){ # do something}
Vous devez toujours créer la fonction pour faire la validation, mais cela rend ce code beaucoup plus facile à travailler avec. Cela rend ce code plus facile à tester. Dans vos tests, vous pouvez simuler l’appel àTest-ADDriveConfiguration
et vous n’avez besoin que de deux tests pour cette fonction. L’une où il renvoie$true
et un autre où il retourne $false
. Tester l’autre fonction est plus simple car c’estsi petit.
le corps de cette fonction pourrait toujours être celui avec lequel nous avons commencé ou la logique éclatée que nous avons utilisée dans la dernière section., Cela fonctionne bien pour les deux scénarios et vous permet de changer facilement thatimplementation plus tard.
gestion des Erreurs
Une importante utilisation de la balise if
déclaration est de vérifier les conditions d’erreur avant d’exécuter intoerrors. Un bon exemple est de vérifier si un dossier existe déjà avant d’essayer de le créer.
if ( -not (Test-Path -Path $folder) ){ New-Item -Type Directory -Path $folder}
j’aime dire que si vous vous attendez à ce qu’une exception se produise, ce n’est pas vraiment une exception. Vérifiez donc vos valeurs et validez vos conditions où vous le pouvez.,
Si vous voulez plonger un peu plus dans la gestion réelle des exceptions, j’ai un article sur tout ce que vous avez toujours voulu savoir sur les exceptions.
derniers mots
Le if
déclaration est une déclaration simple mais est un élément fondamental de PowerShell. Vous vous retrouverez en utilisant cela plusieurs fois dans presque tous les scripts que vous écrivez. J’espère que vous avez un betterunderstanding que vous aviez avant.