allt du ville veta om if-uttalandet

  • 05/23/2020
  • 18 minuter att läsa
    • j
    • x
    • t
    • d
    • s

liksom många andra språk har PowerShell uttalanden för villkorligt exekvering av kod i dinskript. En av dessa uttalanden är If-uttalandet., Idag kommer vi att ta ett djupt dyk in i en avDe mest grundläggande kommandona i PowerShell.

Obs

den ursprungliga versionen av denna artikel dök upp på bloggen skriven av @KevinMarquette. ThePowerShell team tack Kevin för att dela innehållet med oss. Vänligen kolla in hans blogg atPowerShellExplained.com.

villkorlig utförande

dina skript behöver ofta 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, dåutvärdera ett annat avsnitt av koden baserat på den utvärderingen. Detta är precis vadif – satsen gör.

if-satsen

här är ett grundläggande exempel påif – satsen:

$condition = $trueif ( $condition ){ Write-Output "The condition was true"}

det första somif – satsen gör är att utvärdera uttrycket inom parentes. Om det utvärderar $true, kör det scriptblock I axlarna., Om värdet var $false, skulle det hoppa över det scriptblock.

i föregående exempel utvärderadeif – satsen bara variabeln$condition. Det var$true och skulle ha utfört kommandot Write-Output inuti scriptblock.

på vissa språk kan du placera en enda rad med kod efter if – uttalandet och det getsexecuted. Det är inte fallet i PowerShell. Du måste tillhandahålla en fullständigscriptblock med hängslen forit att fungera korrekt.,

Jämförelseoperatörer

den vanligaste användningen avif – satsen för är att jämföra två objekt med varandra. PowerShell harspeciella operatörer för olika jämförelsescenarier. När du använder en jämförelseoperatör, värdetpå vänster sida jämförs 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-MysteryValueif ( 5 -eq $value ){ # do something}

i det här exemplet tar jag ett känt värde för 5 och jämför det med min $value för att se om theymatch.

ett möjligt användningsfall är att kontrollera statusen för ett värde innan du vidtar en åtgärd på det. Du kunde 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 på theleft, det gör det misstaget mer besvärligt att göra.

den här operatören (och andra) har några variationer.,

  • -eq case-okänslig jämlikhet
  • -ieq case-okänslig jämlikhet
  • -ceq fallkänslig jämlikhet

-ne inte lika

många operatörer har en relaterad operatör som kontrollerar motsatsen resultat. -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 är5., En bra användning-fall därskulle 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 fallkänslig inte lika

dessa är inversa variationer av -cnefallkänslig inte lika

id = ”626395ddfd” > . Jag grupperar dessa typer tillsammans när jag listar variationerfö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.,Eater än eller lika, case-okänslig

  • -cge större än eller lika, case-sensitive
  • -lt mindre än
  • -ilt mindre än, case-okänslig
  • -cltmindre än, skiftlägeskänslig
  • -lemindre än eller lika
  • -ilemindre än eller lika, skiftlägeskänslig
  • -clemindre än eller lika, skiftlägeskänslig
  • Jag vet inte varför du skulle använda skiftlägeskänslig 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.

    • ? matchar 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.,e”>

    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 skiftlägeskänsliga jokertecken inte matchas

    -matcha Reguljärt uttryck

    operatören -match låter dig för att kontrollera en sträng för en Reguljärt uttrycksbaserad matchning., Använd dettanä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 regexmönster matchar var som helst i strängen som standard. Så du kan ange en substring somdu vill matcha 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 ochDe 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 can 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 antingen ha en tjänst eller ett servicenamn som din inmatning. Kontrollera sedan om du har en tjänstoch hämta tjänsten om du bara har namnet.,

    if ( $Service -isnot ){ $Service = Get-Service -Name $Service}

    variationer:

    • -is av typen
    • -isnot inte av typen

    samlingsoperatörer

    När du använder de tidigare operatörerna med ett enda värde är resultatet $true eller $false. Detta ishandled något annorlunda när man arbetar med en samling. Varje objekt i samlingen getsevalueras och operatören returnerar varje värde som utvärderar till $true.,

    PS> 1,2,3,4 -eq 33

    detta fungerar fortfarande korrekt i ettif – uttalande. Så ett värde returneras av din operatör, dåwhole-satsen är $true.

    $array = 1..6if ( $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. Använda-ne med acollection returns$true om något objekt i samlingen inte matchar ditt värde.,

    PS> 1,2,3 -ne 4123

    detta kan se ut som ett smart trick, men vi har operatörer -contains och -in som hanterar detta mereffektivt. Och-notcontains gör vad du förväntar dig.

    -innehåller

    -contains – operatören kontrollerar samlingen för ditt värde. Så snart den hittar en match, itreturns $true.

    $array = 1..6if ( $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ändaWhere-Object (eller-eq) går hela listan varje gång och är betydligt långsammare.,

    variationer:

    • -contains case-okänslig match
    • -icontains case-okänslig match
    • -ccontains case-känslig match
    • -notcontains case-okänslig inte matchad
    • -inotcontains Case-okänslig inte matchad
    • -cnotcontains skiftlägeskänslig inte matchad

    -in

    -in operatören är precis som-contains operatör utom samlingen är på höger sida.,

    $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.,

    -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 variant där du inte behöver använda-not – operatören. Men det finns fortfarande gånger det är användbart.

    !, operator

    Du kan använda !som alias för -not.

    if ( -not $value ){}if ( !$value ){}

    Du kan se! används mer av personer som kommer från ett annat språk som C#. Jag föredrar att skriva itout eftersom jag har svårt att se när snabbt titta 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. Iadded extra parenteser för att göra det tydligare i det exemplet men de är valfria så länge expressionen ä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, lämnar det tidigt och utför inte rätt jämförelse. Detta är praktiskt när du behöver se till att ett värde finns innandu använder det., Till exempel,Test-Path kastar ett fel om du ger det en$null sökväg.

    if ( $null -ne $path -and (Test-Path -Path $path) )

    -eller

    -or tillåter dig att 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 denförsta delen är $true, är hela satsen $true och den behandlar inte resten av expressionen.

    notera också hur syntaxen fungerar för dessa operatörer. Du behöver två separata uttryck. Ihave sett användare försöker 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 är $true är hela uttrycket $false. Ett annat sätt atttitta 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 som Towy 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 resultatet., Undervisning bitwise operatörer är utanför ramen för denna artikel, men här är listan thedem.

    • -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 återvänderandra värden.

    if ( Get-Process Notepad* )

    den utvärderar till$true om det finns en returnerad process och$false om det inte finns något., Det är korrekt att använda pipeline-uttryck eller andra PowerShell-uttryck som detta:

    if ( Get-Process | Where Name -eq Notepad )

    dessa uttryck kan kombineras med varandra med operatörerna -and och -or, men du kanmåste använda parentes för att bryta dem i subexpressioner.

    if ( (Get-Process) -and (Get-Service) )

    söker efter $null

    har inget resultat eller ett$null värde utvärderar till$false Iif – uttalandet., Vid kontrollspecifikt för $nullär det bästa sättet 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 att dyka djupare, har jag 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.,

    if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}

    normalt när du tilldelar ett värde till en variabel överförs inte värdet till rörledningen ellerkonsol. När du gör en variabel tilldelning i ett subuttryck, Det går vidare till thepipeline.

    PS> $first = 1PS> ($second = 2)2

    se hur tilldelningen$first inte har någon utgång och tilldelningen$second gör? När en överlåtelse görs i ett if – uttalande, körs det precis som $second – uppdraget ovan., Här är ett cleanexample om hur du kan använda det:

    if ( $process = Get-Process Notepad* ){ $process | Stop-Process}

    om$process tilldelas ett värde, är uttalandet$true och$process stoppas.

    se till att du inte förväxlar detta med-eq eftersom detta inte är en jämlikhetskontroll. Detta är en moreobscure funktion som de flesta människor inte inser fungerar på detta sätt.,

    alternativ körningssökväg

    uttalandetif låter dig ange en åtgärd för inte bara när uttalandet är$true, men också 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 insidethem, 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 Vien annan kontroll och för att ge mer detaljerad information till användaren.

    elseif

    Vi är inte begränsade till bara en enda villkorlig kontroll., Vi kan kedjaif ochelse uttalandentillsammans istället för att häcka dem genom att användaelseif uttalande.

    utförandet sker från toppen till botten. Den övre if – satsen utvärderas först. Om detta är $false flyttas det ner till nästa elseif eller else I listan. Det sista elseär default-åtgärden att vidta om ingen av de andra returnerar$true.,

    byt

    Vid denna tidpunkt måste jag nämnaswitch – satsen. Det ger en alternativ syntax för att göraflera jämförelser med ett värde. Med switch anger du ett uttryck och resultatet getscompared med flera olika värden. Om ett av dessa värden matchar är matchningskodblocket exekverat. 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 matchar det med Role., Iused ett enkelt exempel bara för att ge dig viss exponering förswitch – operatören. Jag pratar mer om allt du någonsin velat veta om switch-uttalandet i en annan artikel.

    rörledning

    rörledningen är ett unikt och viktigt inslag i PowerShell. Alla värden som inte suppressedor tilldelas en variabel placeras i rörledningen. if ger oss ett sätt att ta fördel 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. Sedan tilldelar vi resultatet avif – satsen till$discount – variabeln. Det exemplet kunde ha lika lätttilldelat dessa värden till variabeln$discount direkt i varje scriptblock. Jag kan inte säga att Iuse detta med if uttalande ofta, men jag har ett exempel där jag använde detta nyligen.,

    Array inline

    Jag har en funktion som heter Invoke-SnowSql som lanserar en körbar med flera kommandoradsdokument. 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, kommer dessa värden att hamna 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 att kontrollera och dinIf statement 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 som 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., Logicoperators-and och-or är bra operatörer att använda om du vill bryta ditt uttryck iflera linjer.

    det är fortfarande mycket som händer där, men att placera varje bit på sin egen linje gör stor skillnad.Jag brukar använda detta när jag får mer än två jämförelser eller om jag måste rulla till höger förläs någon av logiken.

    Pre-calculating results

    Vi kan ta det uttalandet urif – 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 avariable namn som förklarar vad det är att du verkligen kontrollerar. Detta är också och exempel påsjälvdokumenterande 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 använder vi aflag 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 enindividuell if uttalande., Fördelen med detta är att när du felsöker kan du telexactly 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åsom 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 detta ser på aglance.,

    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 enklare attarbeta med. Det gör denna kod lättare att testa. I dina tester kan du håna samtalet tillTest-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 är enklare eftersom det ärså liten.

    kroppen av denna funktion kan fortfarande vara att en-liner vi började med eller den exploderade logik somvi använde i det sista avsnittet., Detta fungerar bra för båda scenarierna och låter dig enkelt ändra detgenomförandet senare.

    felhantering

    en viktig användning avif – satsen är att kontrollera felförhållandena innan du kör in ifel. 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 egentligen inget undantag. Så kontrollera dina värden och validera dina villkor där du kan.,

    om du vill dyka lite mer i faktisk undantagshantering, har jag en artikel omallt du någonsin velat veta om undantag.

    sista ord

    if uttalande är en sådan enkel uttalande men är en 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.

    Lämna ett svar

    Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *