Ligesom mange andre sprog, PowerShell har erklæringer til betinget udførelse af kode i dine scripts. En af disse udsagn er if-erklæringen. I dag tager vi et dybt dykke ned i en af de mest grundlæggende kommandoer i Po .ershell.,
- Index
- Betinget udførelse
- hvis-sætning
- Sammenligning operatører
- -eq for ligestilling
- -ne ikke lige
- -gt -ge -lt -le for større end eller mindre end
- -som wildcard kampe
- -match med regulære udtryk
- -er af typen
- -eq for ligestilling
- Samling operatører
- -indeholder
- -i
- Logiske operatorer
- ikke
- !,pressions
- at Kontrollere for $null
- Variabel opgave
- Alternativ sti
- andet
- Indlejrede if
- elseif
- skift
- Pipeline
- Array inline
- Forenkle komplekse operationer
- Linje fortsættelse
- Pre-beregning af resultater
- Flere if-sætninger
- Brug af funktioner
- håndtering af Fejl
- Sidste ord
Betinget udførelse
Dine scripts vil ofte være nødvendigt at træffe beslutninger og udføre forskellige logik baseret på disse beslutninger., Dette er hvad jeg mener med betinget udførelse. Du har en erklæring eller værdi til at evaluere, derefter udføre en anden sektion af kode baseret på denne evaluering. Dette er præcis, hvad
if
erklæring gør.hvis-sætning
Her er en helt grundlæggende eksempel på det
if
erklæring:$condition = $true if ( $condition ) { Write-Output "The condition was true" }
Den første ting
if
erklæring ikke er at evaluere udtrykket i parentes., Hvis den evaluerer til$true
, udfører denscriptblock
i selerne. Hvis værdien var$false
, ville den springe over den scriptblock.i det foregående eksempel vurderede
if
sætningen kun variablen$condition
. Det var$true
og ville have udført kommandoenWrite-Output
inde i scriptblock.på nogle sprog kan du placere en enkelt kodelinje efter
if
– sætningen, og den vil blive udført., Det er ikke tilfældet i Po .ershell. Du skal angive en fuldscriptblock
med seler for at det skal fungere korrekt.sammenligningsoperatører
den mest almindelige ting, du vil bruge
if
– sætningen til, sammenligner to elementer med hinanden. Po .ershell har specielle operatører til forskellige sammenligningsscenarier. Når du bruger en sammenligningsoperatør, sammenlignes værdien i venstre side med værdien i højre side.,-E.for ligestilling
-eq
foretager en ligestillingskontrol mellem to værdier for at sikre, at de er lig med hinanden.$value = Get-MysteryValue if ( 5 -eq $value ) { # do something }
I dette eksempel, at jeg tager en kendt værdi af
5
og sammenligne det til min$value
for at se, om de er ens.en mulig brugtilfælde er at kontrollere status for en værdi, før du foretager en handling på den. Du kan få en service og kontrollere, at status kørte, før du kaldte
Restart-Service
på den.,Det er almindeligt i andre sprog som C# for at bruge
==
for ligestilling (ex:5 == $value
), men det virker ikke med powershell. En anden almindelig fejl, som folk gør, er at bruge lighedstegnet (e.:5 = $value
), der er forbeholdt tildeling af værdier til variabler. Ved at placere din kendte værdi til venstre, det gør det forkert mere akavet at gøre.denne operatør (og andre) har et par variationer.,
-
-eq
mellem store og små bogstaver ligestilling -
-ieq
mellem store og små bogstaver ligestilling -
-ceq
bogstaver ligestilling
-ne ikke lige
Mange aktører har en tilhørende aktør, der har kontrollen for det modsatte resultat.
-ne
vil kontrollere værdierne ikke lig hinanden.if ( 5 -ne $value ) { # do something }
Brug dette til at sikre, at handlingen kun udføres, hvis værdien ikke er
5
., En god brug-tilfælde, hvor det ville være at kontrollere, om en tjeneste var i løbende tilstand, før du prøver at starte den.Variationer:
-
-ne
mellem store og små bogstaver ikke lige -
-ine
mellem store og små bogstaver ikke lige -
-cne
bogstaver ikke lige
Disse er blot inverse variationer af
-eq
. Jeg grupperer disse typer sammen, når jeg viser variationer for andre operatører.,-gt-ge-lt-le for større end eller mindre end
disse operatører bruges, når de kontrollerer, om en værdi er større eller mindre end en anden værdi.
-gt -ge -lt -le
står for GreaterThan, GreaterThanOrEqual, LessThan, og LessThanOrEqual.,eater end eller lig, store og små bogstaver - !,pressions
-
-cge
større end eller lig med, bogstaver -
-lt
mindre end -
-ilt
mindre end, store og små bogstaver -
-clt
mindre end, bogstaver -
-le
mindre end eller lig med -
-ile
mindre end eller lig, store og små bogstaver -
-cle
mindre end eller lig med, bogstaver
jeg ved ikke hvorfor ville du bruge store og små bogstaver og ufølsom muligheder for disse aktører.,
-som wildcard kampe
PowerShell har sin egen wildcard-baseret pattern matching syntaks, og du kan bruge den med
-like
operatør. Disse wildildcard mønstre er ret grundlæggende.-
?
vil matche et enkelt tegn -
*
vil matche et vilkårligt antal tegn
$value = 'S-ATX-SQL01' if ( $value -like 'S-*-SQL??') { # do something }
Det er vigtigt at påpege, at det mønster, der matcher hele strengen., Hvis du har brug for at matche noget midt i strengen, skal du placere
*
i begge ender af strengen.,iv> - ikke
Variationer:
-
-like
mellem store og små bogstaver wildcard -
-ilike
mellem store og små bogstaver wildcard -
-clike
bogstaver wildcard -
-notlike
mellem store og små bogstaver wildcard, der ikke modsvares -
-inotlike
mellem store og små bogstaver wildcard, der ikke modsvares -
-cnotlike
bogstaver wildcard, der ikke modsvares
-match med regulære udtryk
-match
operatøren giver dig mulighed for at kontrollere en streng til et regulært udtryk baseret match., Brug dette, når wildildcard-mønstrene ikke er fleksible nok til dig.
$value = 'S-ATX-SQL01' if ( $value -match 'S-\w\w\w-SQL\d\d') { # do something }
et rege. – mønster matcher som standard hvor som helst i strengen. Så du kan angive en substring, som du vil matche som denne:
$value = 'S-ATX-SQL01' if ( $value -match 'SQL') { # do something }
Rege.er et komplekst sprog for sig selv og værd at undersøge. Jeg taler mere om -match
og de mange måder at bruge rege.på i en anden 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 bruge dette, hvis du arbejder med klasser eller accepterer forskellige objekter over rørledningen. Du kan enten have en tjeneste eller et servicenavn som dit input. Kontroller derefter, om du har en service, og hent tjenesten, hvis du kun har navnet.,
if ( $Service -isnot ) { $Service = Get-Service -Name $Service }
Variationer:
-
-is
type -
-isnot
ikke af typen
Samling operatører
Når du bruger den tidligere erhvervsdrivende med en enkelt værdi, resultatet er $true
eller $false
. Dette håndteres lidt anderledes, når du arbejder med en samling. Hvert element i samlingen bliver evalueret, og operatøren vil i stedet returnere hver værdi, der evaluerer til $true
.,
PS> 1,2,3,4 -eq 3 3
Dette fungerer stadig korrekt i en if
erklæring. Så en værdi returneres af din operatør, så er hele sætningen $true
.
$array = 1..6 if ( $array -gt 3 ) { # do something }
Der er en lille fælde, der gemmer sig i detaljerne her, som jeg skal påpege. Når du bruger -ne
operatøren på denne måde, er det let at fejlagtigt se logikken baglæns., Brug -ne
med en samling vil returnere $true
hvis noget element i samlingen ikke matcher din værdi.
PS> 1,2,3 -ne 4 1 2 3
Det kan ligne et smart trick, men vi har operatører -contains
og -in
at håndtere dette mere effektivt og -notcontains
korrekt, vil gøre, hvad du forventer.
-indeholder
-contains
operatøren vil kontrollere samlingen for din værdi., Så snart den finder en kamp, vender den tilbage $true
.
$array = 1..6 if ( $array -contains 3 ) { # do something }
Dette er den foretrukne måde at se, om en samling indeholder din værdi. Ved hjælp af Where-Object
( eller -eq
) vil gå hele listen hver gang, og være betydeligt langsommere.,
Variationer:
-
-contains
match mellem store og små bogstaver -
-icontains
match mellem store og små bogstaver -
-ccontains
bogstaver match -
-notcontains
mellem store og små bogstaver, der ikke modsvares -
-inotcontains
mellem store og små bogstaver, der ikke modsvares -
-cnotcontains
bogstaver, der ikke modsvares
-i
-in
operatøren er ligesom -contains
operatør undtagen samling er på højre side.,
$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.,
ikke
-not
operatør vender et udtryk fra $false
til $true
eller $true
til $false
. Her er et eksempel, hvor vi vil udføre en handling, når Test-Path
er $false
.
if ( -not ( Test-Path -Path $path ) )
de Fleste af de aktører, vi talte om, har en variation, hvor du ikke behøver at bruge -not
operatør, men der er stadig tidspunkter, du ville bruge det.
!,
Du kan bruge !
som et alias for -not
.
if ( -not $value ){} if ( !$value ){}
Du vil se !
bruges mere af folk, der kommer fra et andet sprog som C#. Jeg foretrækker at skrive det ud, fordi jeg har svært ved at se, når jeg hurtigt ser på mine scripts.
-og
Du kan kombinere udtryk med -and
operatør. Når du gør det, skal begge sider være $true
for at hele udtrykket skal være $true
.,
if ( ($age -gt 13) -and ($age -lt 55) )
I dette eksempel: $age
skal være 13 år eller ældre for venstre side, og mindre end 55 for højre side. Jeg tilføjede ekstra parenteser for at gøre det mere klart i dette eksempel, men de er valgfrie, så længe ekspressionen er enkel. Her er det samme eksempel uden dem.
if ( $age -gt 13 -and $age -lt 55 )
evaluering sker fra venstre mod højre. Hvis det første element evalueres til $false
, afslutter det tidligt og udfører ikke den rigtige sammenligning., Dette er praktisk, når du skal sørge for, at der findes en værdi, før du bruger den. Test-Path
for eksempel vil kaste en fejl, hvis du giver det en $null
sti.
if ( $null -ne $path -and (Test-Path -Path $path) )
-eller
-or
gør det muligt for dig at angive to udtryk og returnerer $true
hvis den ene af dem er $true
.
if ( $age -le 13 -or $age -ge 55 )
ligesom med -and
operatør, evaluering sker fra venstre mod højre., Bortset fra, at hvis den første del er $true
, så hele sætningen er $true
og det vil ikke behandle resten af udtrykket.
Bemærk også, hvordan syntaksen fungerer for disse operatører. Du har brug for to separate udtryk. Jeg har set brugere forsøge at gøre noget som dette $value -eq 5 -or 6
uden at indse deres fejl.
-exclusiveor eksklusiv eller
Denne er lidt usædvanlig. -xor
tillader kun et udtryk at evaluere til$true
., Så hvis begge elementer er $false
eller begge elementer er $true
, så er hele udtrykket $false
. En anden måde at se på dette er udtrykket er kun $true
når resultaterne af udtrykket er forskellige.
det er sjældent, at nogen nogensinde ville bruge denne logiske operatør, og jeg kan ikke tænke på et godt eksempel på, hvorfor jeg nogensinde ville bruge det.
Bitwiseise operatører
Bitwiseise operatører udføre beregninger på bits inden for værdierne og producere en ny værdi som resultat., Undervisning bitwiseise operatører er uden for rammerne af denne artikel, men her er listen over dem.
-
-band
binære OG -
-bor
binære ELLER -
-bxor
binære eksklusive ELLER -
-bnot
binær IKKE -
-shl
skift til venstre -
-shr
skift til højre
PowerShell udtryk
Vi kan bruge normale PowerShell inde i den betingelse, sætning.,
if ( Test-Path -Path $Path )
Test-Path
tilbage $true
eller $false
, når det udfører. Dette gælder også for kommandoer, der returnerer andre værdier.
if ( Get-Process Notepad* )
Det vil evaluere til $true
hvis der er en, der returneres proces og $false
hvis der er noget., Det er helt i orden at benytte rørledningen, udtryk eller andre PowerShell udsagn som dette:
if ( Get-Process | Where Name -eq Notepad )
Disse udtryk kan være kombineret med hinanden med -and
og -or
operatører, men du kan få brug parenteser til at bryde dem i sub-udtryk.
if ( (Get-Process) -and (Get-Service) )
Kontrol for $null
at Have en noget resultat eller en $null
værdi evalueres til $false
if
erklæring., Når du kontrollerer specifikt for $null
, er det en bedste praksis at placere $null
på venstre side.
if ( $null -eq $value )
Der er en hel del nuancer, når der beskæftiger sig med $null
værdier i PowerShell. Hvis du er interesseret i at dykke dybere, har jeg en artikel om alt, hvad du ville vide om $null.
variabel tildeling
Jeg glemte næsten at tilføje denne, indtil Prasoon Karunan v mindede mig om det.,
normalt, når du tildeler en værdi til en variabel, overføres værdien ikke til rørledningen eller konsollen. Når du udfører en variabel opgave i et underudtryk, overføres det til rørledningen.
PS> $first = 1 PS> ($second = 2) 2
Se, hvordan $first
opgave har ingen output og $second
opgave, ikke? Når en opgave udføres i enif
– erklæring, udføres den ligesom$second
– opgaven ovenfor., Her er en ren eksempel på, hvordan du kan bruge det:
if ( $process = Get-Process Notepad* ) { $process | Stop-Process }
Hvis $process
får tildelt en værdi, så vil meddelelsen være $true
og derefter $process
vil blive stoppet.
sørg for, at du ikke forveksler dette med -eq
, fordi dette ikke er en ligestillingskontrol. Dette er en mere uklar funktion, som de fleste ikke er klar over, fungerer på denne måde.,
Alternativ sti
if
erklæring giver dig mulighed for at angive en handling, ikke kun når redegørelsen er $true
, men også for, hvornår det er $false
. Det er herelse
sætningen kommer i spil.
andet
else
erklæring er altid den sidste del af if
statement, når det anvendes.
i dette eksempel kontrollerer vi $path
for at sikre, at det er en fil. Hvis vi finder filen, flytter vi den. Hvis ikke, skriver vi en advarsel., Denne type forgreningslogik er meget almindelig.
Indlejrede if –
if
og else
erklæringer tage et script blokken, så vi kan placere nogen PowerShell-kommando inde i dem, herunder en if
erklæring. Dette giver dig mulighed for at gøre brug af meget mere kompliceret logik.
i dette eksempel tester vi den glade sti først og tager derefter handling på den. Hvis det mislykkes, foretager vi en anden kontrol og giver mere detaljerede oplysninger til brugeren.
elseif
Vi er ikke begrænset til blot en enkelt betinget check., Vi kan kæde if
og else
udsagn sammen i stedet for at lægge dem ved hjælp af elseif
erklæring.
udførelsen sker fra toppen til bunden. Den øverste if
erklæring evalueres først. Hvis det er $false
, går det ned til det næste elseif
eller else
på listen. Det sidste else
er standardhandlingen, der skal udføres, hvis ingen af de andre vender tilbage $true
.,
s .itch
på tis punkt skal jeg nævneswitch
erklæring. Det giver en alternativ syntaks for at gøre flere sammenligninger med en værdi. Med switch
angiver du et udtryk, og det resultat sammenlignes med flere forskellige værdier. Hvis en af disse værdier mach, udføres den matchende kodeblok. Tag et kig på dette eksempel:
$itemType = 'Role' switch ( $itemType ) { 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' } }
Der er tre mulige værdier, som kan matche $itemType
., I dette tilfælde vil det matche Role
og is a role
ville blive udført. Jeg brugte et meget simpelt eksempel bare for at give dig en vis eksponering for switch
operatør. Jeg taler mere om alt, hvad du nogensinde har ønsket at vide om S .itch-erklæringen i en anden artikel.
Pipeline
rørledningen er et meget unikt og vigtigt træk ved Po .ershell. Enhver værdi, der ikke undertrykkes eller tildeles en variabel, placeres i rørledningen., if
giver os en måde at drage fordel af rørledningen på en måde, der ikke altid er indlysende.
$discount = if ( $age -ge 55 ) { Get-SeniorDiscount } elseif ( $age -le 13 ) { Get-ChildDiscount } else { 0.00 }
hver scriptblok placerer resultaterne kommandoerne eller værdien i rørledningen. Derefter tildeler vi resultatet af if-sætningen til variablen$discount
. Dette eksempel kunne lige så let have tildelt disse værdier til variablen$discount
direkte i hver scriptblock., Jeg kan ikke sige, at jeg bruger dette med if
erklæring meget ofte, men jeg har et eksempel, hvor jeg har brugt dette for nylig.
Array inline
Jeg har en funktion kaldet Invoke-sno .s .l, der lancerer en eksekverbar med flere kommandolinjeargumenter. Her er et klip fra den funktion, hvor jeg bygger en række argumenter.
variablerne$Debug
og$Path
er parametre for den funktion, der leveres af slutbrugeren. Jeg evaluerer dem inline inde i initialiseringen af mit array., Hvis $Debug
er sandt, falder disse værdier i $snowSqlParam
på det rigtige sted. Det samme gælder for variablen $Path
.
forenkle komplekse operationer
det er uundgåeligt, at du løber ind i en situation, der har alt for mange sammenligninger til at kontrollere, og din if-erklæring ruller langt væk fra højre side af skærmen.
de kan være svære at læse, og det gør dig mere tilbøjelig til at begå fejl. Der er et par ting, vi kan gøre ved det.,
Linjeforlængelse
Der er nogle operatører i Po .ershell, der lader dig pakke dig kommando til næste linje. De logiske operatører -and
og -or
er gode operatører at bruge, hvis du vil bryde dit udtryk i flere linjer.
der foregår stadig meget der, men at placere hvert stykke på sin egen linje gør en stor forskel. Jeg gør det generelt kun, når jeg får mere end to sammenligninger, eller hvis jeg skal rulle til højre for at læse nogen af ligikerne.,
Forberegningsresultater
Vi kan tage denne erklæring ud af if-sætningen og kun kontrollere resultatet.
dette føles bare meget renere end det foregående eksempel. Du får også mulighed for at bruge et variabelnavn, der forklarer, hvad det er, du virkelig tjekker. Dette er også et eksempel på selvdokumenterende kode, der sparer unødvendige kommentarer.
flere hvis udsagn
Vi kan bryde dette op i flere udsagn og kontrollere dem en ad gangen. I dette tilfælde bruger vi et flag eller en sporingsvariabel til at kombinere resultaterne.,
Jeg var nødt til at vende logikken for at få flaglogikken til at fungere korrekt. Hver evaluering er en individuelif
erklæring. Fordelen ved dette er, at når du debugger, kan du fortælle præcis, hvad logikken gør. Jeg var i stand til at tilføje meget bedre verbositet på samme tid.
den åbenlyse ulempe er, at det er så meget mere kode at skrive. Koden er mere kompleks at se på, da det tager en enkelt linje af logik og eksploderer det i 25 eller flere linjer.
ved hjælp af funktioner
kan vi også flytte al den valideringslogik til en funktion., Se på, hvor rent dette ser på et øjeblik.
if ( Test-SecureDriveConfiguration -ADUser $user ) { # do something }
Du skal stadig oprette funktionen for at udføre valideringen, men det gør denne kode meget lettere at arbejde med. Det gør denne kode lettere at teste. I dine test kan du mocke opkaldet til Test-ADDriveConfiguration
, og du har kun brug for to test til denne funktion. En, hvor den returnerer $true
og en, hvor den returnerer $false
. Test af den anden funktion vil være enklere, fordi den er så lille.,
kroppen af denne funktion kunne stadig være den ene liner, vi startede med, eller den eksploderede logik, som vi brugte i det sidste afsnit. Dette fungerer godt for begge scenarier og giver dig mulighed for nemt at ændre denne implementering senere.
fejlhåndtering
en virkelig vigtig brug af if
erklæring er at kontrollere for fejlbetingelser, før du løber ind i fejl. Et godt eksempel er at kontrollere, om der allerede findes en mappe, før du prøver at oprette den.,
if ( -not (Test-Path -Path $folder) ) { New-Item -Type Directory -Path $folder }
Jeg kan godt lide at sige, at hvis du forventer, at en undtagelse skal ske, er det ikke rigtig en undtagelse. Så tjek dine værdier og valider dine forhold, hvor du kan.
Hvis du vil dykke lidt mere ind i faktisk undtagelseshåndtering, har jeg en artikel om alt, hvad du nogensinde har ønsket at vide om undtagelser.
afsluttende ord
if
erklæring er sådan en simpel erklæring, men er et meget grundlæggende stykke Po .ershell. Du vil finde dig selv ved hjælp af denne flere gange i næsten hver script du skriver., Jeg håber du har en bedre forståelse end du havde før.