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
if
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 wykonaniescriptblock
w nawiasach klamrowych. Jeśli wartość wynosi$false
, to pomija ten blok skryptów.w poprzednim przykładzie, polecenie
if
oceniał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łnyscriptblock
z szelkami, aby działał poprawnie.operatory porównywania
najczęściej używasz instrukcji
if
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 - !,presje
-
-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
$true
lub$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
-contains
I-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
-notcontains
wielkość liter nie jest dopasowana - -nie
-
-inotcontains
wielkość liter nie jest dopasowana -
-cnotcontains
wielkość liter nie jest dopasowana
-w
-in
operator jest taki sam jak operator-contains
z 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 $true
jeś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-Path
zwraca$true
lub$false
podczas 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 $null
wartość oblicza się na $false
w 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$first
nie ma wyjścia, a przypisanie$second
robi? Gdy przypisanie zostanie wykonane w instrukcjiif
, zostanie wykonane tak samo jak przypisanie$second
powyż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 elseif
lubelse
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 $Debug
jest 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.