- 05/23/2020
- 18 minutter til at læse
-
- j
- x
- t
- D
- s
Ligesom mange andre sprog, PowerShell har erklæringer til betinget udførelse af kode i yourscripts. En af disse udsagn er If-erklæringen., I dag vil vi tage et dybt dykke ind i en afde mest grundlæggende kommandoer i Po .ershell.
Bemærk
den originale version af denne artikel blev vist på bloggen skrevet af @Kevinmar .uette. Thepo .ershell team tak Kevin for at dele dette indhold med os. Tjek venligst hans blog atPowerShellExplained.com.
betinget udførelse
dine scripts skal ofte 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, såudfør et andet afsnit af kode baseret på den evaluering. Dette er præcis, hvad if
erklæring gør.
hvis-sætning
Her er en grundlæggende eksempel på det if
erklæring:
$condition = $trueif ( $condition ){ Write-Output "The condition was true"}
Den første ting if
erklæring ikke er at evaluere udtrykket i parentes. Hvis det evaluereresto $true
, udfører den scriptblock
i selerne., Hvis værdien var $false
, så ville det springe over scriptblock.
i det foregående eksempel vurderede if
– erklæringen bare variablen $condition
. Det var$true
og ville have udført kommandoen Write-Output
inde i scriptblock.
på nogle sprog, kan du placere en enkelt linje kode efter if
erklæring, og det getse .ecuted. Det er ikke tilfældet i Po .ershell. Du skal angive en fuld scriptblock
med seler forit at fungere korrekt.,
sammenligningsoperatører
den mest almindelige anvendelse afif
– erklæringen for sammenligner to elementer med hinanden. Po .ershell harspecielle operatører til forskellige sammenligningsscenarier. Når du bruger en sammenligningsoperatør, skal værdienpå venstre side sammenlignes med værdien på 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-MysteryValueif ( 5 -eq $value ){ # do something}
I dette eksempel tager jeg en kendt værdi af 5
og sammenligne det til min $value
for at se, om theymatch.
en mulig brugssag er at kontrollere status for en værdi, før du foretager en handling på den. Du kunne få en service og kontrollere, at status kørte, før du kaldte Restart-Service
på det.
Det er almindeligt i andre sprog som C# for at bruge ==
for ligestilling (ex: 5 == $value
), men det betyder’twork 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 på theleft, det gør denne fejl mere akavet at gøre.
denne operatør (og andre) har et par variationer.,
-
-eq
store og små bogstaver ligestilling -
-ieq
store og små bogstaver ligestilling -
-ceq
case-sensitive ligestilling
-ne ikke lige
Mange aktører har en tilhørende aktør, der har kontrollen for det modsatte resultat. -ne
verificerer, at værdierne ikke svarer til hinanden.
if ( 5 -ne $value ){ # do something}
Brug dette til at sikre dig, at handlingen kun udføres, hvis værdien ikke er 5
., En god brug-tilfælde hvorville være at kontrollere, om en tjeneste var i løbende tilstand, før du forsøger at starte den.
Variationer:
-
-ne
store og små bogstaver ikke lige -
-ine
store og små bogstaver ikke lige -
-cne
mellem store og små bogstaver ikke lige
Disse er omvendt variationer af -eq
. Jeg grupperer disse typer sammen, når jeg viser variationerfor 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 med store og små bogstaver
-cge
større end eller lig med,- / store bogstaver-lt
mindre end-ilt
mindre end, store og små bogstaver-clt
mindre end, mellem store og små bogstaver-le
mindre end eller lig med-ile
mindre end eller lig med, store og små bogstaver-cle
mindre end eller lig med,- / store bogstaverjeg ved ikke hvorfor du vil bruge 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.
-
?
matcher et enkelt tegn -
*
matcher et vilkårligt antal tegn
$value = 'S-ATX-SQL01'if ( $value -like 'S-*-SQL??'){ # do something}
Det er vigtigt at pointere, at det mønster, der matcher hele strengen. Hvis du skal matchenoget midt i strengen, skal du placere *
i begge ender af strengen.,e”>
Variationer:
-
-like
store og små bogstaver wildcard -
-ilike
store og små bogstaver wildcard -
-clike
case-sensitive wildcard -
-notlike
store og små bogstaver wildcard, der ikke modsvares -
-inotlike
store og små bogstaver wildcard, der ikke modsvares -
-cnotlike
case-sensitive wildcard, der ikke modsvares
-match med regulære udtryk
-match
operatøren giver dig mulighed for at kontrollere en streng til en almindelig-udtryk-baseret match., Brug thiswhhen wildildcard mønstre er ikke fleksible nok for 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 derdu vil matche sådan:
$value = 'S-ATX-SQL01'if ( $value -match 'SQL'){ # do something}
Rege.er et komplekst sprog af sig selv og værd at undersøge. Jeg taler mere om -match
ogmange 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 can 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. Youcould have enten en tjeneste eller et servicenavn som dit input. Kontroller derefter, om du har en serviceog 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 returnerer hver værdi, der evaluerer til $true
.,
PS> 1,2,3,4 -eq 33
Dette fungerer stadig korrekt i en if
erklæring. Så en værdi returneres af din operatør, såhele erklæring er $true
.
$array = 1..6if ( $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 acollection returns $true
hvis et element i samlingen ikke matcher din værdi.,
PS> 1,2,3 -ne 4123
Det kan ligne et smart trick, men vi har operatører -contains
og -in
at håndtere denne moreefficiently. Og -notcontains
gør hvad du forventer.
-indeholder
-contains
operatøren kontrollerer samlingen for din værdi. Så snart den finder en kamp, vender den tilbage $true
.
$array = 1..6if ( $array -contains 3 ){ # do something}
Dette er den foretrukne måde at se, om en samling indeholder din værdi., Brug af Where-Object
(eller-eq
) går hele listen hver gang og er markant langsommere.,
Variationer:
-
-contains
store og små bogstaver match -
-icontains
store og små bogstaver match -
-ccontains
case-sensitive match -
-notcontains
store og små bogstaver, der ikke modsvares -
-inotcontains
store og små bogstaver, der ikke modsvares -
-cnotcontains
bogstaver, der ikke modsvares
-i
-in
operatøren er ligesom -contains
operatøren undtagen samling er på højre-handside.,
$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.,
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 gange, det er nyttigt.
!, operatøren
Du kan bruge !
som et alias for -not
.
if ( -not $value ){}if ( !$value ){}
Du kan se !
bruges mere af folk, der kommer fra et andet sprog som C#. Jeg foretrækker at skrive itout, 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. Iadded ekstra parenteser for at gøre det klarere i dette eksempel, men de er valgfrie, så længe udtrykket er enkelt. 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 punkt evalueres til $false
, forlader det tidligt og udfører ikke den rigtige sammenligning. Dette er praktisk, når du skal sikre dig, at der findes en værdi, før du bruger den., For eksempel kaster Test-Path
en fejl, hvis du giver den 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, sker evalueringen fra venstre mod højre., Bortset fra at hvis den første del er $true
, så er hele sætningen $true
, og det behandler ikke 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 emner er $false
eller begge elementer er $true
, så er hele udtrykket $false
. En anden måde Atse 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 et godt eksempel som tohhy 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 thethem.
-
-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 vender tilbageandre værdier.
if ( Get-Process Notepad* )
Det vurderer $true
hvis der er en, der returneres proces og $false
hvis der’sn’thing., Det’sperfectly gyldigt 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 måske har til brug parenteser til at bryde dem i subexpressions.
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 tjekker 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.,
if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}
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 tildeling i et sub-udtryk, bliver det videreført tilpipeline.
PS> $first = 1PS> ($second = 2)2
se, hvordan$first
– tildelingen ikke har nogen output, og $second
– tildelingen gør? Når en assignmentis udført i enif
erklæring, udfører den ligesom$second
opgaven ovenfor., Her er en cleanexample om, hvordan du kan bruge det:
if ( $process = Get-Process Notepad* ){ $process | Stop-Process}
Hvis $process
får tildelt en værdi, så oversigten er $true
og $process
bliver stoppet.
sørg for, at du ikke forveksler dette med -eq
, fordi dette ikke er en ligestillingskontrol. Dette er en moreobscure-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
, butalso, når det er $false
. Det er her else
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 insidethem, 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, gør vi en anden kontrol og for at give mere detaljerede oplysninger til brugeren.
elseif
Vi er ikke begrænset til blot en enkelt betinget check., Vi kan kæde if
og else
statementstogether 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. Den sidste else
er default handling at tage, hvis ingen af de andre vender tilbage$true
.,
s .itch
På dette tidspunkt skal jeg nævne switch
erklæring. Det giver en alternativ syntaks til doingmultiple sammenligninger med en værdi. Med switch
angiver du et udtryk, og det resultat får detsammenlignet med flere forskellige værdier. Hvis en af disse værdier matcher, er den matchende kodeblok udført. Se 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, der kan matche $itemType
. I dette tilfælde matcher det med Role
., Jeg brugte et simpelt eksempel bare for at give dig en vis eksponering for switch
operatør. Jeg taler mereom alt, hvad du nogensinde har ønsket at vide om S .itch-erklæringen i en anden artikel.
Pipeline
rørledningen er et unikt og vigtigt træk ved Po .ershell. Enhver værdi, der ikke suppressedor tildelt en variabel bliver placeret 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 viresultatet af if
sætningen til$discount
variablen. Dette eksempel kunne have lige så lettildelt disse værdier til variablen$discount
direkte i hver scriptblock. Jeg kan ikke sige, at jeg bruger dette med if
erklæring ofte, men jeg har et eksempel, hvor jeg brugte dette for nylig.,
Array inline
jeg har en funktion kaldet Påberåbe-SnowSql, der lancerer en eksekverbar med flere kommando-linearguments. 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, så er disse værdierfalder ind i $snowSqlParam
på det rigtige sted. Det samme gælder 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 dinIf
erklæring ruller langt 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., Den logicaloperators -and
og -or
er god operatører til at bruge, hvis du ønsker at bryde dit udtryk intomultiple linjer.
Der er stadig meget der foregår der, men at placere hvert stykke på sin egen linje gør en stor forskel.Jeg bruger generelt dette, når jeg får mere end to sammenligninger, eller hvis jeg skal rulle til højre for at læse nogen af logikken.
Forudberegningsresultater
Vi kan tage denne erklæring ud af if
erklæring og kun kontrollere resultatet.
dette føles bare meget renere end det foregående eksempel., Du får også mulighed for at bruge avariable navn, der forklarer, hvad det er, at 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 aflag 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 debugging, du kan telle .actly 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åsom 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å aglance.,
if ( Test-SecureDriveConfiguration -ADUser $user ){ # do something}
Du skal stadig oprette funktionen til at udføre valideringen, men det gør denne kode meget lettere atarbejde med. Det gør denne kode lettere at teste. I dine test kan du mocke opkaldet tilTest-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 er enklere, fordi den erså lille.
kroppen af denne funktion kunne stadig være den one-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 detgennemførelse senere.
fejlhåndtering
en vigtig anvendelse af if
erklæring er at kontrollere for fejlbetingelser, før du løber indfejl. 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 omalt hvad du nogensinde har ønsket at vide om undtagelser.
afsluttende ord
if
erklæring er sådan en simpel erklæring, men er et grundlæggende stykke Po .ershell. Du willillfind 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.