- 05/23/2020
- 18 minuten te lezen
-
- j
- x
- t
- D
- s
net Als veel andere talen, PowerShell verklaringen voor voorwaardelijk uitvoeren van code in yourscripts. Een van die verklaringen is de If-verklaring., Vandaag zullen we een diepe duik nemen in een van de meest fundamentele commando ‘ s in PowerShell.
Note
De originele versie van dit artikel verscheen op de blog geschreven door @KevinMarquette. Het PowerShell team bedankt Kevin voor het delen van deze content met ons. Bekijk zijn blog atPowerShellExplained.com.
conditionele uitvoering
uw scripts moeten vaak beslissingen nemen en andere logica uitvoeren op basis van die beslissingen.Dit is wat ik bedoel met voorwaardelijke uitvoering., Je hebt één statement of waarde te evalueren, voer dan een ander gedeelte van de code uit op basis van die evaluatie. Dit is precies wat het if
statement doet.
de if statement
Hier is een basisvoorbeeld van de if
statement:
$condition = $trueif ( $condition ){ Write-Output "The condition was true"}
het eerste wat de if
statement doet is de expressie tussen haakjes evalueren. Als het evalueert naar $true
, dan voert het de scriptblock
uit in de accolades., Als de waarde $false
was, dan zou het dat scriptblok overslaan.
in het vorige voorbeeld was de verklaring if
slechts een evaluatie van de variabele $condition
. Het was$true
en zou het Write-Output
commando in het scriptblok hebben uitgevoerd.
in sommige talen kunt u een enkele regel code plaatsen na het statement if
en het wordt uitgevoerd. Dat is niet het geval in PowerShell. U moet een volledige scriptblock
voorzien van accolades om correct te kunnen werken.,
Vergelijkingsoperators
het meest voorkomende gebruik van hetif
statement voor is het vergelijken van twee items met elkaar. PowerShell heeft speciale operators voor verschillende vergelijkingsscenario ‘ s. Wanneer u een vergelijkingsoperator gebruikt, wordt de waarde aan de linkerkant vergeleken met de waarde aan de rechterkant.
-eq voor gelijkheid
de -eq
controleert of twee waarden gelijk zijn aan elkaar.,
$value = Get-MysteryValueif ( 5 -eq $value ){ # do something}
In dit voorbeeld neem ik een bekende waarde van 5
en vergelijk deze met mijn $value
om te zien of ze overeenkomen.
een mogelijk gebruik is om de status van een waarde te controleren voordat u een actie onderneemt. Je kunt een service instellen en controleren of de status actief was voordat je Restart-Service
aanriep.
het is gebruikelijk in andere talen zoals C# om ==
te gebruiken voor gelijkheid (bijvoorbeeld: 5 == $value
) maar dat werkt niet met PowerShell., Een andere veelvoorkomende fout die mensen maken is het gebruik van het ‘ = ‘ teken (bijvoorbeeld:5 = $value
) dat gereserveerd is voor het toewijzen van waarden aan variabelen. Door het plaatsen van uw bekende waarde op de linker, het maakt die fout meer onhandig om te maken.
deze operator (en anderen) heeft een paar variaties.,
-
-eq
hoofdletterongevoelige gelijkheid -
-ieq
hoofdletterongevoelige gelijkheid -
-ceq
hoofdlettergevoelige gelijkheid
-ne niet gelijk
veel operators hebben een verwante operator dat is controleren op het tegenovergestelde resultaat. -ne
controleert of de waarden niet gelijk zijn aan elkaar.
if ( 5 -ne $value ){ # do something}
Gebruik dit om ervoor te zorgen dat de actie alleen wordt uitgevoerd als de waarde niet 5
is., Een goed gebruik-gevallen waar zou zijn om te controleren of een dienst was in de draaiende staat voordat u probeert om het te starten.
variaties:
-
-ne
ongevoelig voor hoofdletters niet gelijk -
-ine
ongevoelig voor hoofdletters niet gelijk -
-cne
gevoelig voor hoofdletters niet gelijk
variaties van -eq
. Ik groepeer deze types als ik variaties voor andere operators opmaak.,
– gt-ge-lt-le voor groter of kleiner dan
deze operators worden gebruikt bij het controleren of een waarde groter of kleiner is dan een andere waarde.De -gt -ge -lt -le
staat voor groter dan, groter Danorequal, minder dan, en minder Danorequal.,eter dan of gelijk aan, niet hoofdlettergevoelig
-cge
groter dan of gelijk aan, hoofdlettergevoelig-lt
minder dan-ilt
minder dan, niet hoofdlettergevoelig-clt
minder dan hoofdlettergevoelig-le
kleiner dan of gelijk aan-ile
kleiner dan of gelijk aan, niet hoofdlettergevoelig-cle
kleiner dan of gelijk aan, hoofdlettergevoeligik weet niet waarom zou u gebruik maken van case-gevoelig en ongevoelig opties voor deze operatoren.,
– achtige jokertekens
PowerShell heeft zijn eigen op jokertekens gebaseerde syntaxis voor patroonafstemming en u kunt het gebruiken met de-like
operator. Deze wildcard patronen zijn vrij basic.
-
?
komt overeen met elk enkel teken -
*
komt overeen met elk aantal tekens
$value = 'S-ATX-SQL01'if ( $value -like 'S-*-SQL??'){ # do something}
Het is belangrijk erop te wijzen dat het patroon overeenkomt met de hele tekenreeks. Als je iets in het midden van de string moet matchen, moet je de *
aan beide uiteinden van de string plaatsen.,e”>
Variaties:
-
-like
case-insensitive wildcard -
-ilike
case-insensitive wildcard -
-clike
hoofdlettergevoelig wildcard -
-notlike
case-insensitive wildcard niet overeenkomt -
-inotlike
case-insensitive wildcard niet overeenkomt -
-cnotlike
hoofdlettergevoelig wildcard niet overeenkomt
-overeen met reguliere expressie
De -match
operator kunt u controleren of een string voor een reguliere-expressie-based match., Gebruik ditwanneer de wildcard patronen zijn niet flexibel genoeg voor u.
$value = 'S-ATX-SQL01'if ( $value -match 'S-\w\w\w-SQL\d\d'){ # do something}
een regexpatroon komt standaard overal in de tekenreeks overeen. U kunt dus een substring opgeven die u als volgt wilt matchen:
$value = 'S-ATX-SQL01'if ( $value -match 'SQL'){ # do something}
Regex is een complexe taal op zich en de moeite waard om naar te kijken. Ik praat meer over -match
en de vele manieren om regex in een ander artikel te gebruiken.,
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}
u kunt dit gebruiken als u met klassen werkt of verschillende objecten via de pijplijn accepteert. U kunt een service of een service naam als uw input. Controleer dan of je een service hebt en haal de service op als je alleen de naam hebt.,
if ( $Service -isnot ){ $Service = Get-Service -Name $Service}
Opties:
-
-is
type -
-isnot
niet van het type
Verzameling operatoren
Wanneer u de vorige exploitanten met een enkele waarde, het resultaat is $true
of $false
. Dit ishandled iets anders bij het werken met een collectie. Elk item in de collectie wordt geëvalueerd en de operator retourneert elke waarde die evalueert naar $true
.,
PS> 1,2,3,4 -eq 33
Dit werkt nog steeds correct in een if
statement. Dus een waarde wordt geretourneerd door uw operator, dan is het hele statement $true
.
$array = 1..6if ( $array -gt 3 ){ # do something}
Er is een kleine val verborgen in de details hier die ik moet aanwijzen. Als u de -ne
operator op deze manier gebruikt, is het gemakkelijk om de logica verkeerd achterwaarts te bekijken. -ne
met acollection geeft $true
terug als een item in de collectie niet overeenkomt met uw waarde.,
PS> 1,2,3 -ne 4123
Dit lijkt misschien een slimme truc, maar we hebben operators -contains
en -in
die dit efficiënter verwerken. En -notcontains
doet wat u verwacht.
– bevat
de-contains
operator controleert de verzameling op uw waarde. Zodra het een overeenkomst vindt, draait het $true
.
$array = 1..6if ( $array -contains 3 ){ # do something}
Dit is de beste manier om te zien of een verzameling uw waarde bevat., Met behulp van Where-Object
(of-eq
) loopt de hele lijst elke keer en is aanzienlijk langzamer.,
Variaties:
-
-contains
case-insensitive match -
-icontains
case-insensitive match -
-ccontains
hoofdlettergevoelig match -
-notcontains
case-insensitive niet overeenkomt -
-inotcontains
case-insensitive niet overeenkomt -
-cnotcontains
hoofdlettergevoelig niet overeenkomt
in
De -in
operator is net als de -contains
de operator behalve de collectie aan de rechter kant.,
$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.,
-niet
De -not
operator flipt een expressie van $false
naar $true
of Van $true
naar $false
. Hier is een voorbeeld waar we een actie willen uitvoeren als Test-Path
is $false
.
if ( -not ( Test-Path -Path $path ) )
De meeste operators waar we het over hadden hebben een variatie waarbij u de -not
operator niet hoeft te gebruiken. Maar er zijn nog steeds momenten dat het nuttig is.
!, operator
u kunt !
gebruiken als een alias voor -not
.
if ( -not $value ){}if ( !$value ){}
u kunt zien dat !
meer wordt gebruikt door mensen die uit andere talen komen, zoals C#. Ik typ liever itout omdat ik het moeilijk vind om te zien wanneer ik snel naar mijn scripts kijk.
-en
u kunt expressies combineren met de -and
operator. Als je dat doet, moeten beide zijden$true
zijn om de hele expressie $true
te laten zijn.,
if ( ($age -gt 13) -and ($age -lt 55) )
in dat voorbeeld moet $age
13 of ouder zijn voor de linkerkant en minder dan 55 voor de rechterkant. Iadded extra haakjes om het duidelijker te maken in dat voorbeeld, maar ze zijn optioneel zolang de expression is eenvoudig. Hier is hetzelfde voorbeeld zonder hen.
if ( $age -gt 13 -and $age -lt 55 )
evaluatie gebeurt van links naar rechts. Als het eerste item evalueert naar $false
, wordt het vroeg afgesloten en wordt de juiste vergelijking niet uitgevoerd. Dit is handig wanneer u ervoor moet zorgen dat er een waarde bestaat voordat u het gebruikt., Bijvoorbeeld, Test-Path
gooit een fout als je het een $null
pad geeft.
if ( $null -ne $path -and (Test-Path -Path $path) )
-or
met -or
kunt u twee expressies opgeven en geeft $true
als een van hen$true
is.
if ( $age -le 13 -or $age -ge 55 )
net als bij de operator -and
, vindt de evaluatie plaats van links naar rechts., Behalve dat als het eerste deel $true
is, dan is het hele statement $true
en het verwerkt de rest van de expressie niet.
noteer ook hoe de syntaxis werkt voor deze operators. Je hebt twee verschillende uitdrukkingen nodig. Ik heb gebruikers zien proberen om iets als dit te doen $value -eq 5 -or 6
zonder hun fout te realiseren.
– XOR exclusive of
Deze is een beetje ongebruikelijk. -xor
staat slechts één expressie toe om te evalueren naar $true
., Dus als beide items $false
zijn of beide items $true
zijn, dan is de hele expressie $false
. Een andere manier om hier naar te kijken is dat de expressie alleen $true
is als de resultaten van de expressie verschillend zijn.
Het is zeldzaam dat iemand deze logische operator ooit zou gebruiken en ik kan geen goed voorbeeld bedenken omdat ik het ooit zou gebruiken.
Bitwise operators
Bitwise operators voeren berekeningen uit op de bits binnen de waarden en produceren een nieuwe waarde als het resultaat., Het onderwijzen van bitwise operators valt buiten het bereik van dit artikel, maar hier is de lijst thethem.
-
-band
binaire EN -
-bor
binaire OF -
-bxor
binaire exclusieve OF -
-bnot
binaire NIET -
-shl
shift links -
-shr
shift rechts
PowerShell expressions
We kunnen gebruik maken van de normale PowerShell in de toestand-en verliesrekening.,
if ( Test-Path -Path $Path )
Test-Path
geeft $true
of $false
wanneer het wordt uitgevoerd. Dit geldt ook voor commando ‘ s die andere waarden retourneren.
if ( Get-Process Notepad* )
het evalueert naar $true
als er een geretourneerd proces is en $false
als er niets is., Het is volkomen geldig om pipeline expressies of andere PowerShell statements als deze te gebruiken:
if ( Get-Process | Where Name -eq Notepad )
deze expressies kunnen met elkaar worden gecombineerd met de -and
en -or
operators, maar u moet misschien haakjes gebruiken om ze in subexpressies op te splitsen.
if ( (Get-Process) -and (Get-Service) )
controle op $null
met een geen resultaat of een$null
waarde evalueert naar$false
in hetif
statement., Bij het specifiek controleren op $null
, is het een beste praktijk om de $null
aan de linkerkant te plaatsen.
if ( $null -eq $value )
Er zijn nogal wat nuances bij het omgaan met $null
waarden in PowerShell. Als je geïnteresseerd bent in dieper duiken, heb ik een artikel over alles wat je wilde weten over $null.
variabele toewijzing
Ik vergat deze bijna toe te voegen totdat Prasoon Karunan V me eraan herinnerde.,
if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}
normaal gesproken wanneer u een waarde toewijst aan een variabele, wordt de waarde niet doorgegeven aan de pijplijn ofconsole. Wanneer je een variabele toewijzing in een subexpressie doet, wordt deze doorgegeven aan de pipeline.
PS> $first = 1PS> ($second = 2)2
zie hoe de$first
toewijzing geen uitvoer heeft en de $second
toewijzing wel? Wanneer een assignment wordt gedaan in een if
statement, wordt het uitgevoerd net als de $second
toewijzing hierboven., Hier is een cleanexample over hoe je het zou kunnen gebruiken:
if ( $process = Get-Process Notepad* ){ $process | Stop-Process}
als $process
een waarde wordt toegewezen, dan is het statement $true
en $process
wordt gestopt.
verwar dit niet met -eq
omdat dit geen gelijkheidscontrole is. Dit is een moreobscure functie die de meeste mensen niet beseffen werkt op deze manier.,
Alternate execution path
met de opdracht if
kunt u een actie opgeven voor niet alleen wanneer de opdracht $true
is, maar ook wanneer het $false
is. Dit is waar het else
commando in het spel komt.
else
deelse
statement is altijd het laatste deel van deif
statement indien gebruikt.
in dit voorbeeld controleren we de $path
om er zeker van te zijn dat het een bestand is. Als we het dossier vinden, verplaatsen we het. Zo niet, dan schrijven we een waarschuwing., Dit type vertakkingslogica komt veel voor.
Genest als
deif
enelse
statements een scriptblok bevatten, zodat we elk PowerShell commando insidethem kunnen plaatsen, inclusief een anderif
statement. Hierdoor kunt u gebruik maken van veel ingewikkelder logica te maken.
in dit voorbeeld testen we eerst het happy path en nemen er dan actie op. Als dat niet lukt, doen we een andere controle en om meer gedetailleerde informatie te verstrekken aan de gebruiker.
elseif
We zijn niet beperkt tot slechts een enkele voorwaardelijke controle., We kunnen if
en else
statementstogether in plaats van ze te nestelen met behulp van de elseif
statement.
de uitvoering vindt plaats van boven naar beneden. Het bovensteif
statement wordt eerst geëvalueerd. Als dit $false
is, gaat het naar beneden naar de volgende elseif
of else
in de lijst. Die laatste else
is de standaardactie die moet worden uitgevoerd als geen van de anderen $true
retourneert.,
switch
Op dit punt moet ik het switch
statement vermelden. Het biedt een alternatieve syntaxis voor het doen vanmultiple vergelijkingen met een waarde. Met de switch
, specificeer je een expressie en dat resultaat wordt vergeleken met verschillende waarden. Als een van deze waarden overeenkomt, wordt het overeenkomende codeblok uitgevoerd. Kijk eens naar dit voorbeeld:
$itemType = 'Role'switch ( $itemType ){ 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' }}
Er zijn drie mogelijke waarden die overeenkomen met de $itemType
. In dit geval komt het overeen met Role
., Ik heb een eenvoudig voorbeeld gebruikt om je enige blootstelling te geven aan de switch
operator. Ik praat meer over alles wat je ooit wilde weten over de switch statement in een ander artikel.
pijplijn
de pijplijn is een uniek en belangrijk kenmerk van PowerShell. Elke waarde die niet wordt onderdrukt of toegewezen aan een variabele wordt in de pijplijn geplaatst. De if
biedt ons een manier om voordeel te halen uit de pijplijn op een manier die niet altijd voor de hand ligt.,
$discount = if ( $age -ge 55 ){ Get-SeniorDiscount}elseif ( $age -le 13 ){ Get-ChildDiscount}else{ 0.00}
elk scriptblok plaatst de resultaten van de commando ‘ s of de waarde in de pijplijn. Vervolgens wijzen we het resultaat van de if
statement toe aan de $discount
variabele. Dat voorbeeld kan net zo gemakkelijk deze waarden toegewezen hebben aan de$discount
variabele direct in elk scriptblok. Ik kan niet zeggen dat ik dit vaak gebruik met het if
statement, maar ik heb wel een voorbeeld waar ik dit onlangs heb gebruikt.,
Array inline
Ik heb een functie genaamd Invoke-SnowSql die een uitvoerbaar bestand start met verschillende command-linearguments. Hier is een clip van die functie waar ik de array van argumenten Bouw.
De $Debug
en $Path
variabelen zijn parameters voor de functie die door de eindgebruiker worden geleverd.Ik evalueer ze inline binnen de initialisatie van mijn array. Als $Debug
waar is, dan vallen die waarden op de juiste plaats in $snowSqlParam
. Hetzelfde geldt voor de $Path
variabele.,
complexe bewerkingen vereenvoudigen
Het is onvermijdelijk dat u in een situatie komt die veel te veel vergelijkingen bevat om te controleren en dat uwIf
statement ver van de rechterkant van het scherm schuift.
ze kunnen moeilijk te lezen zijn en dat maakt je meer geneigd om fouten te maken. Daar kunnen we een paar dingen aan doen.
voortzetting van de regel
Er zijn een aantal operators in PowerShell die u de opdracht laten afbreken naar de volgende regel., De logicaloperators -and
en -or
zijn goede operators om te gebruiken als u uw expressie in meerdere regels wilt breken.
Er is daar nog veel aan de hand, maar het plaatsen van elk stuk op zijn eigen lijn maakt een groot verschil.Ik gebruik dit meestal als ik meer dan twee vergelijkingen krijg of als ik naar rechts moet scrollen om een van de logica te lezen.
pre-calculating results
We kunnen dat statement uit de if
statement halen en alleen het resultaat controleren.
Dit voelt gewoon veel schoner dan het vorige voorbeeld., U krijgt ook de mogelijkheid om avariabele naam die verklaart wat het is dat je echt controleert gebruiken. Dit is ook een voorbeeld van zelfdocumenterende code die onnodige opmerkingen opslaat.
meerdere if statements
We kunnen dit opsplitsen in meerdere statements en ze één voor één controleren. In dit geval gebruiken we aflag of een trackingvariabele om de resultaten te combineren.
Ik moest de logica omkeren om de vlaglogica correct te laten werken. Elke evaluatie is een afzonderlijkeif
statement., Het voordeel hiervan is dat wanneer je debuggen, je kunt tellexactly wat de logica doet. Ik was in staat om veel betere woorden toe te voegen op hetzelfde moment.
het voor de hand liggende nadeel is dat het zoveel meer code is om te schrijven. De code is complexer om naar te kijken als het een enkele lijn van logica neemt en het explodeert in 25 of meer lijnen.
met behulp van functies
kunnen we ook al die validatielogica naar een functie verplaatsen. Kijk eens hoe schoon dit lijkt op aglance.,
if ( Test-SecureDriveConfiguration -ADUser $user ){ # do something}
u moet nog steeds de functie aanmaken om de validatie uit te voeren, maar het maakt deze code veel gemakkelijker om mee te werken. Het maakt deze code gemakkelijker te testen. In je tests kun je de aanroep naarTest-ADDriveConfiguration
mockeren en je hebt slechts twee tests nodig voor deze functie. Een waar het$true
retourneert en een waar het $false
retourneert. Het testen van de andere functie is eenvoudiger omdat het zo klein is.
de body van die functie kan nog steeds die one-liner zijn waarmee we begonnen of de exploded logica die we in de laatste sectie gebruikten., Dit werkt goed voor beide scenario ‘ s en stelt u in staat om eenvoudig te wijzigen dat de implementatie later.
foutafhandeling
een belangrijk gebruik van de instructieif
is om te controleren op foutcondities voordat u fouten uitvoert. Een goed voorbeeld is om te controleren of een map al bestaat voordat u probeert om het te maken.
if ( -not (Test-Path -Path $folder) ){ New-Item -Type Directory -Path $folder}
Ik wil graag zeggen dat als je een uitzondering verwacht, het niet echt een uitzondering is. Dus controleer uw waarden en valideer uw voorwaarden waar u kunt.,
als je iets meer wilt ingaan op de behandeling van uitzonderingen, heb ik een artikel over alles wat je ooit wilde weten over uitzonderingen.
laatste woorden
hetif
statement is zo ‘ n eenvoudig statement, maar is een fundamenteel stuk van PowerShell. Je zult merken dat je dit meerdere keren gebruikt in bijna elk script dat je schrijft. Ik hoop dat je een beter begrip hebt dan voorheen.