Hvordan Scopes påvirker PowerShell Scripts
I batchskript har endringer i miljøvariabler som standard en global innvirkning på gjeldende sesjon. For PowerShell er det nøyaktige motsatt sant fordi omfangene 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 opprettet fra. 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, vil det referere til det globale omfanget, innenfor et skript vil det være Script-omfanget, osv.
- 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å refereres til i tall i bestemte 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 innenfor Script-omfanget, for eksempel en funksjon, ville referere til det globale omfanget som 2 . Negative tall vil imidlertid ikke fungere for å referere til barnestrekninger - årsaken til dette vil være tydelig innen kort tid.
Hvordan Scopes påvirker kommandoer
Som nevnt tidligere, vil kommandoer som utføres i ett omfang ikke påvirke ting i et annet omfang, med mindre det spesielt er sagt om det. For eksempel, hvis $ 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 er plassert 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 foreldreområdet, 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 funksjons endringer for å vedvare utover ferdigstillelsen, men ikke så mange der du må 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 kun tilgjengelige for kommandoer som går i omfanget de ble opprettet fra. Et annet viktig unntak er elementer som har AllScope-eiendommen. Dette er spesielle variabler og aliaser som 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 | Hvor-objekt $ _. Alternativer -match 'AllScope' Hent-alias | Hvor-objekt $ _. Alternativer -match 'AllScope')
Scopes in Action
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:
Funksjon FunctionScope 'Endre $ MyVar med en funksjon.' $ MyVar = 'Jeg ble satt av en funksjon!' "MyVar sier $ MyVar" "Kontrollerer nåværende verdi på $ MyVar." "MyVar sier $ MyVar" "Endre $ MyVar etter script." $ MyVar = 'Jeg ble satt av et skript!' "MyVar sier $ MyVar" "FunctionScope" Kontrollerer sluttverdien til MyVar før utskrift av script. " "MyVar sier $ MyVar" "
Hvis PowerShell-skriptene virket som de samme som batchskript, kan vi forvente at valget av $ 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!" hvor det ville bli til det eksplisitt endret seg igjen eller økten ble avsluttet. Se imidlertid hva som egentlig skjer her når vi beveger oss gjennom hver av målene - 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 å forandre seg da vi beveget oss 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, 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 omfanget
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:
Funksjon FunctionScope "Endre $ MyVar i det lokale funksjonsområdet ..." $ local: MyVar = "Dette er MyVar i funksjonens lokale omfang." 'Endre $ MyVar i scriptets omfang ...' $ script: MyVar = 'MyVar pleide å være sett av et skript. Nå sett av en funksjon. "Endre $ MyVar i det globale omfanget ... '$ global: MyVar =' MyVar ble satt i det globale omfanget. Nå sett av en funksjon. "Kontrollerer $ MyVar i hvert omfang ..." "Lokalt: $ local: MyVar" "Skript: $ script: MyVar" "Global: $ global: MyVar" "" Få nåverdien av $ MyVar. " "MyVar sier $ MyVar" "Endre $ MyVar etter script." $ MyVar = 'Jeg ble satt av et skript!' "MyVar sier $ MyVar" FunctionScope "Kontrollerer $ MyVar fra skriptomfanget før utgang. ' "MyVar sier $ 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 har endringene vedvarende 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, 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 omfangsnumre i stedet for direkte å referere til variabelen med navngitte omfang:
Funksjon FunctionScope "Endre $ MyVar i omfang 0, i forhold til FunctionScope ..." Set-Variable MyVar "Dette er MyVar i funksjonens omfang 0." -Scope 0 'Endrer $ MyVar i omfang 1, i forhold til FunctionScope ...' Set-Variable MyVar 'MyVar ble endret i omfang 1, fra en funksjon.' -Scope 1 'Endrer $ MyVar i omfang 2, i forhold til Functionscope ...' Set-Variable MyVar 'MyVar ble endret i omfang 2, fra en funksjon.' -Scope 2 "Kontrollerer $ MyVar i hvert omfang ..." Omfang 0: 'Variabel MyVar -Scope 0 -ValueOnly' Scope 1: 'Variabel MyVar -Scope 1 -ValueOnly' Scope 2: 'Variabel MyVar -Scope 2 -ValueOnly "" Få dagens verdi på $ MyVar. " "MyVar sier $ MyVar" "Endre $ MyVar etter script." $ MyVar = 'Jeg ble satt av et skript!' "MyVar sier $ MyVar" FunctionScope "Kontrollerer $ MyVar fra skriptomfanget før utgang. ' "MyVar sier $ MyVar" "
På samme måte som før, kan vi se her hvordan kommandoer i ett omfang kan endre objekter i foreldreområdet.
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:
Få hjelp om_scopes
Den samme hjelpefilen er også tilgjengelig på TechNet.
Scope bilde kreditt: Spadassin på openclipart