- 05/23/2020
- 18 minute pentru a citi
-
- j
- x
- t
- D
- s
la fel Ca multe alte limbi, PowerShell a declarațiilor pentru condiționat executarea de cod în yourscripts. Una dintre aceste declarații este declarația If., Astăzi vom face o scufundare profundă într-una dintrecele mai fundamentale comenzi din PowerShell.versiunea originală a acestui articol a apărut pe blogul scris de @KevinMarquette. Echipa ThePowerShell îi mulțumește lui Kevin că ne-a împărtășit acest conținut. Vă rugăm să verificați blogul său atPowerShellExplained.com.
execuție condiționată
scripturile dvs. trebuie adesea să ia decizii și să efectueze o logică diferită pe baza acestor decizii.Asta vreau să spun prin execuție condiționată., Aveți o declarație sau o valoare de evaluat, atunciexecutați o altă secțiune de cod pe baza acestei evaluări. Aceasta este exact ceea ce face declarația if
.
if
Aici este un exemplu de bază if
declarație:
$condition = $trueif ( $condition ){ Write-Output "The condition was true"}
primul lucru Pe care if
declarație nu este evaluează expresia din paranteze. Dacă evaluatesto $true
, atunci se execută scriptblock
în acolade., Dacă valoarea a fost $false
, atunci ar sări peste care scriptblock.
În exemplul anterior, if
declarație a fost doar evaluarea $condition
variabilă. Acesta a fost$true
și-ar fi executat Write-Output
comandă în interiorul scriptblock.
În unele limbi, puteți plasa o singură linie de cod după if
declarație și getsexecuted. Nu este cazul în PowerShell. Trebuie să furnizați un complet scriptblock
cu bretele pentrusă funcționeze corect.,
operatori de comparare
cea mai obișnuită utilizare a instrucțiuniiif
este compararea a două elemente între ele. PowerShell areoperatori speciali pentru diferite scenarii de comparație. Când utilizați un operator de comparație, valoareape partea stângă este comparată cu valoarea din partea dreaptă.
-eq pentru egalitate
-eq
face o verificare a egalității între două valori pentru a se asigura că sunt egale între ele.,
$value = Get-MysteryValueif ( 5 -eq $value ){ # do something}
In acest exemplu, voi lua o valoare cunoscută a 5
și comparând-o cu a mea $value
pentru a vedea dacă theymatch.
un caz de utilizare posibil este să verificați starea unei valori înainte de a lua o acțiune asupra acesteia. Ai putea obține un serviciu și verificați dacă starea a fost difuzate înainte de a sunat Restart-Service
pe ea.
este comună în alte limbi, cum ar fi C# pentru a folosi ==
pentru egalitate (ex: 5 == $value
), dar care nu funcționează cu PowerShell., O altă greșeală obișnuită pe care oamenii o fac este să folosească semnul egal (ex:5 = $value
) care este rezervat pentru atribuirea valorilor variabilelor. Prin plasarea valorii tale cunoscute pe stânga, face ca această greșeală să fie mai ciudată.acest operator (și altele) are câteva variații.,
-
-eq
case-insensitive egalitatea -
-ieq
case-insensitive egalitatea -
-ceq
case-sensitive egalitatea
-ne nu este egal
Mulți operatori au legate de un operator care este de verificare pentru rezultatul opus. -ne
verifică ca valorile nu sunt egale.
if ( 5 -ne $value ){ # do something}
Folositi aceasta pentru a se asigura că acțiunea execută numai dacă valoarea nu este 5
., O bună utilizare-cazuri în carear trebui să verificați dacă un serviciu a fost în stare de funcționare înainte de a încerca să-l porniți.
Variante:
-
-ne
case-insensitive nu este egal -
-ine
case-insensitive nu este egal -
-cne
case-sensitive nu este egal
Acestea sunt inverse variante de -eq
. Voi grupa aceste tipuri împreună atunci când am lista variațiipentru alți operatori.,
– gt-ge-lt-le pentru mai mare sau mai mică decât
acești operatori sunt utilizați atunci când se verifică dacă o valoare este mai mare sau mai mică decât o altă valoare.-gt -ge -lt -le
suport pentru mai mare, GreaterThanOrEqual, mai mică, și LessThanOrEqual.,eater decât sau egale, caz-insensibil
-cge
mai mare sau egal, case-sensitive-lt
mai mult-ilt
mai puțin decât, caz-insensibil-clt
mai puțin decât, case-sensitive-le
mai mic sau egal cu-ile
egală cu sau mai mică, caz-insensibil-cle
mai mic sau egal, case-sensitivenu știu de ce le-ar folosi sensibile și insensibile opțiuni pentru acești operatori.,PowerShell are propria sintaxă de potrivire a modelului bazat pe wildcard și o puteți utiliza cu operatorul -like
. Aceste modele wildcard sunt destul de bază.
-
?
se potrivește cu orice caracter unic -
*
se potrivește cu orice număr de caractere
$value = 'S-ATX-SQL01'if ( $value -like 'S-*-SQL??'){ # do something}
este important să subliniem că modelul se potrivește întregul șir. Dacă trebuie să potrivițiceva în mijlocul șirului, trebuie să plasați *
la ambele capete ale șirului.,e”>
Variante:
-
-like
case-insensitive wildcard -
-ilike
case-insensitive wildcard -
-clike
case-sensitive wildcard -
-notlike
case-insensitive wildcard nu se potrivesc -
-inotlike
case-insensitive wildcard nu se potrivesc -
-cnotlike
case-sensitive wildcard nu se potrivesc
-meci expresie regulată
-match
operator vă permite să verificați un șir de-exprimare-pe baza de meci., Utilizați thiswhen modelele wildcard nu sunt suficient de flexibile pentru tine.
$value = 'S-ATX-SQL01'if ( $value -match 'S-\w\w\w-SQL\d\d'){ # do something}
un model regex se potrivește oriunde în șir în mod implicit. Deci, puteți specifica o substring carevrei să se potrivească astfel:
$value = 'S-ATX-SQL01'if ( $value -match 'SQL'){ # do something}
Regex este un limbaj complex propriu și merită privit. Vorbesc mai multe despre -match
șimulte moduri de a utiliza regex într-un alt articol.,
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}
puteți utiliza acest lucru dacă lucrați cu clase sau acceptați diverse obiecte peste conductă. Youcould avea fie un serviciu sau un nume de serviciu ca intrare. Apoi verificați dacă aveți un serviciuși preluați serviciul dacă aveți doar numele.,
if ( $Service -isnot ){ $Service = Get-Service -Name $Service}
Variante:
-
-is
de tip -
-isnot
nu de tip
de Colectare operatorii
atunci Când utilizați operatori cu o singură valoare, rezultatul este $true
sau $false
. Acest lucru estemanipulat ușor diferit atunci când lucrați cu o colecție. Fiecare element din colecție devine evaluat și operatorul returnează fiecare valoare care se evaluează la $true
.,
PS> 1,2,3,4 -eq 33
Acest lucru încă funcționează corect într-oif
declarație. Deci, o valoare este returnată de operatorul dvs., atunciîntreaga declarație este $true
.
$array = 1..6if ( $array -gt 3 ){ # do something}
există o mică capcană ascunsă în detaliile de aici pe care trebuie să le subliniez. Când utilizați operatorul -ne
în acest fel, este ușor să priviți greșit logica înapoi. Folosind -ne
cu acollection se întoarce $true
dacă orice element din colecție nu se potrivește cu valoarea ta.,
PS> 1,2,3 -ne 4123
Acest lucru poate arata ca un truc inteligent, dar trebuie operatorii -contains
și -in
care se ocupa de acest moreefficiently. Și -notcontains
face ceea ce vă așteptați.
– conține
operatorul-contains
verifică colecția pentru valoarea dvs. De îndată ce găsește o potrivire, se întoarce $true
.
$array = 1..6if ( $array -contains 3 ){ # do something}
acesta este modul preferat de a vedea dacă o colecție conține valoarea ta., Folosind Where-Object
(sau-eq
) plimbări întreaga listă de fiecare dată și este semnificativ mai lent.,
Variante:
-
-contains
case-insensitive meci -
-icontains
case-insensitive meci -
-ccontains
case-sensitive meci -
-notcontains
case-insensitive nu se potrivesc -
-inotcontains
case-insensitive nu se potrivesc -
-cnotcontains
case-sensitive nu se potrivesc
în
-in
operator este la fel ca -contains
operator, cu excepția colecției este pe partea dreaptă.,
$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.,
-nu.
-not
operator răstoarnă o expresie de $false
și $true
sau $true
și $false
. Iată un exemplu în care dorim să efectuăm o acțiune când Test-Path
este $false
.
if ( -not ( Test-Path -Path $path ) )
majoritatea operatorilor despre care am vorbit au o variație în care nu este necesar să utilizați operatorul -not
. Dar există încă ori este util.
!, operatorul
puteți utiliza !
ca alias pentru -not
.
if ( -not $value ){}if ( !$value ){}
puteți vedea !
folosit de mai multe persoane care provin din alte limbi, cum ar fi C#. Prefer să tastez itout pentru că mi se pare greu să văd când mă uit repede la scripturile Mele.
– și
puteți combina expresii cu operatorul -and
. Când faci asta, ambele părți trebuie să fie$true
pentru întreaga expresie să fie $true
.,
if ( ($age -gt 13) -and ($age -lt 55) )
În acest exemplu, $age
trebuie să fie 13 ani sau mai în vârstă pentru partea stângă și mai puțin de 55 de ani pentru partea dreapta. Iadded paranteze suplimentare pentru a face mai clar în acest exemplu, dar ele sunt opționale, atâta timp cât theexpression este simplu. Iată același exemplu fără ele.
if ( $age -gt 13 -and $age -lt 55 )
evaluarea se întâmplă de la stânga la dreapta. Dacă primul element se evaluează la $false
, acesta iese din timp și nu efectuează comparația corectă. Acest lucru este util atunci când trebuie să vă asigurați că există o valoare înainte de ao folosi., De exemplu, Test-Path
aruncă o eroare dacă îi dați o cale $null
.
if ( $null -ne $path -and (Test-Path -Path $path) )
sau
-or
vă permite să specificați două expresii și returnează $true
dacă unul dintre ele este$true
.
if ( $age -le 13 -or $age -ge 55 )
la fel ca și cu -and
operator, evaluarea se întâmplă de la stânga la dreapta., Cu excepția că, dacă prima parte este $true
, atunci întreaga declarație este $true
și nu procesul de restul theexpression.de asemenea, notați cum funcționează sintaxa pentru acești operatori. Aveți nevoie de două expresii separate. Am văzut utilizatorii să încerce să facă ceva de genul $value -eq 5 -or 6
fără să-și dea seama de greșeala lor.
– xsau exclusiv sau
acesta este puțin neobișnuit. -xor
permite o singură expresie pentru a evalua la $true
., Deci, dacă bothitems sunt $false
sau ambele elemente sunt $true
, atunci intreaga expresie este $false
. O altă modalitate de a privi acest lucru este expresia este doar $true
atunci când rezultatele expresiei sunt diferite.
este rar ca cineva să folosească vreodată acest operator logic și nu mă pot gândi la un exemplu bun ca towhy l-aș folosi vreodată.
operatorii Bitwise
operatorii Bitwise efectuează calcule pe biții din cadrul valorilor și produc o nouă valoare ca urmare., Predarea operatorilor bitwise este dincolo de domeniul de aplicare al acestui articol, dar aici este lista thethem.
-
-band
binar ȘI -
-bor
binar SAU -
-bxor
binar SAU exclusiv -
-bnot
binar NU -
-shl
schimb -
-shr
shift dreapta
PowerShell expresii
putem folosi normal PowerShell în stare de declarație.,
if ( Test-Path -Path $Path )
Test-Path
livrare $true
sau $false
când se execută. Acest lucru se aplică și comenzilor care se întoarcalte valori.
if ( Get-Process Notepad* )
Se evaluează la $true
dacă există o revenit proces și $false
dacă nu iese totul., Se’sperfectly valabil pentru a utiliza conducte expresii sau alte PowerShell afirmații de genul asta:
if ( Get-Process | Where Name -eq Notepad )
Aceste expresii pot fi combinate cu fiecare alte cu -and
și -or
operatori, dar ne-ați pentru a utiliza paranteze pentru a le sparge în subexpressions.
if ( (Get-Process) -and (Get-Service) )
Verificare pentru $nul
Având o nici un rezultat sau un $null
valoare se evaluează la $false
în if
declarație., Când checkingspecifically pentru $null
, este o bună practică pentru a plasa $null
pe partea stângă.
if ( $null -eq $value )
Există destul de câteva nuanțe atunci când se ocupă cu $null
valori în PowerShell. Dacă sunteți interesat să vă scufundați mai adânc, am un articol despre tot ce ați vrut să știți despre $null.
Variabilei
aproape că am uitat să adăugați asta până Prasoon Karunan V mi-a amintit de ea.,
if ($process=Get-Process notepad -ErrorAction ignore) {$process} else {$false}
în mod Normal, atunci când se atribuie o valoare unei variabile, valoarea nu este trecut pe conducta orconsole. Când faci o atribuire variabilă într-o expresie sub, Se trece pe la thepipeline.
PS> $first = 1PS> ($second = 2)2
Vezi cum $first
misiune nu are nici o ieșire și $second
misiune nu? Atunci când un assignmentis făcut într-un if
declarație, se execută la fel ca $second
atribuirea de mai sus., Aici este un cleanexample pe cum ai putea folosi:
if ( $process = Get-Process Notepad* ){ $process | Stop-Process}
Dacă $process
se atribuie o valoare, atunci afirmatia este $true
și $process
este oprit.
asigurați-vă că nu confundați acest lucru cu -eq
deoarece aceasta nu este o verificare a egalității. Aceasta este o caracteristică moreobscure pe care majoritatea oamenilor nu-și dau seama că funcționează în acest fel.,
Supleant cale de execuție
if
declarație vă permite să specificați o acțiune pentru care nu numai atunci când declarația este $true
, darde asemenea, pentru atunci când e $false
. Aici intră în joc declarația else
.
mai mult
else
declarație este întotdeauna ultima parte a if
declarație atunci când este utilizat.
în acest exemplu, verificăm $path
pentru a ne asigura că este un fișier. Dacă găsim fișierul, îl mutăm. Dacă nu, scriem un avertisment., Acest tip de logică de ramificare este foarte frecventă.
Imbricate dacă
if
și else
declarații ia un bloc de script-ul, astfel încât să putem plasa orice comanda PowerShell insidethem, inclusiv un alt if
declarație. Acest lucru vă permite să utilizați o logică mult mai complicată.
în acest exemplu, testăm mai întâi calea fericită și apoi luăm măsuri în acest sens. În cazul în care nu reușește, vom faceo altă verificare și pentru a oferi informații mai detaliate pentru utilizator.
elseif
Nu ne limităm la o singură verificare condiționată., Putem lanț if
și else
statementstogether în loc de cuibărit-le cu ajutorul elseif
declarație.
execuția se întâmplă de sus în jos. Declarația de sus if
este evaluată mai întâi. Dacă e $false
, apoi se mută în jos la următoarea elseif
sau else
în listă. Ultima else
este thedefault măsuri să ia dacă nici unul dintre ceilalți reveni $true
.,
comutator
în acest moment, trebuie să menționez instrucțiunea switch
. Acesta oferă o sintaxă alternativă pentru a facecomparații multiple cu o valoare. Cu switch
, puteți specifica o expresie și ca urmare getscompared cu mai multe valori diferite. Dacă una dintre aceste valori se potrivește, blocul de cod de potrivire esteexecutat. Uită-te la acest exemplu:
$itemType = 'Role'switch ( $itemType ){ 'Component' { 'is a component' } 'Role' { 'is a role' } 'Location' { 'is a location' }}
Există trei valori posibile care se potrivesc $itemType
. În acest caz, se potrivește cu Role
., Am folosit un exemplu simplu doar pentru a vă oferi o anumită expunere la operatorul switch
. Vorbesc mai mult despre tot ce ai vrut vreodată să știi despre declarația switch într-un alt articol.
conductă
conducta este o caracteristică unică și importantă a PowerShell. Orice valoare care nu este suprimată sau atribuită unei variabile este plasată în conductă. if
ne oferă o modalitate de a profita de conductă într-un mod care nu este întotdeauna evident.,
$discount = if ( $age -ge 55 ){ Get-SeniorDiscount}elseif ( $age -le 13 ){ Get-ChildDiscount}else{ 0.00}
fiecare bloc de script este plasarea rezultatelor comenzile sau valoarea în conducta. Apoi atribuim rezultatul declarației if
la variabila $discount
. Ca exemplu ar putea fi doar ca easilyassigned aceste valori $discount
variabile direct în fiecare scriptblock. Nu pot spune că Iuse asta cu if
declarație de multe ori, dar am un exemplu în care am folosit recent acest lucru.,
Array inline
am o funcție numită Invoca-SnowSql care lansează un executabil cu mai multe comandă-linearguments. Aici este un clip de la acea funcție în cazul în care am construi matrice de argumente.
variabilele$Debug
și$Path
sunt parametrii funcției furnizate de utilizatorul final.Le evaluez în linie în interiorul inițializării matricei mele. Dacă $Debug
este adevărat, atunci cei valuesfall în $snowSqlParam
în locul corect. Același lucru este valabil și pentru variabila $Path
.,
Simplifica operațiunile complexe
este inevitabil ca tu a alerga într-o situație care are prea multe comparații pentru a verifica și dvs.If
declarație suluri de drum de pe partea dreaptă a ecranului.ele pot fi greu de citit și care te fac mai predispus la greșeli. Sunt câteva lucruri pe care le putem face în legătură cu asta.
continuarea liniei
există unii operatori din PowerShell care vă permit să vă înfășurați comanda la linia următoare., La logicaloperators -and
și -or
sunt operatorii de bun pentru a utiliza în cazul în care doriți să rupă expresie intomultiple linii.
încă se întâmplă multe acolo, dar plasarea fiecărei piese pe propria linie face o mare diferență.În general, folosesc acest lucru atunci când primesc mai mult de două comparații sau dacă trebuie să derulez spre dreaptacitiți oricare dintre logici.
Pre-calcularea rezultatelor
putem lua această declarație din declarația if
și verificați numai rezultatul.acest lucru se simte mult mai curat decât exemplul anterior., De asemenea, vi se oferă posibilitatea de a utiliza numele avariable care explică ceea ce este că sunteți într-adevăr de verificare. Acesta este, de asemenea, un exemplu decodul de auto-documentare care salvează comentarii inutile.
multiple if declarații
putem rupe acest lucru în mai multe declarații și să le verifice la un moment dat. În acest caz, folosim aflag sau o variabilă de urmărire pentru a combina rezultatele.
a trebuit să inversez logica pentru ca logica steagului să funcționeze corect. Fiecare evaluare este anindividualif
declarație., Avantajul acestui lucru este că atunci când depanați, puteți tellexact ceea ce face logica. Am reușit să adaug o verbozitate mult mai bună în același timp.dezavantajul evident este că este mult mai mult cod pentru a scrie. Codul este mai complex de privitdeoarece este nevoie de o singură linie de logică și o explodează în 25 sau mai multe linii.
folosind funcții
putem muta, de asemenea, toată logica de validare într-o funcție. Uită-te la cât de curat arată acest lucru la aglance.,
if ( Test-SecureDriveConfiguration -ADUser $user ){ # do something}
încă mai trebuie să creați funcția pentru a face validarea, dar face acest cod mult mai ușorlucrează cu. Face acest cod mai ușor de testat. În testele dvs., puteți batjocori apelul laTest-ADDriveConfiguration
și aveți nevoie doar de două teste pentru această funcție. Unul în care returnează$true
și unul în care returnează $false
. Testarea celeilalte funcții este mai simplă pentru că esteatât de mic.
corpul acelei funcții ar putea fi în continuare acea linie cu care am început sau logica explodată pe care am folosit-o în ultima secțiune., Acest lucru funcționează bine pentru ambele scenarii și vă permite să schimbați cu ușurință acest lucruimplementarea ulterioară.
Eroare de manipulare
O utilizare importantă a if
declarație este de a verifica pentru condiții de eroare înainte de a alerga intoerrors. Un bun exemplu este să verificați dacă există deja un folder înainte de a încerca să îl creați.
if ( -not (Test-Path -Path $folder) ){ New-Item -Type Directory -Path $folder}
îmi place să spun că dacă vă așteptați să se întâmple o excepție, atunci nu este chiar o excepție. Așa că verificați-vă valorile și validați-vă Condițiile unde puteți.,
dacă doriți să se scufunde un pic mai mult în manipularea reală excepție, am un articol petot ce ai vrut vreodată să știi despre excepții.
cuvinte finale
declarațiaif
este o declarație atât de simplă, dar este o piesă fundamentală a PowerShell. Vă veți găsi folosind acest lucru de mai multe ori în aproape fiecare script pe care îl scrieți. Sper că ai o înțelegere mai bună decât înainte.