Powershell: allt du ville veta om if-uttalandet

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
  • 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 vadif – 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 somif – satsen gör är att utvärdera uttrycket inom parentes., Om den utvärderar till $true, kommer den att exekvera scriptblock I hängslen. 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 kod efter if uttalande och det kommer att få exekveras., Så är inte fallet i PowerShell. Du måste tillhandahålla en fullständig scriptblock med hängslen för att den ska fungera korrekt.

      Jämförelseoperatörer

      det vanligaste Du kommer att användaif 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 är5., 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>-cgestörre än eller lika, skiftlägeskänslig

    • -ltmindre än
    • -iltmindre än, skiftlägeskänslig
    • -cltmindre än, skiftlägeskänslig
    • -lemindre än eller lika
    • -ilemindre än eller lika, fall okänslig
    • -clemindre ä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 ettif 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 -nemed 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-containsoch-insom 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ändaWhere-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
    • -ccontainsfall känslig match

  • -notcontains fall okänslig match inte matchas
  • -inotcontains fall okänslig inte matchas
  • -cnotcontainsfall 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-Pathtill 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 -andoch-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.

Share

Lämna ett svar

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