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.
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.
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' ''
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