Powershell: wszystko, co chcesz wiedzieć o instrukcji IF

podobnie jak wiele innych języków, PowerShell ma instrukcje do warunkowego wykonywania kodu w skryptach. Jednym z tych stwierdzeń jest stwierdzenie if. Dzisiaj przyjrzymy się jednej z najbardziej podstawowych komend w PowerShell.,

  • indeks
  • wykonanie warunkowe
  • Instrukcja if
  • operatory porównania
    • -eq dla równości
      • -ne Nie równe
    • -gt-Ge-lt-le dla większej lub mniejszej niż
    • -podobne do wieloznacznych dopasowań
    • -dopasowanie wyrażenia regularnego
    • -jest typu
  • operatory zbioru
    • -zawiera
    • -w
  • operatory logiczne
    • -nie
      • !,presje
        • sprawdzanie pod kątem $null
        • przypisanie zmiennej
      • alternatywna ścieżka wykonania
        • else
        • zagnieżdżenie if
        • ElseIf
        • przełącznik
      • rurociąg
        • tablica Inline
      • Uprość złożone operacje
        • kontynuacja linii
        • wstępne obliczanie wyników
        • wielokrotne polecenia if
        • korzystanie z funkcji
      • obsługa błędów
      • końcowe słowa

      warunkowe wykonywanie

      twoje skrypty często będą musiały podejmować decyzje i wykonywać inną logikę opartą na tych decyzjach., To jest to, co mam na myśli przez warunkowe wykonanie. Masz jedną instrukcję lub wartość do oceny, a następnie wykonaj różne sekcje kodu na podstawie tej oceny. To jest dokładnie to, co robi if.

      Instrukcja if

      oto bardzo podstawowy przykładif Instrukcja:

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

      pierwsza rzecz, jaką if instrukcja jest ewaluacją wyrażenia w nawiasach., Jeśli wartość ta zostanie obliczona na $true, to spowoduje wykonanie scriptblock w nawiasach klamrowych. Jeśli wartość wynosi $false, to pomija ten blok skryptów.

      w poprzednim przykładzie, polecenie ifoceniało zmienną $condition. Było to $true I wykonałoby polecenieWrite-Output wewnątrz bloku skryptów.

      w niektórych językach można umieścić pojedynczy wiersz kodu po instrukcji if i zostanie on wykonany., Tak nie jest w PowerShell. Musisz dostarczyć pełny scriptblock z szelkami, aby działał poprawnie.

      operatory porównywania

      najczęściej używasz instrukcjiif do porównywania dwóch elementów ze sobą. Powershell ma specjalne operatory dla różnych scenariuszy porównawczych. W przypadku użycia operatora porównania wartość po lewej stronie jest porównywana z wartością po prawej stronie.,

      -eq dla równości

      -eq sprawdza równość dwóch wartości, aby upewnić się, że są one równe sobie.

       $value = Get-MysteryValue if ( 5 -eq $value ) { # do something }

      w tym przykładzie biorę znaną wartość 5 I porównuję ją z moją $value, aby sprawdzić, czy pasują.

      jednym z możliwych zastosowań jest sprawdzenie stanu wartości przed podjęciem na niej działania. Możesz uzyskać usługę i sprawdzić, czy status był uruchomiony przed wywołaniem Restart-Service na nim.,

      w innych językach, takich jak C#, często używa się== dla równości (np.5 == $value), ale to nie działa z powershell. Innym częstym błędem popełnianym przez ludzi jest użycie znaku równości (np. 5 = $value), który jest zarezerwowany do przypisywania wartości do zmiennych. Umieszczając swoją znaną wartość po lewej stronie, sprawia, że błąd jest bardziej niezręczny.

      ten operator (i inne) ma kilka odmian.,

      • -eq rozróżnianie wielkości liter
      • -ieq rozróżnianie wielkości liter
      • -ceq rozróżnianie wielkości liter

      -nie jest równe

      wiele operatorów ma powiązanego operatora, który sprawdza przeciwny wynik. -ne sprawdza, czy wartości nie są sobie równe.

       if ( 5 -ne $value ) { # do something }

      Użyj tego, aby upewnić się, że akcja jest wykonywana tylko wtedy, gdy wartość nie jest 5., Dobre przypadki użycia, w których należy sprawdzić, czy usługa jest w stanie uruchomionym, zanim spróbujesz ją uruchomić.

      zmiany:

      • -ne wielkość liter nie jest równa
      • -ine wielkość liter nie jest równa
      • -cne wielkość liter nie jest równa

      są to tylko odwrotne wariacje -eq. Będę grupować te typy razem, gdy wymienię odmiany dla innych operatorów.,

      -gt-ge-lt-le dla większej lub mniejszej niż

      operatory te są używane podczas sprawdzania, czy wartość jest większa lub mniejsza od innej wartości. -gt -ge -lt -le oznacza GreaterThan, GreaterThanOrEqual, LessThan i LessThanOrEqual.,eater than or equal, case sensitive

    • -cge większe lub równe, case sensitive
    • -lt mniej niż
    • -ilt mniej niż, case sensitive
    • -clt mniej niż, rozróżniana wielkość liter
    • -le mniej niż lub równe
    • -ile mniej lub równe, rozróżniana wielkość liter
    • -cle mniej lub równe, rozróżnianie wielkości liter

    Nie wiem, po co używać opcji rozróżniania wielkości liter i niewrażliwości dla tych operatorów.,

    -podobne do wieloznacznych dopasowań

    PowerShell ma swoją własną składnię dopasowania wzorców wieloznacznych i można go używać z operatorem-like. Te wzory wieloznaczne są dość podstawowe.

    • ? będzie pasował do dowolnego pojedynczego znaku
    • * będzie pasował do dowolnej liczby znaków
     $value = 'S-ATX-SQL01' if ( $value -like 'S-*-SQL??') { # do something }

    ważne jest aby zaznaczyć, że wzór pasuje do całego ciągu., Jeśli chcesz dopasować coś w środku łańcucha, musisz umieścić *na obu końcach łańcucha.,iv>

    wariacje:

    • -like rozróżnialna wielkość liter
    • -ilike rozróżnialna wielkość liter
    • -clike rozróżnialna wielkość liter
    • -notlike rozróżnialna wielkość liter nie jest dopasowana
    • -inotlike rozróżnialna wielkość liter nie jest dopasowana
    • -cnotlike rozróżnialna wielkość liter nie jest dopasowana

    -dopasuj Wyrażenie regularne

    -match operator pozwala sprawdzić ciąg znaków dla dopasowania opartego na wyrażeniach regularnych., Użyj tego, gdy wzory wieloznaczne nie są wystarczająco elastyczne.

     $value = 'S-ATX-SQL01' if ( $value -match 'S-\w\w\w-SQL\d\d') { # do something }

    domyślnie wzór regex będzie pasował w dowolnym miejscu łańcucha. Możesz więc określić substring, który chcesz dopasować w następujący sposób:

     $value = 'S-ATX-SQL01' if ( $value -match 'SQL') { # do something }

    Regex jest złożonym językiem, który sam w sobie jest wart przyjrzenia się. Mówię więcej o -match i wielu sposobach użycia regex w innym artykule.,

    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 }

    możesz tego użyć, jeśli pracujesz z klasami lub akceptujesz różne obiekty w potoku. Możesz mieć usługę lub nazwę usługi jako dane wejściowe. Następnie sprawdź, czy masz usługę i pobierz usługę, jeśli masz tylko nazwę.,

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

    wariacje:

    • -is typu
    • -isnot Nie typu

    operatory kolekcji

    gdy używasz poprzednich operatorów z pojedynczą wartością, wynikiem jest$truelub$false. Jest to traktowane nieco inaczej podczas pracy z kolekcją. Każdy element w kolekcji zostanie oceniony, a operator zwróci każdą wartość, która zostanie oceniona do $true.,

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

    to nadal działa poprawnie w instrukcji if. Tak więc wartość jest zwracana przez operatora, wtedy cała instrukcja jest $true.

     $array = 1..6 if ( $array -gt 3 ) { # do something }

    w szczegółach kryje się jedna mała pułapka, na którą muszę zwrócić uwagę. Używając w ten sposób operatora -ne, łatwo jest błędnie spojrzeć na logikę wstecz., Użycie-ne z kolekcją zwróci $true jeśli jakikolwiek element w kolekcji nie pasuje do twojej wartości.

     PS> 1,2,3 -ne 4 1 2 3

    może to wyglądać na sprytną sztuczkę, ale mamy operatory-containsI-in które obsługują to bardziej efektywnie i -notcontains poprawnie zrobi to, czego oczekujesz.

    -zawiera

    operator-contains sprawdzi kolekcję pod kątem Twojej wartości., Gdy tylko znajdzie dopasowanie, zwróci $true.

     $array = 1..6 if ( $array -contains 3 ) { # do something }

    jest to preferowany sposób sprawdzania, czy Kolekcja zawiera twoją wartość. Użycie Where-Object ( lub -eq) spowoduje przejście całej listy za każdym razem i będzie znacznie wolniejsze.,

    zmiany:

    • -contains dopasowanie rozróżniające wielkość liter
    • -icontains dopasowanie rozróżniające wielkość liter
    • -ccontains dopasowanie rozróżniające wielkość liter
    • -notcontainswielkość liter nie jest dopasowana

  • -inotcontainswielkość liter nie jest dopasowana
  • -cnotcontainswielkość liter nie jest dopasowana

-w

-inoperator jest taki sam jak operator-containsz tym, że kolekcja znajduje się po prawej stronie.,

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

-nie

-not operator odwraca wyrażenie z $false do $true lub z $true do $false. Oto przykład, w którym chcemy wykonać akcję, gdy Test-Path wynosi $false.

 if ( -not ( Test-Path -Path $path ) )

większość operatorów, o których rozmawialiśmy, ma odmianę, w której nie trzeba by używać operatora -not, ale nadal są czasy, w których można go używać.

!,

możesz użyć !jako aliasu dla -not.

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

zobaczysz ! używane bardziej przez osoby pochodzące z innych języków, takich jak C#. Wolę to wpisać, ponieważ trudno mi to zobaczyć, gdy szybko przeglądam moje Skrypty.

-i

można łączyć wyrażenia z operatorem-and. Gdy to zrobisz, obie strony muszą być $true, aby całe wyrażenie było $true.,

 if ( ($age -gt 13) -and ($age -lt 55) )

w tym przykładzie $age musi mieć 13 lub więcej dla lewej strony i mniej niż 55 dla prawej strony. Dodałem dodatkowe nawiasy, aby było to bardziej jasne w tym przykładzie, ale są opcjonalne, o ile wyrażenie jest proste. Oto ten sam przykład bez nich.

 if ( $age -gt 13 -and $age -lt 55 )

ocena odbywa się od lewej do prawej. Jeśli pierwsza pozycja zostanie oceniona na $false, to zakończy się wcześniej i nie wykona właściwego porównania., Jest to przydatne, gdy musisz upewnić się, że wartość istnieje przed jej użyciem. Test-Path na przykład wyrzuci błąd, jeśli podasz mu ścieżkę $null.

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

-lub

-or pozwala określić dwa wyrażenia i zwraca $truejeśli jedno z nich to $true.

 if ( $age -le 13 -or $age -ge 55 )

podobnie jak w przypadku operatora -and, ocena odbywa się od lewej do prawej., Z tym wyjątkiem, że jeśli pierwsza część jest $true , to cała instrukcja jest $true I nie przetworzy reszty wyrażenia.

zanotuj również, jak działa składnia tych operatorów. Potrzebujesz dwóch oddzielnych wyrażeń. Widziałem, że użytkownicy próbują zrobić coś takiego $value -eq 5 -or 6 nie zdając sobie sprawy z ich błędu.

-XOR exclusive lub

ten jest trochę nietypowy. -xor umożliwia ocenę tylko jednego wyrażenia do$true., Więc jeśli oba elementy są $false lub oba elementy są $true, to całe wyrażenie jest $false. Innym sposobem, aby spojrzeć na to jest wyrażenie jest tylko $true, gdy wyniki wyrażenia są różne.

rzadko ktoś używa tego operatora logicznego i nie mogę wymyślić dobrego przykładu, dlaczego miałbym go używać.

operatory bitowe

operatory bitowe wykonują obliczenia na bitach w wartościach i wytwarzają nową wartość jako wynik., Nauczanie operatorów bitowych wykracza poza zakres tego artykułu, ale tutaj znajduje się ich lista.

  • -band binary I
  • -bor binary lub
  • -bxor Binary exclusive lub
  • -bnot Binary not
  • -shl shift left
  • -shr shift right

wyrażenia PowerShell

możemy użyć zwykłego PowerShell ' a wewnątrz instrukcji condition.,

 if ( Test-Path -Path $Path )

Test-Pathzwraca$truelub$falsepodczas wykonywania. Dotyczy to również poleceń zwracających inne wartości.

 if ( Get-Process Notepad* )

zostanie on oceniony na$true jeśli istnieje zwrócony proces i $false jeśli nie ma nic., Można używać wyrażeń potoków lub innych instrukcji PowerShell takich jak:

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

wyrażenia te mogą być łączone ze sobą za pomocą operatorów -and I -or aby użyć nawiasu, aby podzielić je na pod-wyrażenia.

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

sprawdzanie $null

brak wyniku lub $nullwartość oblicza się na $falsew if , Podczas sprawdzania $null najlepszą praktyką jest umieszczenie $null po lewej stronie.

 if ( $null -eq $value )

wartości $null w PowerShell występują całkiem różne niuanse. Jeśli jesteś zainteresowany nurkowaniem głębiej, mam artykuł o wszystkim, co chciałeś wiedzieć o $null.

przypisanie zmiennej

prawie zapomniałem dodać tę, dopóki nie przypomniał mi o tym Prasoon Karunan V.,

zwykle gdy przypisujesz wartość do zmiennej, wartość ta nie jest przekazywana do potoku lub konsoli. Przyporządkowanie zmiennej w wyrażeniu podrzędnym jest przekazywane do potoku.

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

zobacz, jak przypisanie$firstnie ma wyjścia, a przypisanie$secondrobi? Gdy przypisanie zostanie wykonane w instrukcjiif, zostanie wykonane tak samo jak przypisanie$secondpowyżej., Poniżej znajduje się prosty przykład, jak możesz go użyć:

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

Jeśli $process zostanie przypisana wartość, wtedy instrukcja będzie $true a następnie $process zostanie zatrzymany.

upewnij się, że nie pomylisz tego z-eq, ponieważ nie jest to sprawdzanie równości. Jest to bardziej niejasna cecha, że większość ludzi nie zdaje sobie sprawy, że działa w ten sposób.,

alternatywna ścieżka wykonania

polecenieif pozwala określić akcję nie tylko wtedy, gdy poleceniem jest$true, ale także wtedy, gdy poleceniem jest$false. W tym miejscu pojawia się polecenie else.

else

Instrukcjaelse jest zawsze ostatnią częścią instrukcjiif gdy jest używana.

w tym przykładzie sprawdzamy $path, aby upewnić się, że jest to plik. Jeśli znajdziemy plik, przeniesiemy go. Jeśli nie, napiszemy Ostrzeżenie., Ten rodzaj logiki rozgałęzień jest bardzo powszechny.

zagnieżdżone jeśli

if Ielse pobierają blok skryptu, więc możemy umieścić w nich dowolne polecenie PowerShell, w tym inne polecenieif. Pozwala to na wykorzystanie znacznie bardziej skomplikowanej logiki.

w tym przykładzie najpierw testujemy szczęśliwą ścieżkę, a następnie podejmujemy na niej działania. Jeśli to się nie powiedzie, wykonujemy kolejną kontrolę i przekazujemy użytkownikowi bardziej szczegółowe informacje.

elseif

nie ograniczamy się tylko do pojedynczego sprawdzenia warunkowego., Możemy łączyć if I else zamiast zagnieżdżać je za pomocą instrukcji elseif.

wykonanie odbywa się od góry do dołu. Topif jest obliczana jako pierwsza. Jeśli jest to $false, to przechodzi w dół do następnego elseiflubelse na liście. Ta ostatnia else jest domyślną akcją do wykonania, jeśli żadna z pozostałych nie zwróci $true.,

switch

w tym momencie Muszę wspomnieć oswitch. Zapewnia alternatywną składnię do wykonywania wielu porównań z wartością. Za pomocą switch można określić wyrażenie, a wynik zostanie porównany z kilkoma różnymi wartościami. Jeżeli jedna z tych wartości mach, wtedy zostanie wykonany pasujący blok kodu. Spójrz na ten przykład:

 $itemType = 'Role' switch ( $itemType ) { 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' } }

istnieją trzy możliwe wartości, które mogą pasować do $itemType., W tym przypadku będzie on zgodny z Role I is a role zostanie wykonany. Użyłem bardzo prostego przykładu, aby dać ci trochę ekspozycji na operatorswitch. Mówię więcej o wszystkim, co kiedykolwiek chciałeś wiedzieć o oświadczeniu switch w innym artykule.

Pipeline

pipeline jest bardzo wyjątkową i ważną cechą PowerShell. Każda wartość, która nie jest tłumiona lub przypisana do zmiennej, jest umieszczana w potoku., if zapewnia nam sposób na wykorzystanie potoku w sposób, który nie zawsze jest oczywisty.

 $discount = if ( $age -ge 55 ) { Get-SeniorDiscount } elseif ( $age -le 13 ) { Get-ChildDiscount } else { 0.00 }

każdy blok skryptu umieszcza wyniki poleceń lub wartość w potoku. Następnie przypisujemy wynik instrukcji if do zmiennej $discount. Ten przykład mógł równie łatwo przypisać te wartości do zmiennej $discount bezpośrednio w każdym bloku skryptów., Nie mogę powiedzieć, że używam tego często ze stwierdzeniem if, ale mam przykład, w którym ostatnio tego używałem.

tablica inline

mam funkcję o nazwie Invoke-SnowSql, która uruchamia program wykonywalny z kilkoma argumentami linii poleceń. Oto klip z tej funkcji, gdzie buduję tablicę argumentów.

zmienne$Debug I$Path są parametrami funkcji, które są dostarczane przez użytkownika końcowego. Oceniam je inline wewnątrz inicjalizacji mojej tablicy., Jeśli $Debugjest prawdziwe, to wartości te mieszczą się w$snowSqlParam we właściwym miejscu. To samo dotyczy zmiennej $Path.

Uprość złożone operacje

nieuniknione jest napotkanie sytuacji, która ma zbyt wiele porównań do sprawdzenia, a twoje polecenie if przewija się z prawej strony ekranu.

mogą być trudne do odczytania, a to sprawia, że jesteś bardziej podatny na popełnianie błędów. Jest kilka rzeczy, które możemy z tym zrobić.,

kontynuacja linii

w PowerShell są operatory, które pozwalają zawinąć polecenie do następnej linii. Operatory logiczne -and I -or są dobrymi operatorami do użycia, jeśli chcesz podzielić wyrażenie na wiele linii.

jeszcze wiele się tam dzieje, ale umieszczenie każdego elementu na własnej linii robi dużą różnicę. Generalnie robię to tylko wtedy, gdy dostaję więcej niż dwa porównania lub jeśli muszę przewijać w prawo, aby przeczytać którekolwiek z ligic.,

wstępne obliczanie wyników

możemy wyjąć to polecenie z instrukcji if i sprawdzić tylko wynik.

to po prostu wydaje się dużo czystsze niż w poprzednim przykładzie. Masz również możliwość użycia nazwy zmiennej, która wyjaśnia, co tak naprawdę sprawdzasz. Jest to również i przykład samodzielnego dokumentowania kodu, który zapisuje niepotrzebne komentarze.

wiele poleceń if

możemy podzielić je na wiele poleceń i sprawdzać je pojedynczo. W tym przypadku użyjemy flagi lub zmiennej śledzenia, aby połączyć wyniki.,

musiałem odwrócić logikę, aby logika flagi działała poprawnie. Każda ocena jest indywidualnym if oświadczeniem. Zaletą tego jest to, że podczas debugowania możesz dokładnie określić, co robi logika. Udało mi się dodać znacznie lepszą słowność w tym samym czasie.

oczywistym minusem jest to, że jest to o wiele więcej kodu do napisania. Kod jest bardziej skomplikowany, ponieważ zajmuje pojedynczą linię logiki i rozdziela ją na 25 lub więcej linii.

używając funkcji

możemy również przenieść całą logikę walidacji do funkcji., Zobacz, jak czyste to wygląda na pierwszy rzut oka.

 if ( Test-SecureDriveConfiguration -ADUser $user ) { # do something }

nadal musisz utworzyć funkcję, aby wykonać walidację, ale to znacznie ułatwia pracę z tym kodem. Ułatwia to testowanie tego kodu. W swoich testach możesz wyśmiewać wywołanie Test-ADDriveConfiguration I potrzebujesz tylko dwóch testów dla tej funkcji. Jeden, w którym zwraca $true I drugi, w którym zwraca $false. Testowanie drugiej funkcji będzie prostsze, ponieważ jest tak mała.,

ciało tej funkcji może nadal być tym jednowierszowym, od którego zaczęliśmy lub logiką, której użyliśmy w ostatniej sekcji. Działa to dobrze dla obu scenariuszy i pozwala łatwo zmienić tę implementację później.

obsługa błędów

jednym z naprawdę ważnych zastosowań instrukcjiif jest sprawdzenie warunków błędów, zanim pojawią się błędy. Dobrym przykładem jest sprawdzenie, czy folder już istnieje, zanim spróbujesz go utworzyć.,

 if ( -not (Test-Path -Path $folder) ) { New-Item -Type Directory -Path $folder }

Lubię powiedzieć, że jeśli spodziewasz się wystąpienia wyjątku, to tak naprawdę nie jest to wyjątek. Więc sprawdź swoje wartości i zweryfikuj swoje warunki, gdzie możesz.

Jeśli chcesz bardziej zagłębić się w rzeczywistą obsługę wyjątków, mam artykuł na temat wszystkiego, co kiedykolwiek chciałeś wiedzieć o wyjątkach.

Ostatnie słowa

if oświadczenie jest takie proste, ale jest bardzo fundamentalnym elementem PowerShell. Znajdziesz się za pomocą tego wiele razy w prawie każdym skrypcie piszesz., Mam nadzieję, że masz lepsze zrozumienie niż wcześniej.

Share

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *