Adam the Automator

author
11 minutes, 31 seconds Read

Kun kirjoitat PowerShell-skriptin, jossa ei ole funktioita eikä ulkoisia riippuvuuksia muista skripteistä, PowerShellin laajuuksien käsitteellä ei ole suurta merkitystä. PowerShellin globaalien muuttujien käsite ei ole etusijalla. Mutta kun alat rakentaa funktioita, moduuleja ja opit kutsumaan skriptejä muista skripteistä, aiheesta tulee entistä tärkeämpi.

Tässä artikkelissa saat syvällisen oppitunnin siitä, mitä PowerShellin laajuudet ovat, miten ne toimivat ja miten voit kirjoittaa koodia laajuudet huomioiden. Kun olet valmis, ymmärrät PowerShellin globaalit muuttujat ja paljon muuta!

Sisällysluettelo

Scopes: Vähän kuin ämpäreitä

Oletko koskaan kirjoittanut skriptiä, jossa määrittelet muuttujan ja kun tarkistat muuttujan arvon, se on jotain muuta? Saatat raapia päätäsi siitä, miten tuo muuttuja muuttui, kun määrittelit sen selkeästi. Yksi syy voi olla se, että muuttujan arvo ylikirjoitetaan toisessa laajuudessa.

Olet ehkä miettinyt, miten tietyillä PowerShell-muuttujilla on arvoja, kun viittaat niihin konsolissa, mutta niitä ei ole skripteissäsi. Todennäköisesti nämä muuttujat ovat toisessa ”ämpäriin”, joka ei ole sillä hetkellä käytettävissä.

Scopes ovat kuin ämpäreitä. Laajuusalueet vaikuttavat siihen, miten PowerShell eristää muuttujat, aliakset, funktiot ja PSDriven eri alueiden välillä. Laajuusalue on kuin ämpäri. Se on paikka, johon kerätään kaikki nämä kohteet yhteen.

Kun PowerShell käynnistyy, se luo nämä ”ämpärit” automaattisesti puolestasi. Siinä vaiheessa käytät jo scopeja huomaamattasi. PowerShell määrittelee kaikki laajuudet, ja ne luodaan ilman sinun apuasi.

Scope-tyypit

Kun PowerShell käynnistyy, se luo automaattisesti neljä ”ämpäriä” eli laajuutta, joihin eri kohteet voidaan sijoittaa. Et voi luoda scopeja itse. Voit lisätä ja poistaa kohteita vain näistä alla määritellyistä laajuusalueista.

Globaali laajuusalue

PowerShellin avautuessa määritellyt kohteet asetetaan globaaliin laajuusalueeseen. Näihin kohteisiin kuuluvat järjestelmän luomat kohteet, kuten PowerShell-asemat, ja myös kaikki, mitä olet määritellyt PowerShell-profiilissa, koska profiili suoritetaan käynnistyksen yhteydessä.

Globaalissa laajuudessa olevat kohteet ovat käytettävissä kaikkialla. Voit viitata globaalissa laajuudessa oleviin kohteisiin interaktiivisesti konsolissa, missä tahansa suorittamassasi skriptissä ja missä tahansa funktiossa. PowerShellin globaalit muuttujat ovat käytettävissä kaikkialla. Tästä syystä PowerShellin globaalien muuttujien yleinen käyttötapa on käyttää PowerShellin globaaleja muuttujia komentosarjojen välillä.

On vain yksi globaali laajuus, joka hallitsee kokonaisuutta.

Komentosarjan laajuus

Komentosarjan laajuus luodaan automaattisesti aina, kun PowerShellin komentosarja suoritetaan. Sinulla voi olla useita eri komentosarjan laajuusinstansseja. Skriptialueet luodaan, kun suoritat esimerkiksi PS1-skriptin tai moduulin.

Vain kyseisessä skriptialueen instanssissa luodut kohteet voivat viitata toisiinsa.

Yksityinen alue

Tyypillisesti määritettyyn kohteeseen voidaan päästä käsiksi muista alueista – tämä ei päde yksityisen alueen kohteisiin. Kohteet yksityisessä laajuudessa, sisältävät objekteja, jotka ovat piilossa muilta laajuuksilta. Yksityistä laajuutta käytetään sellaisten kohteiden luomiseen, joilla on sama nimi kuin muissa laajuuksissa olevilla kohteilla päällekkäisyyksien estämiseksi.

Paikallinen laajuus

Lokaalinen laajuus on muista laajuuksista poiketen hieman erilainen. Paikallinen scope on osoitin globaaliin, skripti- tai yksityiseen scopeen. Paikallinen scope on suhteellinen siihen, missä kontekstissa koodi kulloinkin suoritetaan.

Jos luot muuttujan, aliaksen, funktion tai PSDriven määrittelemättä sille eksplisiittisesti scopea (jota käsittelemme myöhemmin), se siirtyy paikalliseen scopeen.

Laajuusalueisiin viittaaminen

Nyt kun sinulla on käsitys neljästä olemassa olevasta laajuustyypistä, sinun pitäisi myös tietää, että näihin laajuuksiin voi viitata kahdella tavalla.

PowerShellissä on kaksi tapaa viitata laajuuksiin: nimettyihin tai numeroituihin. Molemmilla tavoilla viitataan samoihin laajuuksiin, mutta yksinkertaisesti eri tavalla. Nämä ovat kaksi erilaista tapaa olla vuorovaikutuksessa laajuuksien kanssa.

Nimetyt laajuudet

Yllä kohdassa Laajuuden tyyppi opit laajuuksista, joihin viitataan nimellä. Laajuusalueeseen viittaaminen nimellä on intuitiivisesti nimeltään nimetty laajuusalue. Laajuusalueeseen nimellä viittaamisen päätarkoitus on määrittää kohde laajuusalueeseen. Seuraavassa opit, miten tämä tehdään.

Numeroidut scope:t

Nimen lisäksi jokaisella scope:lla on nollasta alkava numero, joka on aina paikallinen scope. Laajuudet numeroidaan dynaamisesti suhteessa nykyiseen paikalliseen laajuuteen.

Heti kun esimerkiksi avaat PowerShell-istunnon, toimit globaalissa laajuudessa. Tässä vaiheessa globaali laajuus on paikallinen laajuus (muista, että paikallinen laajuus on vain osoitin).

Koska paikallinen laajuus on aina laajuus nolla, tässä vaiheessa myös globaali laajuus on tällä hetkellä laajuus nolla. Mutta kun suoritat komentosarjan samasta istunnosta, komentosarjan scope luodaan. Suoritettaessa paikallisen laajuuden osoitin on tällöin muuttunut komentosarjan laajuudeksi. Nyt skriptin scope on scope nolla ja globaali scope on scope yksi.

Scopes are numbered Tämä prosessi toistuu niin monelle scopeille kuin sinulla on, joissa paikallinen scope on 0. Scopeja numeroidaan dynaamisesti scope-hierarkian mukaan.

Scope-hierarkia ja periytyminen

Kuten aiemmin mainittiin, kun käynnistät PowerShell-istunnon, PowerShell luo sinulle joitakin kohteita globaaliin scopeen. Nämä kohteet voivat olla funktioita, muuttujia, aliaksia tai PSDriveja. Kaikki, mitä määrittelet PowerShell-istunnossa, määritellään myös globaalissa laajuudessa.

Koska olet oletusarvoisesti globaalissa laajuudessa, jos teet jotakin, joka luo toisen laajuuden, kuten komentosarjan suorittamisen tai funktion suorittamisen, luodaan lapsilaajuus, jonka vanhempi on globaali laajuus. Laajuusalueet ovat kuin prosessit, joilla on vanhemmat ja lapset.

Kaikkea, mikä on määritelty vanhemmassa laajuudessa, tässä tapauksessa globaalissa laajuudessa, on käytettävissä lapsilaajuudessa. Mutta nämä kohteet ovat muokattavissa vain siinä scopeissa, jossa ne on määritelty.

Asetaan, että sinulla on skripti nimeltä Test.ps1. Tämän komentosarjan sisällä on yksi rivi alla olevan kuvan mukaisesti.

$a = 'Hello world!'

Kun suoritat tämän komentosarjan, $a saa arvon paikallisessa laajuudessa (komentosarja komentosarjan ollessa käynnissä). Kun Test.ps1 suoritetaan, alla näkyy, että siihen ei voi viitata komentosarjan suorittamisen jälkeen. Koska $a annettiin komentosarjan laajuudessa ollessaan, globaali laajuus (interaktiivisessa konsolissa) ei voi nähdä sitä.

Globaali laajuus ei voi nähdä muuttujaa

Viedään tämä esimerkki vielä askeleen pidemmälle ja muutetaan komentosarja Test.ps1 alla olevan näköiseksi. Skripti yrittää nyt tulostaa $a:n arvon, ennen kuin se asetetaan samassa laajuudessa.

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

Näyttääksesi sen, anna arvo $a:lle interaktiivisessa konsolissa. Tämä määrittää arvon globaalissa laajuudessa. Kun skripti nyt suoritetaan, se perii vanhemman scope:n (globaali) ja sen pitäisi nähdä arvo.

Alhaalla näet, että kun Test.ps1 suoritetaan (luoden globaalin scope:n lapsi scope:n), se näkee arvon $a. Voit myös nähdä, että muuttujan arvo on käytettävissä myös globaalissa laajuudessa, koska se asetettiin tähän laajuuteen. Tämä tarkoittaa, että $a on käytettävissä sekä skriptin (child) että vanhemman (global) scopeissa.

Muuttuja on käytettävissä skriptin ja globaalin scopeissa

Muistathan tämän scope-perinnön käyttäytymisen. Näin tekeminen auttaa sinua, kun vianetsintätilanteissa esiintyy muuttujaristiriitoja, kuten samannimisiä muuttujia eri laajuuksissa.

Laajuusalueiden kohteiden määrittäminen ja käyttäminen

Nyt kun tiedät, mikä laajuusalue on ja miten ne toimivat, miten voit käyttää niitä? Katsotaanpa, miten PowerShellin avulla voit määrittää muuttujan laajuuden (ja käyttää niitä).

Get/Set-Variable

PowerShellissä on kaksi cmdlettiä, joiden avulla voit määrittää muuttujia nimeltä Get-Variable ja Set-Variable. Näiden cmdlettien avulla voit hakea muuttujan arvon tai määritellä arvon.

Kummatkin cmdletit ovat samankaltaisia Name– ja Scope-parametrilla. Näiden parametrien avulla PowerShell mahdollistaa muuttujan arvojen asettamisen ja hakemisen kaikissa laajuuksissa.

Paikalliset laajuudet

Muuttujan asettamiseksi paikalliseen laajuuteen käytetään Set-Variable-parametria ja annetaan sille paikallisen muuttujan nimi ja arvo alla esitetyllä tavalla.

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

Lokaalinen laajuus on aina oletusarvo, joten muuttujan määritteleminen paikalliseen laajuuteen onnistuu aina, jos et käytä Scope-parametria.

Voidaksesi hakea paikallisesti määritellyn muuttujan arvon, käytä Get-Variable antaen sille nimen.

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

Private/Script/Global Scopes

Käytät samoja parametreja (Name ja Value) työskennellessäsi myös private-, script- ja globaalimuuttujien kanssa. Ainoa ero on, että tällä kertaa käytät Scope-parametria määritelläksesi laajuuden eksplisiittisesti.

Menetelmät yksityisen, skripti- tai globaalisti rajattujen muuttujien asettamiseen ovat samat. Korvaa vain Scope-parametrille välitetty arvo Private, Script Global.

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

Skriptin tai globaalisti rajatun muuttujan arvon hakemiseksi käytä Get-Variable antamalla sille nimi ja scope.

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

Huomautus: Voit myös viitata laajuusalueisiin käyttämällä nimen sijasta laajuusalueen numeroita Get/Set-Variable-cmdlettien avulla.

Laajuusalue ”Prefacing”

Voit myös hakea ja asettaa laajuusalueiden muuttujia pikakuvakkeen avulla. Sen sijaan, että käyttäisit PowerShell-senttipainikkeita, esitä muuttujan laajuus, kun viittaat siihen.

Paikalliset laajuudet

Koska paikallinen laajuus on aina oletusarvo, pelkkä muuttujan määrittäminen ja viittaaminen asettaa ja hakee paikallisen laajuuden muuttujan

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

Yksityiset/Skripti/Globaalit laajuudet

Jos haluat määritellä ja viitata skripti- tai globaaleihin laajuusalueisiin, voit liittää muuttujan etuliitteeksi laajuuden nimen ja puolipisteen.

Voit esimerkiksi asettaa muuttujan $a globaaliin laajuuteen, voit edeltää a:ta merkinnällä $global:.

$global:a = 'foo'

Samoin voit tehdä skriptin laajuisen muuttujan kohdalla.

$script:a = 'foo'

Kun muuttujat on asetettu haluttuun laajuuteen, voit viitata niihin samalla tavalla. Huomaa myös, että voit jättää scope-esimerkin pois, jos määritelty scope on local scope.

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

Scopes in Scriptblocks

PowerShellissä on kätevä konstruktio nimeltä scriptblocks. Scriptblockien avulla voit liikutella koodinpätkiä ja suorittaa niitä lähes missä tahansa.

Skriptilohkot toimivat PS1-skriptin tavoin omassa skriptin laajuudessaan. Kun suoritat scriptblockin, suoritat periaatteessa PS1-skriptin.

Huomaa alla olevassa esimerkissä, jossa muuttuja on määritelty globaalissa laajuudessa ja sitten yritetään korvata se skriptin laajuudessa. Kuten edellä opit, tämä ei onnistu, koska lapsialue ei voi viitata vanhempialueeseen.

Lapsialue ei voi korvata vanhempialuetta

Tässä esimerkissä nähdään, että kun $a muutetaan skriptiblokissa, globaalin muuttujan $a määrittelyä ei muuteta, koska skriptiblokki on komentosarjan lapsialue.

Dot-sourcing-skriptit (Paikallisten laajuuksien vaihtaminen)

PowerShellissä on käsite nimeltä dot-sourcing. Tämä on menetelmä, jonka avulla voit suorittaa PS1-skriptin ja tuoda sen sijaan kaiken sen, mikä olisi skriptin vaikutusalueella, paikalliseen vaikutusalueeseen.

Sijoittamalla pisteen (.) ennen PS1-skriptiin viittaamista ja sen suorittamista, tämä ”piste-lähtee” skriptin sisällön ja tuo kaiken paikalliseen vaikutusalueeseen.

Demonstraationa minulla on taas Test.ps1-skripti, joka määrittelee muuttujan alla esitetyllä tavalla.

$a = 'Hello world!'

Aseta PowerShell-konsolissa arvo $a-muuttujalle ja tee sitten dot source tähän skriptiin alla esitetyllä tavalla. Huomaa, että alkuperäinen muuttuja korvattiin. PowerShell ”sulautti” kaksi paikallista laajuutta yhteen.

Alkuperäinen muuttuja ylikirjoitettu

AllScope-ominaisuuden käyttäminen (Vaihtoehto)

Olet nähnyt, miten voit olla vuorovaikutuksessa tietyissä laajuuksissa sijaitsevien kohteiden kanssa, mutta toistaiseksi kukin kohde on edelleen määritetty yhdessä laajuudessa. Mutta entä jos et tiedä, missä laajuudessa muuttuja on määritelty?

Muuttujan määrittelyssä Set-Variable-komentokomennolla voit sijoittaa muuttujan kaikkiin laajuuksiin kerralla. Voit tehdä tämän käyttämällä Option-parametrin arvoa AllScope.

Demonstraatiota varten Test.ps1-skriptiä on muutettu siten, että muuttuja asetetaan kaikkiin laajuuksiin. Kyseinen muuttuja tulostetaan sitten alla esitetyllä tavalla.

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

Alhaalla näkyy, että $a:lle asetetaan arvo globaalissa laajuudessa ja Test.ps1-skripti suoritetaan. Sen sijaan, että sillä ei olisi mitään vaikutusta, $a:n arvo on kuitenkin korvattu. Sen lisäksi, että se on määritetty skriptin laajuudessa (Write-Output $a), se on myös korvattu globaalissa laajuudessa.

Muuttuja on korvattu globaalissa laajuudessa

Vaihtoehto AllScope on kätevä, mutta ole varovainen. Tämä vaihtoehto hävittää käytännössä käsitteen scope ja sulauttaa kaiken yhteen.

Funktioiden scope

Kun suoritat funktion, kaikki funktiossa oleva koodi on sen omassa lapsi scopeissa. Funktioiden laajuudet noudattavat samaa lapsi/vanhempi -käyttäytymistä kuin muutkin laajuudet.

Erillisten laajuuksien pitäminen jokaiselle funktiolle on hyvä idea. Se mahdollistaa kohteiden paremman hallinnan, eikä tarvitse huolehtia kohteiden ristiriitaisuudesta, Se antaa myös lisäetua funktiossa olevien muuttujien automaattisesta siivouksesta. Heti kun funktio valmistuu, kaikki funktiossa määritellyt kohteet tyhjennetään.

Demonstraatiota varten kopioi/liitä alla oleva funktio suoraan PowerShell-konsoliin.

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

Kun olet liittänyt sen, suorita funktio. Huomaa, että $var-muuttujaa ei voi käyttää funktion ulkopuolella.

PS> Do-ThingPS> $var

Keeping Items Private (Disabling Inheritance)

Tyypillisesti, jos muuttuja on määritetty vanhemmassa laajuudessa, kyseinen muuttuja määritellään myös lapsen laajuudessa. Mutta ehkä haluaisit käyttää muuttujan nimeä, mutta kyseinen muuttujan nimi on jo määritelty jossakin istunnossa ajettavassa laajuudessa. Siinä tapauksessa voit joko valita toisen muuttujan nimen tai määritellä muuttujan yksityisessä laajuudessa tehden siitä yksityisen muuttujan.

Yksi tapa käyttää laajuuksia ristiriitojen vähentämiseksi on käyttää yksityistä laajuutta. Yksityisen laajuuden käyttäminen poistaa periytymisen käytöstä kyseiseltä muuttujalta. Kun luodaan useita tytärlaajuusalueita, nämä tytärlaajuusalueet eivät näe muuttujia, jotka on määritelty yksityisessä laajuudessa.

Test.ps1-skripti tulostaa $a:n arvon alla esitetyllä tavalla.

Write-Output $a

Alhaalla näet, että määrittelen yksityisessä laajuudessa olevan muuttujan globaalissa laajuudessa ja suoritan sitten Test.ps1-skriptin. Yleensä kun määrittelet muuttujan vanhemmassa laajuudessa, kyseinen muuttuja on käytettävissä lapsilaajuudessa – näin ei ole yksityisesti määritellyn muuttujan kohdalla.

Alla olevassa esimerkissä näkyy, että Test.ps1-skriptin suorittamisella luotu komentosarjan lapsialue ei nähnyt vanhempaan alueeseen määritettyä yksityistä $a-muuttujaa.

Skriptin scope ei voi nähdä private-scoped-muuttujaa

Toisin kuin globaalit scope-alueet tai Set-Variable-cmdletin AllScope-vaihtoehto, private-scoped-muuttujat ovat erinomainen tapa lokeroida kohteita.

Laajennuksen parhaat käytännöt

Ajattelu, että muuttujien määrittäminen globaalissa laajuudessa tai AllScope-vaihtoehdon käyttäminen on oikea tapa, on yleistä. Loppujen lopuksi kaikki muuttujat ovat käytettävissä kaikkialla. Laajuusalueiden monimutkaisuudesta ei tarvitse huolehtia. Vaikka tämä antaakin lisävapautta määritellyn saatavuuteen, se voi riistäytyä nopeasti käsistä ja vaikeuttaa vianetsintää.

Se sijaan, että yrität estää laajuuksien käytön, noudata näitä vinkkejä:

  1. Se sijaan, että määrittelisit laajuuksia funktioissa, käytä parametreja tarvittavien tietojen välittämiseen funktiolle.
  2. Pitäydy paikallisessa laajuudessa (local scope) niin paljon kuin mahdollista.
  3. Määritä globaaleja muuttujia komentosarjassa sen sijaan, että käyttäisit Write-Output-komentoa, jolla voit tulostaa kaiken ja tallentaa sen muuttujaan tarvittaessa konsolista.

Pääasia tässä on, että omaksut laajuudet ja opit käyttämään niitä hyödyksesi sen sijaan, että yrität kiertää niitä.

Lisälukemista

  • Tietoa kehittyneistä funktioista ja funktioparametreista
  • Ympäristömuuttujien käyttäminen PowerShellissä

Similar Posts

Vastaa

Sähköpostiosoitettasi ei julkaista.