Adam the Automator

author
15 minutes, 58 seconds Read

Când scrieți un script PowerShell fără funcții și fără dependențe externe față de alte scripturi, conceptul de domenii PowerShell nu reprezintă o preocupare prea mare. Conceptul de variabile globale PowerShell nu este în față și în centrul atenției. Dar pe măsură ce începeți să construiți funcții, module și învățați să apelați scripturi din alte scripturi, subiectul devine mai important.

În acest articol, veți primi o lecție aprofundată despre ce sunt domeniile de cuprindere în PowerShell, cum funcționează și cum puteți scrie cod ținând cont de domeniile de cuprindere. Până când veți termina, veți înțelege variabilele globale din PowerShell și multe altele!

Tabel de materii

Scopuri: Kinda Like Buckets

Ați scris vreodată un script în care ați definit o variabilă și când verificați valoarea acelei variabile, aceasta este altceva? S-ar putea să vă zgâriați la cap cum s-a schimbat acea variabilă atunci când ați definit-o clar. Un motiv ar putea fi faptul că valoarea variabilei este suprascrisă într-un alt domeniu de aplicare.

Poate că v-ați întrebat cum de anumite variabile PowerShell au valori atunci când le referiți în consolă, dar nu există în scripturile dvs. Sunt șanse ca acele variabile să se afle într-un alt „bucket” care nu este disponibil în acel moment.

Scoapele sunt ca niște bucket-uri. Scopurile afectează modul în care PowerShell izolează variabilele, aliasurile, funcțiile și PSD-urile între diferite zone. Un scope este ca o găleată. Este un loc în care se colectează toate aceste elemente împreună.

Când PowerShell pornește, creează automat aceste „găleți” pentru dumneavoastră. În acel moment, folosiți deja domenii de cuprindere fără să vă dați seama. Toate domeniile de cuprindere sunt definite de PowerShell și sunt create fără niciun ajutor din partea dumneavoastră.

Tipuri de domenii de cuprindere

Când PowerShell pornește, creează automat patru „găleți” sau domenii de cuprindere pentru ca diverse elemente să fie plasate în ele. Nu puteți crea domenii de cuprindere pe cont propriu. Puteți doar să adăugați și să eliminați elemente din aceste domenii de cuprindere definite mai jos.

Domeniul de cuprindere global

Elementele definite la deschiderea PowerShell sunt setate la nivelul domeniului de cuprindere global. Aceste elemente includ obiecte create de sistem, cum ar fi unitățile PowerShell și, de asemenea, tot ceea ce ați definit într-un profil PowerShell, deoarece profilul dvs. se execută la pornire.

Elementele din sfera globală sunt disponibile peste tot. Puteți face referire la elementele din sfera globală în mod interactiv pe consolă, în orice script pe care îl executați și în orice funcție. Variabilele globale din PowerShell sunt peste tot. Din acest motiv, utilizarea obișnuită a variabilelor globale PowerShell constă în utilizarea variabilelor globale PowerShell între scripturi.

Există un singur domeniu global care guvernează global.

Domeniul de cuprindere a scripturilor

Un domeniu de cuprindere a scripturilor este creat automat de fiecare dată când se execută un script PowerShell. Puteți avea mai multe instanțe diferite de script scope. Script scope-urile sunt create atunci când executați un script PS1 sau un modul, de exemplu.

Doar elementele create în acea instanță specială de script scope se pot referi unele la altele.

Private Scope

În mod normal, un element definit poate fi accesat din alte scope-uri – ceea ce nu este adevărat în cazul elementelor dintr-un scope privat. Elementele dintr-un domeniu de aplicare privat, conțin obiecte care sunt ascunse pentru alte domenii de aplicare. Un domeniu privat este utilizat pentru a crea elemente cu același nume ca și elementele din alte domenii pentru a preveni suprapunerea.

Domeniul local

În comparație cu celelalte domenii, domeniul local este puțin diferit. Domeniul local este un pointer către domeniul global, script sau privat. Domeniul local este relativ la orice context în care se execută codul în acel moment.

Dacă creați o variabilă, un alias, o funcție sau un PSDrive fără să-i atribuiți în mod explicit un domeniu de aplicare (pe care îl vom aborda mai târziu), aceasta va intra în domeniul local.

Referință la domenii de cuprindere

Acum că aveți o idee despre cele patru tipuri de domenii de cuprindere care există, ar trebui să știți, de asemenea, că există două moduri de a face referință la aceste domenii de cuprindere.

În PowerShell, există două moduri de a face referință la domenii de cuprindere – numite sau numerotate. Ambele metode fac referire la aceleași domenii de cuprindere, dar pur și simplu într-un mod diferit. Acestea sunt două moduri diferite de a interacționa cu domeniile de cuprindere.

Domenii de cuprindere numite

Mai sus, în secțiunea Scope Type, ați învățat despre domeniile de cuprindere la care se face referire prin nume. Referirea unui domeniu de aplicare prin nume se numește, intuitiv, un domeniu de aplicare numit. Scopul principal al referirii unui domeniu de aplicare prin nume este acela de a atribui un element unui domeniu de aplicare. Veți învăța cum să faceți acest lucru mai jos.

Scope-uri numerotate

Pe lângă un nume, fiecare scope are un număr care începe de la zero și care va fi întotdeauna scope-ul local. Scopurile sunt numerotate dinamic în raport cu domeniul local curent.

De exemplu, de îndată ce deschideți o sesiune PowerShell, operați în domeniul global. În acest moment, domeniul global este domeniul local (rețineți că domeniul local este doar un pointer).

Din moment ce domeniul local este întotdeauna domeniul zero, în acest moment, domeniul global este, de asemenea, în prezent domeniul zero. Dar, atunci când executați un script din aceeași sesiune, este creat un domeniu de cuprindere al scriptului. În timpul rulării, pointerul domeniului de aplicare local s-a schimbat atunci în domeniul de aplicare al scriptului. Acum, domeniul de script este domeniul zero, iar domeniul global este domeniul unu.

Scopurile sunt numerotate Acest proces se repetă pentru atâtea domenii cât aveți în care domeniul local este 0. Domeniile sunt numerotate în mod dinamic prin ierarhia domeniilor.

Ierarhia și moștenirea domeniului de aplicare

După cum am menționat mai devreme, atunci când lansați o sesiune PowerShell, PowerShell creează unele elemente pentru dumneavoastră în domeniul de aplicare global. Aceste elemente pot fi funcții, variabile, alias-uri sau PSDrive. Orice lucru pe care îl definiți în sesiunea PowerShell va fi definit și în domeniul global.

Din moment ce vă aflați în domeniul global în mod implicit, dacă faceți ceva care creează un alt domeniu, cum ar fi executarea unui script sau rularea unei funcții, se va crea un domeniu copil, părintele fiind domeniul global. Scopurile sunt ca niște procese cu părinți și copii.

Ceea ce este definit într-un domeniu părinte, domeniul global, în acest caz, va fi accesibil în domeniul copil. Dar aceste elemente sunt editabile doar în scope-ul în care au fost definite.

Să spunem că aveți un script numit Test.ps1. În interiorul acestui script se află o singură linie, așa cum se arată mai jos.

$a = 'Hello world!'

Când executați acest script, lui $a i se atribuie o valoare în domeniul local (scriptul în timp ce scriptul rulează). Când se execută Test.ps1, puteți vedea mai jos că nu se poate face referire la acesta după ce scriptul se execută. Deoarece $a a fost atribuită în timp ce se află în domeniul scriptului, domeniul global (la consola interactivă) nu o poate vedea.

Domeniul global nu poate vedea variabila

Să luăm acest exemplu cu un pas mai departe și să facem ca scriptul Test.ps1 să arate ca mai jos. Scriptul încearcă acum să scoată valoarea lui $a înainte de a o seta în același domeniu de aplicare.

Write-Output $a$a = 'Hello world!'

Pentru a demonstra, atribuiți o valoare lui $a la consola interactivă. Acest lucru atribuie valoarea în domeniul global. Acum, scriptul se execută, va moșteni domeniul părinte (global) și ar trebui să poată vedea valoarea.

Vezi mai jos că atunci când Test.ps1 este executat (creând un domeniu copil al domeniului global), acesta poate vedea valoarea $a. Puteți vedea, de asemenea, că valoarea variabilei este disponibilă și în domeniul global, deoarece acest domeniu este cel în care a fost setată. Aceasta înseamnă că $a este disponibilă atât în scope-ul script (child), cât și în scope-ul părinte (global).

Variabila este disponibilă în scope-urile script și global

Rețineți acest comportament de moștenire a scope-urilor. Făcând acest lucru vă va ajuta la depanarea ocaziilor de depanare vor apărea conflicte de variabile, cum ar fi variabile în domenii de cuprindere diferite cu același nume.

Definirea și accesarea elementelor din domenii de cuprindere

Acum că știți ce este un domeniu de cuprindere și cum funcționează, cum îl accesați? Să vedem cum să folosim PowerShell pentru a defini un domeniu de aplicare a variabilelor (și să le accesăm).

Get/Set-Variable

În PowerShell, există două cmdlet-uri care vă permit să definiți variabile numite Get-Variable și Set-Variable. Aceste cmdlet-uri vă permit să preluați valoarea unei variabile sau să definiți o valoare.

Ambele cmdlet-uri sunt similare cu un parametru Name și Scope. Utilizând acești parametri, PowerShell vă permite să definiți și să recuperați valorile variabilelor în toate sferele.

Sfere locale

Pentru a defini o variabilă într-o sferă locală, utilizați Set-Variable și furnizați-i un nume de variabilă locală și o valoare, așa cum se arată mai jos.

PS> Set-Variable -Name a -Value 'foo'

Sfera locală este întotdeauna cea implicită, astfel încât neutilizarea parametrului Scope va defini întotdeauna variabila în sfera locală.

Pentru a prelua valoarea unei variabile cu domeniu local, utilizați Get-Variable furnizându-i numele.

PS> Get-Variable -Name aName Value---- -----a foo

Domenii private/script/globale

Vă veți utiliza aceiași parametri (Name și Value) și atunci când lucrați cu variabile private, script și globale. Singura diferență este că de data aceasta veți folosi parametrul Scope pentru a defini explicit domeniul de aplicare.

Metodele de setare a unei variabile private, de script sau cu domeniu de aplicare global sunt aceleași. Pur și simplu înlocuiți valoarea transmisă la parametrul Scope ca Private, Script Global.

PS> Set-Variable -Name a -Value 'foo' -Scope <Private|Script|Global>

Pentru a prelua valoarea unei variabile de script sau global-scoped, utilizați Get-Variable furnizându-i numele și domeniul de aplicare.

PS> Get-Variable -Name a -Scope <Script|Global>Name Value---- -----a foo

Rețineți: Puteți, de asemenea, să faceți referire la domenii de cuprindere utilizând numere de domenii de cuprindere în loc de nume cu cmdleturile Get/Set-Variable.

Domeniul de cuprindere „Prefacere”

De asemenea, puteți prelua și seta variabile în domenii de cuprindere utilizând o scurtătură. În loc să utilizați cmdlets PowerShell, veți prefața domeniul de aplicare la variabilă atunci când faceți referire la aceasta.

Domenii locale

Din moment ce domeniul local este întotdeauna implicit, prin simpla definire a unei variabile și referențiere se va seta și se va prelua o variabilă din domeniul local

PS> $a = 'foo'PS> $afoo

Domenii private/script/globale

Dacă doriți să definiți și să faceți referire la domenii de script sau globale, puteți prefața variabilele cu numele domeniului și un punct și virgulă.

De exemplu, pentru a seta variabila $a în domeniul global, puteți prefața a cu $global:.

$global:a = 'foo'

Același lucru se poate face și pentru o variabilă cu domeniu de cuprindere script.

$script:a = 'foo'

După ce variabilele sunt setate în domeniul preferat, le veți referi în același mod. De asemenea, observați că puteți exclude prefața domeniului de aplicare dacă domeniul de aplicare definit este domeniul de aplicare local.

PS> $global:a = 'foo'PS> $global:afooPS> $afoo

Domenii de aplicare în blocurile de script

PowerShell are o construcție la îndemână numită blocuri de script. Scriptblock-urile vă permit să deplasați fragmente de cod și să le executați cam oriunde.

Ca un script PS1, scriptblock-urile se execută în propriul lor domeniu de script. Atunci când executați un scriptblock, executați în esență un script PS1.

Observați în exemplul de mai jos unde o variabilă este definită în domeniul global și apoi se încearcă să se suprascrie într-un domeniu de script. După cum ați învățat mai sus, acest lucru nu va funcționa deoarece un domeniu copil nu poate face referire la un domeniu părinte.

Un domeniu copil nu poate suprascrie un domeniu părinte

Acest exemplu arată că atunci când $a este modificată în scriptblock, definiția variabilei globale pentru $a nu este modificată deoarece scriptblock este un domeniu copil de script.

Scripturi Dot Sourcing (Schimbarea domeniilor locale)

PowerShell are un concept numit dot-sourcing. Aceasta este o metodă care vă permite să executați un script PS1 și să aduceți, în schimb, tot ceea ce ar trebui să fie script-scopulat în domeniul local.

Prin punerea unui punct (.) înainte de a face referire la un script PS1 și de a-l executa, acest „dot-sourcing” „sursă de puncte” a conținutului scriptului și aduce totul în domeniul local.

Pentru a demonstra, am din nou un script Test.ps1 care definește o variabilă așa cum se arată mai jos.

$a = 'Hello world!'

Într-o consolă PowerShell, setați o valoare pentru o variabilă $a, apoi puneți un punct sursă pentru acest script așa cum se arată mai jos. Observați că variabila originală a fost suprascrisă. PowerShell a „fuzionat” cele două domenii de cuprindere locale împreună.

Variabila originală a fost suprascrisă

Utilizarea proprietății AllScope (opțiune)

Ați văzut cum să interacționați cu elemente din domenii de cuprindere specifice, dar până acum fiecare element este încă definit într-un singur domeniu de cuprindere. Dar ce se întâmplă dacă nu știți în ce domeniu de cuprindere este definită o variabilă?

Când definiți o variabilă cu cmdlet-ul Set-Variable, puteți plasa variabila în toate domeniile de cuprindere deodată. Pentru a face acest lucru, utilizați valoarea AllScope pentru parametrul Option.

Pentru a demonstra, scriptul Test.ps1 a fost modificat pentru a defini o variabilă a în toate sferele. Această variabilă este apoi emisă după cum se arată mai jos.

Set-Variable -Name a -Value 'Hello world!' -Option AllScopeWrite-Output $a

Puteți vedea apoi mai jos că se stabilește o valoare pentru $a în domeniul global și că scriptul Test.ps1 este executat. Cu toate acestea, în loc să nu aibă niciun efect, valoarea lui $a a fost suprascrisă. Nu numai că a fost definită în domeniul scriptului (Write-Output $a), dar a fost suprascrisă și în domeniul global.

Variabilă suprascrisă în domeniul global

Opțiunea AllScope este la îndemână, dar aveți grijă. Această opțiune elimină, în esență, conceptul de domenii de cuprindere și fuzionează totul la un loc.

Domeniile funcțiilor

Când executați o funcție, tot codul din cadrul acelei funcții se află în propriul său domeniu copil. Scopurile funcțiilor urmează același comportament copil/părinte ca și celelalte scopes.

Având scopes separate pentru fiecare funcție este o idee bună. Permite un control mai bun asupra elementelor, nefiind nevoie să ne facem griji cu privire la elementele care intră în conflict, De asemenea, oferă avantajul suplimentar al curățării automate a variabilelor dintr-o funcție. De îndată ce funcția se finalizează, toate elementele definite în funcție vor fi șterse.

Pentru a demonstra, copiați/lipiți funcția de mai jos direct în consola PowerShell.

Function Do-Thing { $var = 'bar'}

După ce a fost lipită, executați funcția. Observați că nu puteți accesa variabila $var în afara funcției.

PS> Do-ThingPS> $var

Păstrarea elementelor private (dezactivarea moștenirii)

În mod normal, dacă o variabilă este definită într-un domeniu părinte, acea variabilă va fi definită în domeniul copil. Dar poate că ați dori să utilizați un nume de variabilă, dar acel nume de variabilă a fost deja definit într-unul dintre domeniile de aplicare care urmează să fie executat într-o sesiune. În acest caz, puteți fie să alegeți un alt nume de variabilă, fie să definiți variabila într-un domeniu privat, transformând-o într-o variabilă privată.

O modalitate de a utiliza domeniile de aplicare pentru a reduce conflictele este utilizarea domeniului privat. Utilizarea domeniului privat dezactivează moștenirea pe acea variabilă specifică. Atunci când sunt create mai multe domenii copil, acele domenii copil nu vor vedea nicio variabilă definită într-un domeniu privat.

Un script Test.ps1 emite valoarea lui $a, așa cum se arată mai jos.

Write-Output $a

Vezi mai jos că definesc o variabilă cu domeniu privat în domeniul global și apoi execut scriptul Test.ps1. De obicei, atunci când definiți o variabilă într-un domeniu părinte, acea variabilă va fi disponibilă în domeniul copil – nu și în cazul unei variabile cu domeniu privat.

În exemplul de mai jos, puteți vedea că domeniul copil al scriptului creat prin executarea scriptului Test.ps1 nu a putut vedea variabila $a cu scuptură privată definită în domeniul părinte.

Scopul de script nu poate vedea variabila cu acoperire privată

În comparație cu sferele globale sau cu opțiunea AllScope din cmdlet Set-Variable, variabilele cu acoperire privată sunt o modalitate excelentă de compartimentare a elementelor.

Cele mai bune practici de definire a domeniului de cuprindere

Credința că definirea variabilelor în domeniul global sau utilizarea opțiunii AllScope este calea de urmat este comună. La urma urmei, toate variabilele sunt disponibile peste tot. Nu este nevoie să vă faceți griji cu privire la complicațiile de domenii de cuprindere. Deși acest lucru oferă o libertate suplimentară pentru accesul la ceea ce este definit, poate scăpa rapid de sub control și poate deveni dificil de depanat.

În loc să încercați să împiedicați utilizarea domeniilor de cuprindere, urmați aceste sfaturi:

  1. În loc să specificați domenii de cuprindere în funcții, utilizați parametrii pentru a transmite informațiile necesare funcției.
  2. Rămâneți în domeniul de cuprindere local pe cât de mult posibil.
  3. În loc să definiți variabile globale dintr-un script, utilizați cmdlet-ul Write-Output pentru a scoate totul și a salva într-o variabilă atunci când este necesar din consolă.

Principalul punct aici este să acceptați domeniile de cuprindere și să învățați să le folosiți în avantajul dumneavoastră în loc să încercați să le ocoliți.

Lecturi suplimentare

  • Despre funcțiile avansate și parametrii funcțiilor
  • Utilizarea variabilelor de mediu în PowerShell

.

Similar Posts

Lasă un răspuns

Adresa ta de email nu va fi publicată.