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
- -eq dla równości
- 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ład
ifInstrukcja:$condition = $true if ( $condition ) { Write-Output "The condition was true" }pierwsza rzecz, jaką
ifinstrukcja jest ewaluacją wyrażenia w nawiasach., Jeśli wartość ta zostanie obliczona na$true, to spowoduje wykonaniescriptblockw 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$trueI wykonałoby polecenieWrite-Outputwewnątrz bloku skryptów.w niektórych językach można umieścić pojedynczy wiersz kodu po instrukcji
ifi zostanie on wykonany., Tak nie jest w PowerShell. Musisz dostarczyć pełnyscriptblockz szelkami, aby działał poprawnie.operatory porównywania
najczęściej używasz instrukcji
ifdo 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
-eqsprawdza 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ść
5I 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-Servicena 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.,
-
-eqrozróżnianie wielkości liter -
-ieqrozróżnianie wielkości liter -
-ceqrozróżnianie wielkości liter
-nie jest równe
wiele operatorów ma powiązanego operatora, który sprawdza przeciwny wynik.
-nesprawdza, 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:
-
-newielkość liter nie jest równa -
-inewielkość liter nie jest równa -
-cnewielkość 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 -leoznacza GreaterThan, GreaterThanOrEqual, LessThan i LessThanOrEqual.,eater than or equal, case sensitive - !,presje
-
-cgewiększe lub równe, case sensitive -
-ltmniej niż -
-iltmniej niż, case sensitive -
-cltmniej niż, rozróżniana wielkość liter -
-lemniej niż lub równe -
-ilemniej lub równe, rozróżniana wielkość liter -
-clemniej 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:
-
-likerozróżnialna wielkość liter -
-ilikerozróżnialna wielkość liter -
-clikerozróżnialna wielkość liter -
-notlikerozróżnialna wielkość liter nie jest dopasowana -
-inotlikerozróżnialna wielkość liter nie jest dopasowana -
-cnotlikerozróżnialna wielkość liter nie jest dopasowana
-dopasuj Wyrażenie regularne
-matchoperator 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
-matchi wielu sposobach użycia regex w innym artykule.,Variations:
-
-matchcase insensitive regex -
-imatchcase insensitive regex -
-cmatchcase sensitive regex -
-notmatchcase insensitive regex not matched -
-inotmatchcase insensitive regex not matched -
-cnotmatchcase sensitive regex not matched
-is of type
You are able to check a value’s type with the
-isoperator.,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:
-
-istypu -
-isnotNie 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 3to 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-nez kolekcją zwróci$truejeśli jakikolwiek element w kolekcji nie pasuje do twojej wartości.PS> 1,2,3 -ne 4 1 2 3może to wyglądać na sprytną sztuczkę, ale mamy operatory
-containsI-inktóre obsługują to bardziej efektywnie i-notcontainspoprawnie zrobi to, czego oczekujesz.-zawiera
operator
-containssprawdzi 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:
-
-containsdopasowanie rozróżniające wielkość liter -
-icontainsdopasowanie rozróżniające wielkość liter -
-ccontainsdopasowanie rozróżniające wielkość liter
-notcontainswielkość liter nie jest dopasowana - -nie
-
-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:
-
-incase insensitive match -
-iincase insensitive match -
-cincase sensitive match -
-notincase insensitive not matched -
-inotincase insensitive not matched -
-cnotincase 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.
-
-bandbinary I -
-borbinary lub -
-bxorBinary exclusive lub -
-bnotBinary not -
-shlshift left -
-shrshift 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.