Delen via


about_Scopes

Korte beschrijving

Hierin wordt het concept van het bereik in PowerShell uitgelegd en wordt uitgelegd hoe u het bereik van elementen instelt en wijzigt.

Lange beschrijving

PowerShell beveiligt de toegang tot variabelen, aliassen, functies en PowerShell-stations (PSDrives) door te beperken waar ze kunnen worden gelezen en gewijzigd. PowerShell maakt gebruik van bereikregels om ervoor te zorgen dat u niet per ongeluk een item wijzigt dat niet mag worden gewijzigd.

Hier volgen de basisregels voor het bereik:

  • Bereiken kunnen nesten. Een buitenbereik wordt een bovenliggend bereik genoemd. Geneste bereiken zijn onderliggende bereiken van dat bovenliggende bereik.

  • Een item is zichtbaar in het bereik waarin het is gemaakt en in eventuele onderliggende bereiken, tenzij u het expliciet privé maakt.

  • U kunt variabelen, aliassen, functies en PowerShell-stations declareren in een bereik dat buiten het huidige bereik valt.

  • Een item dat u binnen een bereik hebt gemaakt, kan alleen worden gewijzigd in het bereik waarin het is gemaakt, tenzij u expliciet een ander bereik opgeeft.

Als u een item in een bereik maakt en het item de naam ervan deelt met een item in een ander bereik, is het oorspronkelijke item mogelijk verborgen onder het nieuwe item, maar wordt het niet overschreven of gewijzigd.

PowerShell-bereiken

PowerShell ondersteunt de volgende bereiken:

  • Globaal: het bereik dat van kracht is wanneer PowerShell wordt gestart of wanneer u een nieuwe sessie of runspace maakt. Variabelen en functies die aanwezig zijn wanneer PowerShell wordt gestart, zijn gemaakt in het globale bereik, zoals automatische variabelen en voorkeursvariabelen. De variabelen, aliassen en functies in uw PowerShell-profielen worden ook gemaakt in het globale bereik. Het globale bereik is het bovenliggende hoofdbereik in een sessie.

  • Lokaal: het huidige bereik. Het lokale bereik kan het globale bereik of een ander bereik zijn.

  • Script: het bereik dat wordt gemaakt terwijl een scriptbestand wordt uitgevoerd. Alleen de opdrachten in het script worden uitgevoerd in het scriptbereik. Voor de opdrachten in een script is het scriptbereik het lokale bereik.

Notitie

Privé is geen bereik. Het is een optie waarmee de zichtbaarheid van een item wordt gewijzigd buiten het bereik waarin het item is gedefinieerd.

Bovenliggende en onderliggende bereiken

U kunt een nieuw onderliggend bereik maken door een script of functie aan te roepen. Het aanroepende bereik is het bovenliggende bereik. Het aangeroepen script of de functie is het onderliggende bereik. De functies of scripts die u aanroept, kunnen andere functies aanroepen, waardoor een hiërarchie wordt gemaakt van onderliggende bereiken waarvan het hoofdbereik het globale bereik is.

Tenzij u de items expliciet privé maakt, zijn de items in het bovenliggende bereik beschikbaar voor het onderliggende bereik. Items die u maakt en wijzigt in het onderliggende bereik, hebben echter geen invloed op het bovenliggende bereik, tenzij u het bereik expliciet opgeeft wanneer u de items maakt.

Notitie

Functies van een module worden niet uitgevoerd in een onderliggend bereik van het aanroepende bereik. Modules hebben hun eigen sessiestatus die is gekoppeld aan het globale bereik. Alle modulecode wordt uitgevoerd in een modulespecifieke hiërarchie van bereiken met een eigen hoofdbereik.

Overname

Een onderliggend bereik neemt de variabelen, aliassen en functies niet over van het bovenliggende bereik. Tenzij een item privé is, kan het onderliggende bereik de items in het bovenliggende bereik weergeven. En de items kunnen worden gewijzigd door expliciet het bovenliggende bereik op te geven, maar de items maken geen deel uit van het onderliggende bereik.

Er wordt echter een onderliggend bereik gemaakt met een set items. Normaal gesproken bevat het alle aliassen met de optie AllScope . Deze optie wordt verderop in dit artikel besproken. Het bevat alle variabelen met de optie AllScope , plus enkele automatische variabelen.

Als u de items in een bepaald bereik wilt vinden, gebruikt u de bereikparameter van Get-Variable of Get-Alias.

Als u bijvoorbeeld alle variabelen in het lokale bereik wilt ophalen, typt u:

Get-Variable -Scope local

Als u alle variabelen in het globale bereik wilt ophalen, typt u:

Get-Variable -Scope global

Bereikaanpassingen

Een variabele, alias of functienaam kan een van de volgende optionele bereikaanpassingen bevatten:

  • global: - Hiermee geeft u op dat de naam bestaat in het bereik Globaal .

  • local: - Hiermee geeft u op dat de naam bestaat in het bereik Lokaal . Het huidige bereik is altijd het lokale bereik.

  • private: - Geeft aan dat de naam Privé is en alleen zichtbaar is voor het huidige bereik.

  • script: - Hiermee geeft u op dat de naam bestaat in het scriptbereik . Scriptbereik is het bereik van het dichtstbijzijnde bovenliggende scriptbestand of Globaal als er geen dichtstbijzijnde bovenliggend scriptbestand is.

  • using: - Wordt gebruikt voor toegang tot variabelen die zijn gedefinieerd in een ander bereik tijdens het uitvoeren van scripts via cmdlets zoals Start-Job en Invoke-Command.

  • workflow: - Hiermee geeft u op dat de naam bestaat in een werkstroom. Opmerking: Werkstromen worden niet ondersteund in PowerShell v6 en hoger.

  • <variable-namespace> - Een wijzigingsfunctie die is gemaakt door een PowerShell PSDrive-provider. Bijvoorbeeld:

    Naamruimte Description
    Alias: Aliassen die zijn gedefinieerd in het huidige bereik
    Env: Omgevingsvariabelen die zijn gedefinieerd in het huidige bereik
    Function: Functies die zijn gedefinieerd in het huidige bereik
    Variable: Variabelen die zijn gedefinieerd in het huidige bereik

Het standaardbereik voor scripts is het scriptbereik. Het standaardbereik voor functies en aliassen is het lokale bereik, zelfs als deze zijn gedefinieerd in een script.

Bereikaanpassingen gebruiken

Als u het bereik van een nieuwe variabele, alias of functie wilt opgeven, gebruikt u een bereikaanpassing.

De syntaxis voor een bereikaanpassing in een variabele is:

$[<scope-modifier>:]<name> = <value>

De syntaxis voor een bereikaanpassing in een functie is:

function [<scope-modifier>:]<name> {<function-body>}

Met de volgende opdracht, die geen bereikaanpassing gebruikt, maakt u een variabele in het huidige of lokale bereik:

$a = "one"

Als u dezelfde variabele in het globale bereik wilt maken, gebruikt u de wijzigingsfunctie voor het bereik global: :

$global:a = "one"

Als u dezelfde variabele in het scriptbereik wilt maken, gebruikt u de script: wijzigingsfunctie voor het bereik:

$script:a = "one"

U kunt ook een bereikaanpassing met functies gebruiken. Met de volgende functiedefinitie maakt u een functie in het globale bereik:

function global:Hello {
  Write-Host "Hello, World"
}

U kunt ook bereikaanpassingen gebruiken om te verwijzen naar een variabele in een ander bereik. De volgende opdracht verwijst naar de $test variabele, eerst in het lokale bereik en vervolgens in het globale bereik:

$test
$global:test

De Using: wijziging van het bereik

Het gebruik is een speciale bereikaanpassing waarmee een lokale variabele in een externe opdracht wordt geïdentificeerd. Zonder een wijzigingsfunctie verwacht PowerShell dat variabelen in externe opdrachten worden gedefinieerd in de externe sessie.

De Using bereikaanpassing is geïntroduceerd in PowerShell 3.0.

Voor elk script of elke opdracht die buiten de sessie wordt uitgevoerd, hebt u de Using bereikaanpassing nodig om variabele waarden uit het aanroepende sessiebereik in te sluiten, zodat deze buiten sessiecode toegankelijk zijn. De Using bereikaanpassing wordt ondersteund in de volgende contexten:

  • Extern uitgevoerde opdrachten, gestart met Invoke-Command de parameters ComputerName, HostName, SSHConnection of Sessie (externe sessie)
  • Achtergrondtaken, gestart met Start-Job (out-of-process sessie)
  • Threadtaken, gestart via Start-ThreadJob of ForEach-Object -Parallel (afzonderlijke threadsessie)

Afhankelijk van de context zijn ingesloten variabelewaarden onafhankelijke kopieën van de gegevens in het bereik van de aanroeper of verwijzingen ernaar. In externe en out-of-process sessies zijn het altijd onafhankelijke kopieën.

Zie about_Remote_Variables voor meer informatie.

In threadsessies worden ze doorgegeven door verwijzing. Dit betekent dat het mogelijk is om aanroepbereikvariabelen in een andere thread te wijzigen. Als u variabelen veilig wilt wijzigen, is threadsynchronisatie vereist.

Zie voor meer informatie:

Serialisatie van variabelewaarden

Extern uitgevoerde opdrachten en achtergrondtaken zijn verlopen. Out-of-process sessies maken gebruik van serialisatie en deserialisatie op basis van XML om de waarden van variabelen beschikbaar te maken over de procesgrenzen heen. Tijdens het serialisatieproces worden objecten geconverteerd naar een PSObject dat de oorspronkelijke eigenschappen van objecten bevat, maar niet de bijbehorende methoden.

Voor een beperkte set typen rehydrateerd deserialisatie objecten terug naar het oorspronkelijke type. Het gerehydrateerde object is een kopie van het oorspronkelijke objectexemplaar. Het heeft de eigenschappen en methoden van het type. Voor eenvoudige typen, zoals System.Version, is de kopie exact. Voor complexe typen is de kopie onvolmaakt. Gerehydrateerde certificaatobjecten bevatten bijvoorbeeld niet de persoonlijke sleutel.

Exemplaren van alle andere typen zijn PSObject-exemplaren . De eigenschap PSTypeNames bevat de oorspronkelijke typenaam voorafgegaan door Deserialized, bijvoorbeeld Deserialized.System.Data.DataTable

De optie AllScope

Variabelen en aliassen hebben een eigenschap Option die de waarde AllScope kan aannemen. Items met de eigenschap AllScope worden onderdeel van alle onderliggende bereiken die u maakt, hoewel ze niet met terugwerkende kracht worden overgenomen door bovenliggende bereiken.

Een item met de eigenschap AllScope is zichtbaar in het onderliggende bereik en maakt deel uit van dat bereik. Wijzigingen in het item in een bereik zijn van invloed op alle bereiken waarin de variabele is gedefinieerd.

Bereik beheren

Verschillende cmdlets hebben een bereikparameter waarmee u items in een bepaald bereik kunt ophalen of instellen (maken en wijzigen). Gebruik de volgende opdracht om alle cmdlets in uw sessie te zoeken die een bereikparameter hebben:

Get-Help * -Parameter scope

Als u de variabelen wilt zoeken die zichtbaar zijn in een bepaald bereik, gebruikt u de Scope parameter van Get-Variable. De zichtbare variabelen omvatten globale variabelen, variabelen in het bovenliggende bereik en variabelen in het huidige bereik.

Met de volgende opdracht worden bijvoorbeeld de variabelen ophaalt die zichtbaar zijn in het lokale bereik:

Get-Variable -Scope local

Als u een variabele in een bepaald bereik wilt maken, gebruikt u een bereikaanpassing of de bereikparameter van Set-Variable. Met de volgende opdracht maakt u een variabele in het globale bereik:

New-Variable -Scope global -Name a -Value "One"

U kunt ook de parameter Bereik van de New-Aliascmdlets , Set-Aliasof Get-Alias gebruiken om het bereik op te geven. Met de volgende opdracht maakt u een alias in het globale bereik:

New-Alias -Scope global -Name np -Value Notepad.exe

Als u de functies in een bepaald bereik wilt ophalen, gebruikt u de Get-Item cmdlet wanneer u zich in het bereik bevindt. De Get-Item cmdlet heeft geen bereikparameter .

Notitie

Voor de cmdlets die gebruikmaken van de parameter Bereik , kunt u ook naar bereiken verwijzen op getal. Het getal beschrijft de relatieve positie van het ene bereik naar het andere. Bereik 0 vertegenwoordigt het huidige of lokale bereik. Bereik 1 geeft het directe bovenliggende bereik aan. Bereik 2 geeft het bovenliggende bereik van het bovenliggende bereik aan, enzovoort. Genummerde bereiken zijn handig als u veel recursieve bereiken hebt gemaakt.

Puntbronnotatie gebruiken met bereik

Scripts en functies volgen alle regels van het bereik. U maakt ze in een bepaald bereik en ze zijn alleen van invloed op dat bereik, tenzij u een cmdlet-parameter of een bereikwijziging gebruikt om dat bereik te wijzigen.

U kunt echter een script of functie toevoegen aan het huidige bereik met behulp van de puntbronnotatie. Wanneer een script vervolgens wordt uitgevoerd in het huidige bereik, zijn alle functies, aliassen en variabelen die door het script worden gemaakt, beschikbaar in het huidige bereik.

Als u een functie wilt toevoegen aan het huidige bereik, typt u een punt (.) en een spatie vóór het pad en de naam van de functie in de functie-aanroep.

Als u bijvoorbeeld het Sample.ps1-script wilt uitvoeren vanuit de map C:\Scripts in het scriptbereik (de standaardinstelling voor scripts), gebruikt u de volgende opdracht:

c:\scripts\sample.ps1

Gebruik de volgende opdracht om het script Sample.ps1 uit te voeren in het lokale bereik:

. c:\scripts.sample.ps1

Wanneer u de aanroepoperator (&) gebruikt om een functie of script uit te voeren, wordt deze niet toegevoegd aan het huidige bereik. In het volgende voorbeeld wordt de aanroepoperator gebruikt:

& c:\scripts.sample.ps1

Meer informatie over de oproepoperator vindt u in about_operators.

Aliassen, functies of variabelen die door het Sample.ps1 script worden gemaakt, zijn niet beschikbaar in het huidige bereik.

Beperken zonder bereik

Enkele PowerShell-concepten zijn vergelijkbaar met bereik of interactie met bereik. Deze concepten kunnen worden verward met het bereik of het gedrag van het bereik.

Sessies, modules en geneste prompts zijn zelfstandige omgevingen, maar ze zijn geen onderliggende bereiken van het globale bereik in de sessie.

Sessies

Een sessie is een omgeving waarin PowerShell wordt uitgevoerd. Wanneer u een sessie op een externe computer maakt, maakt PowerShell een permanente verbinding met de externe computer. Met de permanente verbinding kunt u de sessie gebruiken voor meerdere gerelateerde opdrachten.

Omdat een sessie een ingesloten omgeving is, heeft deze een eigen bereik, maar een sessie is geen onderliggend bereik van de sessie waarin deze is gemaakt. De sessie begint met een eigen globaal bereik. Dit bereik is onafhankelijk van het globale bereik van de sessie. U kunt onderliggende bereiken maken in de sessie. U kunt bijvoorbeeld een script uitvoeren om een onderliggend bereik in een sessie te maken.

Modules

U kunt een PowerShell-module gebruiken om PowerShell-hulpprogramma's te delen en te leveren. Een module is een eenheid die cmdlets, scripts, functies, variabelen, aliassen en andere nuttige items kan bevatten. Tenzij expliciet gedefinieerd, zijn de items in een module niet toegankelijk buiten de module. Daarom kunt u de module toevoegen aan uw sessie en de openbare items gebruiken zonder dat u zich zorgen hoeft te maken dat de andere items de cmdlets, scripts, functies en andere items in uw sessie kunnen overschrijven.

Modules worden standaard geladen op het hoogste niveau van de huidige sessiestatus , niet in het huidige bereik. De huidige sessiestatus kan een modulesessiestatus of de globale sessiestatus zijn. Als u een module toevoegt aan een sessie, wordt het bereik niet gewijzigd. Als u zich in het globale bereik bevindt, worden modules geladen in de globale sessiestatus. Alle exports worden in de globale tabellen geplaatst. Als u module2 laadt vanuit module1, wordt module2 geladen in de sessiestatus van module1 en niet in de globale sessiestatus. Exports van module2 worden boven aan de sessiestatus van module1 geplaatst. Als u gebruikt Import-Module -Scope local, worden de exports in het huidige bereikobject geplaatst in plaats van op het hoogste niveau. Als u zich in een module bevindt en (of Import-Module -Global) gebruikt Import-Module -Scope global om een andere module te laden, worden die module en de exports ervan geladen in de globale sessiestatus in plaats van de lokale sessiestatus van de module. Deze functie is ontworpen voor het schrijven van modules waarmee modules worden bewerkt. De WindowsCompatibility-module doet dit om proxymodules te importeren in de globale sessiestatus.

Binnen de sessiestatus hebben modules hun eigen bereik. Bekijk de volgende module C:\temp\mod1.psm1:

$a = "Hello"

function foo {
    "`$a = $a"
    "`$global:a = $global:a"
}

Nu maken we een globale variabele $a, geef deze een waarde en roepen we de functie foo aan.

$a = "Goodbye"
foo

De module declareert de variabele $a in het modulebereik, waarna de functie foo de waarde van de variabele in beide bereiken uitvoert.

$a = Hello
$global:a = Goodbye

Geneste prompts

Geneste prompts hebben geen eigen bereik. Wanneer u een geneste prompt invoert, is de geneste prompt een subset van de omgeving. Maar u blijft binnen het lokale bereik.

Scripts hebben hun eigen bereik. Als u fouten in een script opspoort en u een onderbrekingspunt in het script bereikt, voert u het scriptbereik in.

Privéoptie

Aliassen en variabelen hebben een eigenschap Option die de waarde Privé kan aannemen. Items met de optie Privé kunnen worden weergegeven en gewijzigd in het bereik waarin ze worden gemaakt, maar ze kunnen niet worden weergegeven of gewijzigd buiten dat bereik.

Als u bijvoorbeeld een variabele maakt met een privéoptie in het globale bereik en vervolgens een script uitvoert, Get-Variable wordt de privévariabele niet weergegeven in opdrachten in het script. Als u de wijzigingsfunctie voor het globale bereik in dit exemplaar gebruikt, wordt de privévariabele niet weergegeven.

U kunt de parameter Option van de New-Variablecmdlets , Set-Variable, New-Aliasen Set-Alias gebruiken om de waarde van de eigenschap Option in te stellen op Privé.

Zichtbaarheid

De eigenschap Zichtbaarheid van een variabele of alias bepaalt of u het item kunt zien buiten de container waarin het is gemaakt. Een container kan een module, script of module zijn. Zichtbaarheid is op dezelfde manier ontworpen voor containers als de privéwaarde van de eigenschap Option voor bereiken.

Voor de eigenschap Zichtbaarheid worden de waarden Openbaar en Privé gebruikt. Items met persoonlijke zichtbaarheid kunnen alleen worden weergegeven en gewijzigd in de container waarin ze zijn gemaakt. Als de container wordt toegevoegd of geïmporteerd, kunnen de items met persoonlijke zichtbaarheid niet worden weergegeven of gewijzigd.

Omdat zichtbaarheid is ontworpen voor containers, werkt het anders in een bereik.

  • Als u een item maakt met persoonlijke zichtbaarheid in het globale bereik, kunt u het item in geen enkel bereik weergeven of wijzigen.
  • Als u probeert de waarde van een variabele met persoonlijke zichtbaarheid weer te geven of te wijzigen, retourneert PowerShell een foutbericht.

U kunt de New-Variable cmdlets en Set-Variable gebruiken om een variabele te maken met persoonlijke zichtbaarheid.

Voorbeelden

Voorbeeld 1: alleen een variabelewaarde wijzigen in een script

Met de volgende opdracht wordt de waarde van de $ConfirmPreference variabele in een script gewijzigd. De wijziging heeft geen invloed op het globale bereik.

Gebruik eerst de volgende opdracht om de waarde van de $ConfirmPreference variabele in het lokale bereik weer te geven:

PS>  $ConfirmPreference
High

Creatie een Scope.ps1 script dat de volgende opdrachten bevat:

$ConfirmPreference = "Low"
"The value of `$ConfirmPreference is $ConfirmPreference."

Voer het script uit. Het script wijzigt de waarde van de $ConfirmPreference variabele en rapporteert vervolgens de waarde ervan in het scriptbereik. De uitvoer moet er ongeveer als volgt uitzien:

The value of $ConfirmPreference is Low.

Test vervolgens de huidige waarde van de $ConfirmPreference variabele in het huidige bereik.

PS>  $ConfirmPreference
High

In dit voorbeeld ziet u dat wijzigingen in de waarde van een variabele in het scriptbereik geen invloed hebben op de waarde van de variabele in het bovenliggende bereik.

Voorbeeld 2: een variabelewaarde in verschillende bereiken weergeven

U kunt bereikaanpassingen gebruiken om de waarde van een variabele in het lokale bereik en in een bovenliggend bereik weer te geven.

Definieer eerst een $test variabele in het globale bereik.

$test = "Global"

Maak vervolgens een Sample.ps1 script waarmee de $test variabele wordt gedefinieerd. Gebruik in het script een bereikaanpassing om te verwijzen naar de globale of lokale versies van de $test variabele.

In Sample.ps1:

$test = "Local"
"The local value of `$test is $test."
"The global value of `$test is $global:test."

Wanneer u Sample.ps1 uitvoert, moet de uitvoer er ongeveer als volgt uitzien:

The local value of $test is Local.
The global value of $test is Global.

Wanneer het script is voltooid, wordt alleen de globale waarde van $test gedefinieerd in de sessie.

PS>  $test
Global

Voorbeeld 3: de waarde van een variabele in een bovenliggend bereik wijzigen

Tenzij u een item beveiligt met de optie Privé of een andere methode, kunt u de waarde van een variabele in een bovenliggend bereik weergeven en wijzigen.

Definieer eerst een $test variabele in het globale bereik.

$test = "Global"

Maak vervolgens een Sample.ps1 script waarmee de $test variabele wordt gedefinieerd. Gebruik in het script een bereikaanpassing om te verwijzen naar de globale of lokale versies van de $test variabele.

In Sample.ps1:

$global:test = "Local"
"The global value of `$test is $global:test."

Wanneer het script is voltooid, wordt de globale waarde van $test gewijzigd.

PS>  $test
Local

Voorbeeld 4: een privévariabele maken

Een privévariabele is een variabele met de eigenschap Option met de waarde Privé. Privévariabelen worden overgenomen door het onderliggende bereik, maar ze kunnen alleen worden weergegeven of gewijzigd in het bereik waarin ze zijn gemaakt.

Met de volgende opdracht maakt u een privévariabele met de naam $ptest in het lokale bereik.

New-Variable -Name ptest -Value 1 -Option private

U kunt de waarde van $ptest weergeven en wijzigen in het lokale bereik.

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

Maak vervolgens een Sample.ps1 script dat de volgende opdrachten bevat. Met de opdracht wordt geprobeerd de waarde van $ptestweer te geven en te wijzigen.

In Sample.ps1:

"The value of `$Ptest is $Ptest."
"The value of `$Ptest is $global:Ptest."

De $ptest variabele is niet zichtbaar in het scriptbereik, de uitvoer is leeg.

"The value of $Ptest is ."
"The value of $Ptest is ."

Voorbeeld 5: Een lokale variabele gebruiken in een externe opdracht

Voor variabelen in een externe opdracht die is gemaakt in de lokale sessie, gebruikt u de Using bereikaanpassing. PowerShell gaat ervan uit dat de variabelen in externe opdrachten zijn gemaakt in de externe sessie.

De syntaxis is:

$Using:<VariableName>

Met de volgende opdrachten maakt u bijvoorbeeld een $Cred variabele in de lokale sessie en gebruikt u vervolgens de $Cred variabele in een externe opdracht:

$Cred = Get-Credential
Invoke-Command $s {Remove-Item .\Test*.ps1 -Credential $Using:Cred}

Het bereik Using is geïntroduceerd in PowerShell 3.0. Gebruik in PowerShell 2.0 de volgende opdrachtindeling om aan te geven dat er een variabele is gemaakt in de lokale sessie.

$Cred = Get-Credential
Invoke-Command $s {
  param($c)
  Remove-Item .\Test*.ps1 -Credential $c
} -ArgumentList $Cred

Zie ook