Hvordan Scopes påvirker PowerShell Scripts

Innholdsfortegnelse:

Hvordan Scopes påvirker PowerShell Scripts
Hvordan Scopes påvirker PowerShell Scripts

Video: Hvordan Scopes påvirker PowerShell Scripts

Video: Hvordan Scopes påvirker PowerShell Scripts
Video: Upgraded URLs Hangout on Air - YouTube 2024, April
Anonim
I batchskript har endringer i miljøvariabler som standard en global innvirkning på gjeldende sesjon. For PowerShell er det nøyaktige motsatt sant fordi rekkevidde brukes til å isolere et skripts modifikasjoner. Her vil vi undersøke hvordan omfangene påvirker PowerShell-skript og hvordan de skal fungere i og rundt dem.
I batchskript har endringer i miljøvariabler som standard en global innvirkning på gjeldende sesjon. For PowerShell er det nøyaktige motsatt sant fordi rekkevidde brukes til å isolere et skripts modifikasjoner. Her vil vi undersøke hvordan omfangene påvirker PowerShell-skript og hvordan de skal fungere i og rundt dem.

Hva er et omfang?

I PowerShell refererer et "omfang" til det nåværende miljøet der et skript eller kommandoskall opererer. Scopes brukes til å beskytte enkelte gjenstander i miljøet fra å bli utilsiktet modifisert av skript eller funksjoner. Spesielt er følgende ting beskyttet mot endring av kommandoer som kjører fra et annet omfang, med mindre annet er angitt av parametere i disse kommandoene:

  • variabler
  • aliaser
  • funksjoner
  • PowerShell-stasjoner (PSDrives)

Nye mål blir opprettet når du kjører et skript eller en funksjon, eller når du oppretter en ny økt eller en forekomst av PowerShell. Scopes opprettet ved å kjøre skript og funksjoner har et "foreldre / barn" forhold med omfanget de ble laget av. Det er noen rekkevidder som har spesielt spesielle betydninger, og kan nås med navn:

  • De Global omfanget er omfanget som opprettes når PowerShell starter. Den inneholder variabler, aliaser, funksjoner og PSDrives som er innebygd i PowerShell, samt alle som er laget av PowerShell-profilen din.
  • De lokal omfang refererer til hva det nåværende omfanget er. Når du starter PowerShell, refererer det til det globale omfanget, innenfor et skript vil det være Script-omfanget etc.
  • De Manus Omfanget opprettes når et skript kjøres. De eneste kommandoene som opererer innenfor dette omfanget er de som er i skriptet.
  • Privat Omfang kan defineres innenfor det nåværende omfanget, for å forhindre at kommandoer i andre områder kan lese eller endre elementer de ellers ville ha tilgang til.

Omfang kan også omtales med nummer i visse kommandoer, der nåværende omfang er referert til som null og dets forfedre er referert til ved å øke heltall. For eksempel, i et skript som kjører fra det globale omfanget, vil Script-omfanget være 0 og det globale omfanget ville være 1. Et omfang som ble ytterligere nestet i Script-omfanget, for eksempel en funksjon, ville referere til det globale omfanget som 2. Negative tall vil imidlertid ikke fungere for å referere til barnestørrelser - årsaken til dette kommer snart til syne.

Hvordan Scopes påvirker kommandoer

Som nevnt tidligere, vil kommandoer som utføres innenfor ett område ikke påvirke ting i et annet omfang, med mindre det spesielt er sagt om det. Hvis for eksempel $ MyVar eksisterer i det globale omfanget og et skript kjører en kommando for å sette $ MyVar til en annen verdi, forblir den globale versjonen av $ MyVar uendret mens en kopi av $ MyVar plasseres i Script-omfanget med den nye verdi. Hvis en $ MyVar ikke eksisterer, vil et skript opprette det innenfor Script-omfanget som standard - ikke i det globale omfanget. Dette er viktig å huske som du lærer om det faktiske foreldre / barn forholdet mellom rekkevidde.

Forholdet mellom foreldre og barn i rekkevidde i PowerShell er enveis. Kommandoer kan se på og eventuelt modifisere det nåværende omfanget, dets overordnede og eventuelle omfang over det. Men de kan ikke se eller endre ting i noen barn i det nåværende omfanget. Dette er først og fremst fordi når du har flyttet inn i foreldreomfanget, har barnets omfang allerede blitt ødelagt fordi det har oppfylt sin hensikt. For eksempel, hvorfor må du se eller endre en variabel i Script-omfanget, fra det globale omfanget, etter at manuset har avsluttet? Det er mange tilfeller der du trenger et skript eller funksjonens endringer for å vedvare utover fullførelsen, men ikke så mange hvor du vil måtte gjøre endringer i objekter innenfor skriptets eller funksjonens omfang før eller etter det kjøres. (Vanligvis blir slike ting håndtert som en del av skriptet eller funksjonen uansett.)

Selvfølgelig, hva er regler uten unntak? Ett unntak til det ovenfor er private scopes. Objekter i de private omfangene er bare tilgjengelige for kommandoer som kjører i omfanget de ble opprettet fra. Et annet viktig unntak er elementer som har AllScope-eiendommen. Dette er spesielle variabler og aliaser der en endring i noe omfang vil påvirke alle omfang. Følgende kommandoer vil vise deg hvilke variabler og aliaser som har AllScope-egenskapen:

Get-Variable | Where-Object {$_.Options -match 'AllScope'} Get-Alias | Where-Object {$_.Options -match 'AllScope')

Omfang i aksjon

For vår første titt på målene i aksjon, skal vi starte i en PowerShell-sesjon der variabelen $ MyVar er satt til en streng, "Jeg er en global variabel!", Fra kommandolinjen. Deretter kjøres følgende skript fra en fil som heter Scope-Demo.ps1:

Function FunctionScope { 'Changing $MyVar with a function.' $MyVar = 'I got set by a function!' 'MyVar says $MyVar' } '' 'Checking current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' '' FunctionScope '' 'Checking final value of MyVar before script exit.' 'MyVar says $MyVar' ''

Hvis PowerShell-skriptene virket som de samme som batchskript, kan vi forvente at valget på $ MyVar (eller% MyVar% i batchsyntaxen) endres fra 'Jeg er en global variabel!' Til 'Jeg ble satt av et skript!', og til slutt til "Jeg ble satt av en funksjon!" der det ville bli til det eksplisitt endret seg igjen eller økten ble avsluttet. Men se hva som faktisk skjer her når vi beveger oss gjennom hver av områdene - spesielt etter at FunctionScope-funksjonen har fullført sitt arbeid og vi sjekker variabelen igjen fra Script og senere Global, omfanget.

Som du kan se, syntes variabelen å virke som vi flyttet gjennom skriptet fordi, til funksjonen FunctionScope ble fullført, sjekket vi på variabelen fra samme omfang som den sist ble endret. Etter at FunctionScope ble gjort skjønt, flyttet vi tilbake til Script-omfanget hvor $ MyVar ble forlatt uberørt av funksjonen. Da, da skriptet ble avsluttet, kom vi tilbake til det globale omfanget der det ikke hadde blitt endret i det hele tatt.
Som du kan se, syntes variabelen å virke som vi flyttet gjennom skriptet fordi, til funksjonen FunctionScope ble fullført, sjekket vi på variabelen fra samme omfang som den sist ble endret. Etter at FunctionScope ble gjort skjønt, flyttet vi tilbake til Script-omfanget hvor $ MyVar ble forlatt uberørt av funksjonen. Da, da skriptet ble avsluttet, kom vi tilbake til det globale omfanget der det ikke hadde blitt endret i det hele tatt.

Nå utenfor det lokale området

Så, dette er alt bra og bra for å hjelpe deg med å holde ved et uhell å bruke endringer i miljøet utover dine skript og funksjoner, men hva hvis du egentlig vil gjøre slike endringer? Det er en spesiell og ganske enkel syntaks for å skape og endre objekter utenfor lokalområdet. Du plasserer bare omfangsnavnet ved starten av variabelnavnet, og legger et kolon mellom omfanget og variabelnavnet. Som dette:

$global:MyVar $script:MyVar $local:MyVar

Du kan bruke disse modifikatorene både når du ser og stiller variabler. La oss se hva som skjer med dette demonstrasjonsskriptet:

Function FunctionScope { '' 'Changing $MyVar in the local function scope…' $local:MyVar = 'This is MyVar in the function's local scope.' 'Changing $MyVar in the script scope…' $script:MyVar = 'MyVar used to be set by a script. Now set by a function.' 'Changing $MyVar in the global scope…' $global:MyVar = 'MyVar was set in the global scope. Now set by a function.' '' 'Checking $MyVar in each scope…' 'Local: $local:MyVar' 'Script: $script:MyVar' 'Global: $global:MyVar' '' } '' 'Getting current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' FunctionScope 'Checking $MyVar from script scope before exit.' 'MyVar says $MyVar' ''

Som før starter vi ved å sette variabelen i det globale omfanget og avslutte med å sjekke det endelige globale omfangsresultatet.

Her kan du se at FunctionScope var i stand til å endre variabelen i Script-omfanget, og at endringene vedvarer etter at den ble fullført. Også endringen til variabelen i det globale omfanget fortsatte selv etter at skriptet hadde gått ut. Dette kan være spesielt nyttig hvis du må endre gjentatte ganger variabler i et skript eller i det globale omfanget, ved hjelp av samme kode. Du definerer bare en funksjon eller et skript som er skrevet for å endre variabelen hvor og hvordan du trenger det gjort, og ring på det når disse endringene er nødvendige.
Her kan du se at FunctionScope var i stand til å endre variabelen i Script-omfanget, og at endringene vedvarer etter at den ble fullført. Også endringen til variabelen i det globale omfanget fortsatte selv etter at skriptet hadde gått ut. Dette kan være spesielt nyttig hvis du må endre gjentatte ganger variabler i et skript eller i det globale omfanget, ved hjelp av samme kode. Du definerer bare en funksjon eller et skript som er skrevet for å endre variabelen hvor og hvordan du trenger det gjort, og ring på det når disse endringene er nødvendige.

Som nevnt tidligere kan omfangsnumre også brukes i enkelte kommandoer for å endre variabelen på forskjellige nivåer i forhold til lokalområdet. Her er det samme skriptet som brukes i det andre eksempelet ovenfor, men med funksjonen endret til å bruke kommandoerene Variabel og Set-Variabel med antallnumre i stedet for direkte å referere til variabelen med navngitte rekkevidde:

Function FunctionScope { '' 'Changing $MyVar in scope 0, relative to FunctionScope…' Set-Variable MyVar 'This is MyVar in the function's scope 0.' –Scope 0 'Changing $MyVar in scope 1, relative to FunctionScope…' Set-Variable MyVar 'MyVar was changed in scope 1, from a function.' –Scope 1 'Changing $MyVar in scope 2, relative to Functionscope…' Set-Variable MyVar 'MyVar was changed in scope 2, from a function.' –Scope 2 '' 'Checking $MyVar in each scope…' ‘Scope 0:’ Get-Variable MyVar –Scope 0 –ValueOnly ‘Scope 1:’ Get-Variable MyVar –Scope 1 –ValueOnly ‘Scope 2:’ Get-Variable MyVar –Scope 2 –ValueOnly '' } '' 'Getting current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' FunctionScope 'Checking $MyVar from script scope before exit.' 'MyVar says $MyVar' ''

Image
Image

På samme måte som før, kan vi se her hvordan kommandoer i ett omfang kan endre objekter i sitt overordnede omfang.

Tilleggsinformasjon

Det er fortsatt mye mer som kan gjøres med omfang enn det som passer inn i denne artikkelen. Scopes påvirker mer enn bare variabler, og det er fortsatt mer å lære om Private scopes og AllScope-variablene. For mer nyttig informasjon, kan du kjøre følgende kommando fra PowerShell:

Get-Help about_scopes

Den samme hjelpefilen er også tilgjengelig på TechNet.

Omfang bilde kreditt: Spadassin på openclipart

Anbefalt: