liksom många andra språk har PowerShell uttalanden för att villkorligt exekvera kod i dina skript. En av dessa uttalanden är if-uttalandet. Idag kommer vi att ta en djupdykning i en av de mest grundläggande kommandona i PowerShell.,
- Index
- villkorligt utförande
- if-uttalandet
- Jämförelseoperatörer
- -eq för jämlikhet
- -ne inte lika
- – gt-ge-lt-le för större än eller mindre än
- -som jokertecken matcher
- -matcha reguljära uttryck
- -är av typen
- -är av typen
- -eq för jämlikhet
- samlingsoperatörer
- – innehåller
- – i
- logiska operatörer
- – inte
- !,pressions
- kontrollera för $null
- variabel tilldelning
- alternativ exekveringsväg
- else
- kapslade if
- elseif
- switch
- Pipeline
- Array inline
- förenkla komplexa operationer
- linje fortsättning
- Pre-calculating resultat
- multiple if uttalanden
- använda funktioner
- felhantering
- slutliga ord
villkorligt utförande
dina skript kommer ofta att behöva fatta beslut och utföra olika logik baserat på dessa beslut., Detta är vad jag menar med villkorligt utförande. Du har ett uttalande eller värde att utvärdera, sedan utföra en annan avsnitt av kod baserat på den utvärderingen. Detta är precis vad
if
– satsen gör.if-satsen
här är ett mycket grundläggande exempel på
if
– satsen:$condition = $true if ( $condition ) { Write-Output "The condition was true" }
det första som
if
– satsen gör är att utvärdera uttrycket inom parentes., Om den utvärderar till$true
, kommer den att exekverascriptblock
I hängslen. Om värdet var$false
, skulle det hoppa över det scriptblock.i föregående exempel utvärderade
if
– satsen bara variabeln$condition
. Det var$true
och skulle ha utfört kommandotWrite-Output
inuti scriptblock.på vissa språk kan du placera en enda rad kod efter
if
uttalande och det kommer att få exekveras., Så är inte fallet i PowerShell. Du måste tillhandahålla en fullständigscriptblock
med hängslen för att den ska fungera korrekt.Jämförelseoperatörer
det vanligaste Du kommer att använda
if
uttalande för är att jämföra två objekt med varandra. Powershell har speciella operatörer för olika jämförelsescenarier. När du använder en jämförelseoperatör jämförs värdet på vänster sida med värdet på höger sida.,-eq för jämlikhet
-eq
gör en jämlikhetskontroll mellan två värden för att se till att de är lika med varandra.$value = Get-MysteryValue if ( 5 -eq $value ) { # do something }
i det här exemplet tar jag ett känt värde på
5
och jämför det med min$value
för att se om de matchar.en möjlig usecase är att kontrollera statusen för ett värde innan du vidtar en åtgärd på det. Du kan få en tjänst och kontrollera att statusen kördes innan du ringde
Restart-Service
på den.,det är vanligt på andra språk som C# att använda
==
för jämlikhet (ex:5 == $value
) men det fungerar inte med powershell. Ett annat vanligt misstag som människor gör är att använda likhetstecknet (ex:5 = $value
) som är reserverat för att tilldela värden till variabler. Genom att placera ditt kända värde till vänster gör det misstaget mer besvärligt att göra.den här operatören (och andra) har några variationer.,
-
-eq
fall okänslig jämlikhet -
-ieq
fall okänslig jämlikhet -
-ceq
fall känslig jämlikhet
-ne inte lika
många operatörer har en relaterad operatör som kontrollerar det motsatta resultatet. – herr talman!
-ne
verifierar att värdena inte är lika med varandra.if ( 5 -ne $value ) { # do something }
Använd detta för att se till att åtgärden endast utförs om värdet inte är
5
., En bra användning-fall där skulle vara att kontrollera om en tjänst var i körläge innan du försöker starta den.variationer:
-
-ne
fall okänslig inte lika -
-ine
fall okänslig inte lika -
-cne
fall känslig inte lika
dessa är bara inversa variationer av
-eq
. Jag grupperar dessa typer tillsammans när jag listar variationer för andra operatörer.,-gt-ge-lt-L för större än eller mindre än
dessa operatörer används vid kontroll för att se om ett värde är större eller mindre än ett annat värde.
-gt -ge -lt -le
står för GreaterThan, GreaterThanOrEqual, kortare än, och LessThanOrEqual.,li>-cge
större än eller lika, skiftlägeskänslig - !,pressions
-
-lt
mindre än -
-ilt
mindre än, skiftlägeskänslig -
-clt
mindre än, skiftlägeskänslig -
-le
mindre än eller lika -
-ile
mindre än eller lika, fall okänslig -
-cle
mindre än eller lika, skiftlägeskänslig
jag vet inte varför du skulle använda skiftlägeskänsliga och okänsliga alternativ för dessa operatörer.,
-liknande jokertecken
PowerShell har sin egen jokerbaserad mönstermatchningssyntax och du kan använda den med
-like
– operatören. Dessa jokertecken mönster är ganska grundläggande.-
?
kommer att matcha ett enda tecken -
*
matchar valfritt antal tecken
$value = 'S-ATX-SQL01' if ( $value -like 'S-*-SQL??') { # do something }
det är viktigt att påpeka att mönstret matchar hela strängen., Om du behöver matcha något mitt i strängen måste du placera
*
I båda ändarna av strängen.,IV>variationer:
-
-like
case okänsliga jokertecken -
-ilike
case okänsliga jokertecken -
-clike
case känsliga jokertecken -
-notlike
case okänsliga jokertecken inte matchas -
-inotlike
case okänsliga jokertecken inte matchas -
-cnotlike
case känsliga jokertecken inte matchas
-matcha reguljära uttryck
-match
operatören kan du kontrollera en sträng för ett reguljärt uttryck baserat match. – herr talman!, Använd detta när jokertecknen inte är tillräckligt flexibla för dig.$value = 'S-ATX-SQL01' if ( $value -match 'S-\w\w\w-SQL\d\d') { # do something }
ett regex-mönster matchar som standard var som helst i strängen. Så du kan ange en substring som du vill ha matchad så här:
$value = 'S-ATX-SQL01' if ( $value -match 'SQL') { # do something }
Regex är ett komplext språk av sig själv och värt att titta på. Jag pratar mer om
-match
och de många sätten att använda regex i en annan artikel.,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 are able to check a value’s type with the
-is
operator.,if ( $value -is ) { # do something }
Du kan använda detta om du arbetar med klasser eller accepterar olika objekt över rörledningen. Du kan ha antingen en tjänst eller ett servicenamn som din ingång. Kontrollera sedan om du har en tjänst och hämta tjänsten om du bara har namnet.,
if ( $Service -isnot ) { $Service = Get-Service -Name $Service }
variationer:
-
-is
av typ -
-isnot
inte av typ
Samlingsoperatörer
När du använder de tidigare operatörerna med ett enda värde är resultatet
$true
eller$false
. Detta hanteras något annorlunda när man arbetar med en samling. Varje objekt i samlingen utvärderas och operatören returnerar istället varje värde som utvärderas till$true
.,PS> 1,2,3,4 -eq 3 3
detta fungerar fortfarande korrekt i ett
if
uttalande. Så ett värde returneras av din operatör, då är hela satsen$true
.$array = 1..6 if ( $array -gt 3 ) { # do something }
det finns en liten fälla som gömmer sig i detaljerna här som jag måste påpeka. När du använder
-ne
– operatören på detta sätt är det lätt att felaktigt titta på logiken bakåt., Att använda-ne
med en samling kommer att returnera$true
om något objekt i samlingen inte matchar ditt värde.PS> 1,2,3 -ne 4 1 2 3
detta kan se ut som ett smart trick, men vi har operatörer
-contains
och-in
som hanterar detta mer effektivt och-notcontains
kommer att göra vad du förväntar dig.-innehåller
-contains
– operatören kontrollerar samlingen för ditt värde., Så snart den hittar en matchning kommer den att returnera$true
.$array = 1..6 if ( $array -contains 3 ) { # do something }
det här är det bästa sättet att se om en samling innehåller ditt värde. Använda
Where-Object
( eller-eq
) kommer att gå hela listan varje gång och vara betydligt långsammare.,variationer:
-
-contains
fall okänslig match -
-icontains
fall okänslig match -
-ccontains
fall känslig match -
-notcontains
fall okänslig match
-ccontains
fall känslig match - – inte
-
-notcontains
fall okänslig match inte matchas -
-inotcontains
fall okänslig inte matchas -
-cnotcontains
fall känslig inte matchas
-i
-in
operatören är precis som -contains
operatören utom samlingen är på höger sida.,
$array = 1..6 if ( 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.,
-inte
-not
operatören vänder ett uttryck från$false
till$true
eller från$true
till$false
. Här är ett exempel där vi vill utföra en åtgärd när Test-Path
är $false
.
if ( -not ( Test-Path -Path $path ) )
de flesta av operatörerna vi pratade om har en variation där du inte skulle behöva använda-not
– operatören, men det finns fortfarande gånger du skulle använda den.
!,
Du kan använda!
som alias för-not
.
if ( -not $value ){} if ( !$value ){}
du kommer att se !
används mer av personer som kommer från ett annat språk som C#. Jag föredrar att skriva ut det eftersom jag har svårt att se när jag snabbt tittar på mina skript.
-och
Du kan kombinera uttryck med-and
– operatören. När du gör det måste båda sidorna vara $true
för att hela uttrycket ska vara $true
.,
if ( ($age -gt 13) -and ($age -lt 55) )
i det exemplet måste $age
vara 13 eller äldre för vänster sida och mindre än 55 för höger sida. Jag lade till extra parenteser för att göra det tydligare i det exemplet men de är valfria så länge expresionen är enkel. Här är samma exempel utan dem.
if ( $age -gt 13 -and $age -lt 55 )
utvärdering sker från vänster till höger. Om det första objektet utvärderar till $false
kommer det att avslutas tidigt och inte utföra rätt jämförelse., Detta är praktiskt när du behöver se till att ett värde finns innan du använder den. Test-Path
till exempel kommer att kasta ett fel om du ger det en$null
sökväg.
if ( $null -ne $path -and (Test-Path -Path $path) )
-eller
-or
låter dig ange två uttryck och returnerar $true
om någon av dem är $true
.
if ( $age -le 13 -or $age -ge 55 )
precis som med-and
– Operatören sker utvärderingen från vänster till höger., Förutom att om den första delen är $true
är hela satsen $true
och det kommer inte att behandla resten av uttrycket.
notera också hur syntaxen fungerar för dessa operatörer. Du behöver två separata uttryck. Jag har sett användare försöka göra något liknande $value -eq 5 -or 6
utan att inse deras misstag.
-xor exclusive eller
den här är lite ovanlig. -xor
tillåter endast ett uttryck att utvärdera till$true
., Så om båda objekten är $false
eller båda objekten är $true
, är hela uttrycket $false
. Ett annat sätt att titta på detta är uttrycket är bara $true
när resultaten av uttrycket är olika.
det är sällsynt att någon någonsin skulle använda denna logiska operatör och jag kan inte tänka mig ett bra exempel på varför jag någonsin skulle använda den.
Bitwise operators
Bitwise operators utför beräkningar på bitarna inom värdena och producerar ett nytt värde som resultat., Undervisning bitwise operatörer är utanför ramen för denna artikel, men här är listan dem.
-
-band
binär och -
-bor
binär eller -
-bxor
binär exklusiv eller -
-bnot
binär inte -
-shl
skift vänster -
-shr
Skift höger
PowerShell uttryck
Vi kan använda normal PowerShell inuti villkoret uttalande.,
if ( Test-Path -Path $Path )
Test-Path
returnerar$true
eller$false
när den körs. Detta gäller även kommandon som returnerar andra värden.
if ( Get-Process Notepad* )
det kommer att utvärdera till $true
om det finns en returnerad process och $false
om det inte finns något., Det är helt giltigt att använda pipeline uttryck eller andra PowerShell uttalanden så här:
if ( Get-Process | Where Name -eq Notepad )
dessa uttryck kan kombineras med varandra med-and
och-or
operatörer, men du kan behöva använda parentes för att bryta dem i underuttryck.
if ( (Get-Process) -and (Get-Service) )
söker efter $null
har inget resultat eller ett$null
värde utvärderar till$false
Iif
– uttalandet., När du kontrollerar specifikt för $null
är det en bästa praxis att placera $null
på vänster sida.
if ( $null -eq $value )
det finns en hel del nyanser när man hanterar $null
värden i PowerShell. Om du är intresserad av dykning djupare, jag har en artikel om allt du ville veta om $null.
variabel tilldelning
Jag glömde nästan att lägga till den här tills Prasoon Karunan V påminde mig om det.,
normalt när du tilldelar ett värde till en variabel överförs inte värdet till rörledningen eller konsolen. När du gör en variabel tilldelning i ett sub uttryck, det får vidare till rörledningen.
PS> $first = 1 PS> ($second = 2) 2
se hur tilldelningen$first
inte har någon utgång och tilldelningen$second
gör? När ett uppdrag görs i ett if
– uttalande, kommer det att utföras precis som $second
– uppdraget ovan., Här är ett rent exempel på hur du kan använda det:
if ( $process = Get-Process Notepad* ) { $process | Stop-Process }
om $process
tilldelas ett värde, blir uttalandet $true
och sedan stoppas $process
.
se till att du inte förväxlar detta med-eq
eftersom detta inte är en jämlikhetskontroll. Detta är en mer obskyr funktion som de flesta människor inte inser fungerar på detta sätt.,
alternativ exekveringsväg
uttalandetif
låter dig ange en åtgärd för inte bara när uttalandet är$true
, men också för när det är$false
. Det är här else
– satsen kommer till spel.
else
else
– satsen är alltid den sista delen avif
– satsen när den används.
i det här exemplet kontrollerar vi $path
för att se till att det är en fil. Om vi hittar filen, flyttar vi den. Om inte, skriver vi en varning., Denna typ av förgreningslogik är mycket vanlig.
kapslade if
if
ochelse
uttalanden tar ett manusblock, så vi kan placera alla PowerShell-kommando inuti dem, inklusive en annanif
– uttalande. Detta gör att du kan använda dig av mycket mer komplicerad logik.
i det här exemplet testar vi den lyckliga vägen först och vidtar sedan åtgärder på den. Om det misslyckas gör vi en annan kontroll och ger mer detaljerad information till användaren.
elseif
Vi är inte begränsade till bara en enda villkorlig kontroll., Vi kan kedja if
och else
– satser tillsammans istället för att häcka dem genom att använda elseif
– satsen.
utförandet sker från toppen till botten. Den övre if
– satsen utvärderas först. Om det är $false
går det ner till nästa elseif
eller else
I listan. Det sista else
är standardåtgärden att vidta om ingen av de andra returnerar$true
.,
byt
vid tis-punkten måste jag nämnaswitch
– satsen. Det ger en alternativ syntax för att göra flera jämförelser med ett värde. Med switch
anger du ett uttryck och det resultatet jämförs med flera olika värden. Om ett av dessa värden mach, körs matchande kodblocket. Ta en titt på det här exemplet:
$itemType = 'Role' switch ( $itemType ) { 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' } }
det finns tre möjliga värden som kan matcha $itemType
., I det här fallet kommer det att matcha med Role
och is a role
skulle bli exekverat. Jag använde ett mycket enkelt exempel bara för att ge dig lite exponering för switch
– operatören. Jag pratar mer om allt du någonsin velat veta om switch uttalande i en annan artikel.
rörledning
rörledningen är ett mycket unikt och viktigt inslag i PowerShell. Alla värden som inte undertrycks eller tilldelas en variabel placeras i rörledningen., Den if
ger oss ett sätt att dra nytta av rörledningen på ett sätt som inte alltid är uppenbart.
$discount = if ( $age -ge 55 ) { Get-SeniorDiscount } elseif ( $age -le 13 ) { Get-ChildDiscount } else { 0.00 }
varje scriptblock placerar resultaten kommandona eller värdet i rörledningen. Då tilldelar vi resultatet av if-satsen till variabeln$discount
. Det exemplet kunde lika enkelt ha tilldelat dessa värden till variabeln$discount
direkt i varje scriptblock., Jag kan inte säga att jag använder detta med if
uttalande Mycket ofta, men jag har ett exempel där jag har använt detta nyligen.
Array inline
Jag har en funktion som heter Invoke-SnowSql som startar en körbar med flera kommandoradsargument. Här är ett klipp från den funktionen där jag bygger en rad argument.
variablerna$Debug
och$Path
är parametrar för funktionen som tillhandahålls av slutanvändaren. Jag utvärderar dem inline inuti initieringen av min array., Om$Debug
är sant faller dessa värden i$snowSqlParam
på rätt plats. Samma gäller för variabeln$Path
.
förenkla komplexa operationer
det är oundvikligt att du stöter på en situation som har alldeles för många jämförelser för att kontrollera och ditt if-uttalande rullar långt från höger sida av skärmen.
de kan vara svåra att läsa och det gör dig mer benägen att göra misstag. Det finns några saker vi kan göra åt det.,
Line fortsättning
det finns några operatörer i PowerShell som låter dig slå in kommandot till nästa rad. De logiska operatörerna -and
och-or
är bra operatörer att använda om du vill bryta ditt uttryck i flera rader.
det är fortfarande mycket som händer där, men att placera varje bit på sin egen linje gör stor skillnad. Jag brukar bara göra detta när jag får mer än två jämförelser eller om jag måste rulla till höger för att läsa någon av ligic.,
Pre-calculating results
Vi kan ta det uttalandet ur if-uttalandet och bara kontrollera resultatet.
det här känns bara mycket renare än det föregående exemplet. Du får också möjlighet att använda ett variabelnamn som förklarar vad det är att du verkligen kontrollerar. Detta är också och exempel på själv dokumentera kod som sparar onödiga kommentarer.
Multiple if-satser
Vi kan dela upp detta i flera satser och kontrollera dem en åt gången. I det här fallet kommer vi att använda en flagga eller en spårningsvariabel för att kombinera resultaten.,
jag var tvungen att invertera logiken för att få flagglogiken att fungera korrekt. Varje utvärdering är en individuellif
uttalande. Fördelen med detta är att när du felsöker kan du berätta exakt vad logiken gör. Jag kunde lägga till mycket bättre verbositet samtidigt.
den uppenbara nackdelen är att det är så mycket mer kod att skriva. Koden är mer komplex att titta på eftersom det tar en enda rad logik och exploderar den i 25 eller flera linjer.
använda funktioner
Vi kan också flytta all valideringslogik till en funktion., Titta på hur rent det här ser ut i korthet.
if ( Test-SecureDriveConfiguration -ADUser $user ) { # do something }
Du måste fortfarande skapa funktionen för att göra valideringen, men det gör den här koden mycket lättare att arbeta med. Det gör denna kod lättare att testa. I dina tester kan du håna samtalet till Test-ADDriveConfiguration
och du behöver bara två tester för den här funktionen. En där den returnerar $true
och en där den returnerar $false
. Att testa den andra funktionen blir enklare eftersom den är så liten.,
kroppen av den funktionen kan fortfarande vara att en-liner vi började med eller den exploderade logiken som vi använde i det sista avsnittet. Detta fungerar bra för båda scenarierna och låter dig enkelt ändra implementeringen senare.
felhantering
en väldigt viktig användning avif
– satsen är att kontrollera felförhållandena innan du stöter på fel. Ett bra exempel är att kontrollera om en mapp redan finns innan du försöker skapa den.,
if ( -not (Test-Path -Path $folder) ) { New-Item -Type Directory -Path $folder }
Jag vill säga att om du förväntar dig att ett undantag ska hända, så är det inte riktigt ett undantag. Så kontrollera dina värden och validera dina villkor där du kan.
om du vill dyka lite mer i verklig undantagshantering har jag en artikel om allt du någonsin velat veta om undantag.
slutliga ord
if
uttalande är en sådan enkel uttalande men är en mycket grundläggande del av PowerShell. Du kommer att hitta dig själv med hjälp av detta flera gånger i nästan varje skript du skriver., Jag hoppas att du har en bättre förståelse än du hade tidigare.