about_Scopes

Krótki opis

Wyjaśnia koncepcję zakresu w programie PowerShell i pokazuje, jak ustawić i zmienić zakres elementów.

Długi opis

Program PowerShell chroni dostęp do zmiennych, aliasów, funkcji i dysków programu PowerShell (PSDrive), ograniczając miejsce ich odczytu i zmiany. Program PowerShell używa reguł zakresu w celu zapewnienia, że nie można przypadkowo zmienić elementu, który nie powinien być zmieniany.

Poniżej przedstawiono podstawowe reguły zakresu:

  • Zakresy mogą być zagnieżdżone. Zakres zewnętrzny jest określany jako zakres nadrzędny. Wszystkie zagnieżdżone zakresy są zakresami podrzędnym tego elementu nadrzędnego.

  • Element jest widoczny w zakresie, w którym został utworzony, i we wszystkich zakresach podrzędnych, chyba że jawnie go udostępnisz jako prywatny.

  • Zmienne, aliasy, funkcje i dyski programu PowerShell można deklarować w zakresie poza bieżącym zakresem.

  • Element utworzony w ramach zakresu można zmienić tylko w zakresie, w którym został utworzony, chyba że jawnie określisz inny zakres.

Jeśli tworzysz element w zakresie, a jego nazwa jest udostępniana elementowi w innym zakresie, oryginalny element może być ukryty pod nowym elementem, ale nie zostanie zastąpiony ani zmieniony.

Zakresy programu PowerShell

Program PowerShell obsługuje następujące zakresy:

  • Globalny: zakres, który dzieje się podczas uruchamiania programu PowerShell lub tworzenia nowej sesji lub przestrzeni uruchamiania. Zmienne i funkcje, które są obecne podczas uruchamiania programu PowerShell, zostały utworzone w zakresie globalnym, takim jak zmienne automatyczne i zmienne preferencji. Zmienne, aliasy i funkcje w profilach programu PowerShell są również tworzone w zakresie globalnym. Zakres globalny jest zakresem nadrzędnym katalogu głównego w sesji.

  • Lokalne: bieżący zakres. Zakres lokalny może być zakresem globalnym lub dowolnym innym zakresem.

  • Skrypt: zakres, który jest tworzony podczas uruchamiania pliku skryptu. Tylko polecenia w skrypcie są uruchamiane w zakresie skryptu. W przypadku poleceń w skrypcie zakres skryptu jest zakresem lokalnym.

Uwaga

Prywatna nie jest zakresem. Jest to opcja, która zmienia widoczność elementu poza zakresem, w którym element jest zdefiniowany.

Zakresy nadrzędny i podrzędny

Nowy zakres podrzędny można utworzyć, wywołując skrypt lub funkcję. Zakres wywołujący jest zakresem nadrzędnym. Wywoływany skrypt lub funkcja jest zakresem podrzędnym. Wywołania funkcji lub skryptów mogą wywołać inne funkcje, tworząc hierarchię zakresów podrzędnych, których zakres główny jest zakresem globalnym.

O ile jawnie nie udostępnisz elementów jako prywatnych, elementy w zakresie nadrzędnym będą dostępne dla zakresu podrzędnego. Jednak elementy, które tworzysz i zmieniasz w zakresie podrzędnym, nie wpływają na zakres nadrzędny, chyba że jawnie określisz zakres podczas tworzenia elementów.

Uwaga

Funkcje z modułu nie są uruchamiane w zakresie podrzędnym zakresu wywołującego. Moduły mają własny stan sesji połączony z zakresem globalnym. Cały kod modułu jest uruchamiany w hierarchii zakresów specyficznych dla modułu, która ma własny zakres główny.

Dziedziczenie

Zakres podrzędny nie dziedziczy zmiennych, aliasów i funkcji z zakresu nadrzędnego. Jeśli element nie jest prywatny, zakres podrzędny może wyświetlać elementy w zakresie nadrzędnym. Można również zmieniać elementy, jawnie określając zakres nadrzędny, ale elementy nie są częścią zakresu podrzędnego.

Jednak zakres podrzędny jest tworzony z zestawem elementów. Zazwyczaj zawiera ona wszystkie aliasy, które mają opcję AllScope . Ta opcja jest omówiona w dalszej części tego artykułu. Zawiera on wszystkie zmienne, które mają opcję AllScope , oraz niektóre zmienne automatyczne.

Aby znaleźć elementy w określonym zakresie, użyj parametru Scope lub Get-Variable Get-Alias.

Aby na przykład pobrać wszystkie zmienne w zakresie lokalnym, wpisz:

Get-Variable -Scope local

Aby pobrać wszystkie zmienne w zakresie globalnym, wpisz:

Get-Variable -Scope global

Modyfikatory zakresu

Zmienna, alias lub nazwa funkcji może zawierać dowolny z następujących modyfikatorów zakresu opcjonalnego:

  • global: - Określa, że nazwa istnieje w zakresie globalnym .

  • local: - Określa, że nazwa istnieje w zakresie lokalnym . Bieżący zakres to zawsze zakres lokalny .

  • private: - Określa, że nazwa ma wartość Prywatny i jest widoczna tylko dla bieżącego zakresu.

  • script: - Określa, że nazwa istnieje w zakresie skryptu . Zakres skryptu to zakres najbliższego nadrzędnego pliku skryptu lub globalny, jeśli nie ma najbliższego pliku skryptu nadrzędnego.

  • using: - Służy do uzyskiwania dostępu do zmiennych zdefiniowanych w innym zakresie podczas uruchamiania skryptów za pośrednictwem polecenia cmdlet, takich jak Start-Job i Invoke-Command.

  • workflow: - Określa, że nazwa istnieje w przepływie pracy. Uwaga: przepływy pracy nie są obsługiwane w programie PowerShell w wersji 6 i wyższych.

  • <variable-namespace> — modyfikator utworzony przez dostawcę programu PowerShell PSDrive. Na przykład:

    Przestrzeń nazw Opis
    Alias: Aliasy zdefiniowane w bieżącym zakresie
    Env: Zmienne środowiskowe zdefiniowane w bieżącym zakresie
    Function: Funkcje zdefiniowane w bieżącym zakresie
    Variable: Zmienne zdefiniowane w bieżącym zakresie

Domyślnym zakresem skryptów jest zakres skryptu. Domyślnym zakresem funkcji i aliasów jest zakres lokalny, nawet jeśli są one zdefiniowane w skrypcie.

Używanie modyfikatorów zakresu

Aby określić zakres nowej zmiennej, aliasu lub funkcji, użyj modyfikatora zakresu.

Składnia modyfikatora zakresu w zmiennej jest następująca:

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

Składnia modyfikatora zakresu w funkcji jest następująca:

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

Następujące polecenie, które nie używa modyfikatora zakresu, tworzy zmienną w bieżącym lub lokalnym zakresie :

$a = "one"

Aby utworzyć tę samą zmienną w zakresie globalnym , użyj modyfikatora global: zakresu:

$global:a = "one"

Aby utworzyć tę samą zmienną w zakresie skryptu , użyj modyfikatora script: zakresu:

$script:a = "one"

Można również użyć modyfikatora zakresu z funkcjami. Następująca definicja funkcji tworzy funkcję w zakresie globalnym :

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

Modyfikatory zakresu mogą również odwoływać się do zmiennej w innym zakresie. Następujące polecenie odwołuje się do zmiennej $test , najpierw w zakresie lokalnym, a następnie w zakresie globalnym:

$test
$global:test

Modyfikator Using: zakresu

Przy użyciu jest specjalnym modyfikatorem zakresu, który identyfikuje zmienną lokalną w poleceniu zdalnym. Bez modyfikatora program PowerShell oczekuje, że zmienne w poleceniach zdalnych zostaną zdefiniowane w sesji zdalnej.

Modyfikator Using zakresu został wprowadzony w programie PowerShell 3.0.

W przypadku dowolnego skryptu lub polecenia, które jest wykonywane poza sesją, potrzebny jest modyfikator zakresu, Using aby osadzić wartości zmiennych z zakresu sesji wywołującej, aby kod poza sesją był w stanie uzyskać do nich dostęp. Modyfikator Using zakresu jest obsługiwany w następujących kontekstach:

  • Zdalnie wykonywane polecenia rozpoczęte przy Invoke-Command użyciu parametrów ComputerName, HostName, SSHConnection lub Session (sesja zdalna)
  • Zadania w tle, rozpoczęte z Start-Job (sesja poza procesem)
  • Zadania wątków uruchomione za pośrednictwem lub Start-ThreadJob ForEach-Object -Parallel (oddzielna sesja wątku)

W zależności od kontekstu osadzone wartości zmiennych są niezależnymi kopiami danych w zakresie obiektu wywołującego lub odwołaniami do niego. W sesjach zdalnych i poza procesami są one zawsze niezależnymi kopiami.

Aby uzyskać więcej informacji, zobacz about_Remote_Variables.

W sesjach wątków są one przekazywane przez odwołanie. Oznacza to, że istnieje możliwość modyfikowania zmiennych zakresu wywołań w innym wątku. Bezpieczne modyfikowanie zmiennych wymaga synchronizacji wątków.

Aby uzyskać więcej informacji, zobacz:

Serializacja wartości zmiennych

Zdalnie wykonywane polecenia i zadania w tle są wykonywane poza procesem. Sesje poza procesem używają serializacji i deserializacji opartej na formacie XML, aby udostępnić wartości zmiennych w granicach procesu. Proces serializacji konwertuje obiekty do obiektu PSObject , który zawiera właściwości oryginalnych obiektów, ale nie jego metody.

W przypadku ograniczonego zestawu typów deserializacja ponownie nawrócą obiekty do oryginalnego typu. Obiekt z ponownego nawodnienia jest kopią oryginalnego wystąpienia obiektu. Ma właściwości typu i metody. W przypadku prostych typów, takich jak System.Version, kopia jest dokładna. W przypadku typów złożonych kopia jest niedoskonała. Na przykład ponownie pozysane obiekty certyfikatów nie zawierają klucza prywatnego.

Wystąpienia wszystkich innych typów są wystąpieniami obiektu PSObject . Właściwość PSTypeNames zawiera oryginalną nazwę typu poprzedzoną prefiksem Deserialized, na przykład Deserialized.System.Data.DataTable

Opcja AllScope

Zmienne i aliasy mają właściwość Option , która może przyjmować wartość AllScope. Elementy, które mają właściwość AllScope stają się częścią wszystkich tworzyć zakresy podrzędne, chociaż nie są wstecznie dziedziczone przez zakresy nadrzędne.

Element, który ma właściwość AllScope , jest widoczny w zakresie podrzędnym i jest częścią tego zakresu. Zmiany elementu w dowolnym zakresie mają wpływ na wszystkie zakresy, w których zdefiniowano zmienną.

Zarządzanie zakresem

Kilka polecenia cmdlet mają parametr Scope , który umożliwia uzyskiwanie lub ustawianie (tworzenie i zmienianie) elementów w określonym zakresie. Użyj następującego polecenia, aby znaleźć wszystkie polecenia cmdlet w sesji, które mają parametr Scope :

Get-Help * -Parameter scope

Aby znaleźć zmienne widoczne w określonym zakresie, użyj parametru Scope Get-Variable. Widoczne zmienne obejmują zmienne globalne, zmienne w zakresie nadrzędnym i zmienne w bieżącym zakresie.

Na przykład następujące polecenie pobiera zmienne, które są widoczne w zakresie lokalnym:

Get-Variable -Scope local

Aby utworzyć zmienną w określonym zakresie, użyj modyfikatora zakresu lub parametru Scope .Set-Variable Następujące polecenie tworzy zmienną w zakresie globalnym:

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

Można również użyć zakresu parametru New-Alias, Set-Aliaslub Get-Alias polecenia cmdlet, aby określić zakres. Następujące polecenie tworzy alias w zakresie globalnym:

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

Aby uzyskać funkcje w określonym zakresie, użyj Get-Item polecenia cmdlet , gdy jesteś w zakresie. Polecenie Get-Item cmdlet nie ma parametru Scope .

Uwaga

W przypadku polecenia cmdlet, które używają parametru Scope , można również odwoływać się do zakresów według liczby. Liczba opisuje względne położenie jednego zakresu do innego. Zakres 0 reprezentuje bieżący lub lokalny zakres. Zakres 1 wskazuje bezpośredni zakres nadrzędny. Zakres 2 wskazuje element nadrzędny zakresu nadrzędnego i tak dalej. Zakresy numerowane są przydatne, jeśli utworzono wiele zakresów cyklicznych.

Używanie notacji źródła kropki z zakresem

Skrypty i funkcje są zgodne ze wszystkimi regułami zakresu. Tworzysz je w określonym zakresie i mają one wpływ tylko na ten zakres, chyba że do zmiany tego zakresu używasz parametru polecenia cmdlet lub modyfikatora zakresu.

Można jednak dodać skrypt lub funkcję do bieżącego zakresu przy użyciu notacji źródła kropki. Następnie, gdy skrypt jest uruchamiany w bieżącym zakresie, wszystkie funkcje, aliasy i zmienne, które tworzy skrypt, są dostępne w bieżącym zakresie.

Aby dodać funkcję do bieżącego zakresu, wpisz kropkę (.) i spację przed ścieżką i nazwą funkcji w wywołaniu funkcji.

Aby na przykład uruchomić skrypt Sample.ps1 katalogu C:\Scripts w zakresie skryptu (wartość domyślna dla skryptów), użyj następującego polecenia:

c:\scripts\sample.ps1

Aby uruchomić skrypt Sample.ps1 w zakresie lokalnym, użyj następującego polecenia:

. c:\scripts.sample.ps1

Gdy używasz operatora wywołań (&) do uruchamiania funkcji lub skryptu, nie jest on dodawany do bieżącego zakresu. W poniższym przykładzie użyto operatora wywołania :

& c:\scripts.sample.ps1

Więcej informacji na temat operatora wywołań można znaleźć w about_operators.

Wszelkie aliasy, funkcje lub zmienne, które tworzy Sample.ps1 skrypt, nie są dostępne w bieżącym zakresie.

Ograniczanie bez zakresu

Kilka pojęć dotyczących programu PowerShell jest podobnych do zakresu lub interakcji z zakresem. Te pojęcia mogą być mylone z zakresem lub zachowaniem zakresu.

Sesje, moduły i monity zagnieżdżone są środowiskami samodzielnym, ale nie są one zakresami podrzędnym zakresu globalnego w sesji.

Sesje

Sesja to środowisko, w którym działa program PowerShell. Podczas tworzenia sesji na komputerze zdalnym program PowerShell ustanawia trwałe połączenie z komputerem zdalnym. Połączenie trwałe umożliwia używanie sesji dla wielu powiązanych poleceń.

Ponieważ sesja jest środowiskiem zawartym, ma własny zakres, ale sesja nie jest zakresem podrzędnym sesji, w której została utworzona. Sesja rozpoczyna się od własnego zakresu globalnego. Ten zakres jest niezależny od globalnego zakresu sesji. Zakresy podrzędne można tworzyć w sesji. Na przykład można uruchomić skrypt, aby utworzyć zakres podrzędny w sesji.

Moduły

Moduł programu PowerShell umożliwia udostępnianie i dostarczanie narzędzi programu PowerShell. Moduł to jednostka, która może zawierać polecenia cmdlet, skrypty, funkcje, zmienne, aliasy i inne przydatne elementy. Jeśli elementy w module nie są jawnie zdefiniowane, nie są dostępne poza modułem. W związku z tym możesz dodać moduł do sesji i używać elementów publicznych bez obaw, że inne elementy mogą zastąpić polecenia cmdlet, skrypty, funkcje i inne elementy w sesji.

Domyślnie moduły są ładowane do najwyższego poziomu bieżącego stanu sesji, a nie bieżącego zakresu. Bieżący stan sesji może być stanem sesji modułu lub stanem sesji globalnej. Dodanie modułu do sesji nie zmienia zakresu. Jeśli jesteś w zakresie globalnym, moduły są ładowane do stanu sesji globalnej. Wszystkie eksporty są umieszczane w tabelach globalnych. W przypadku załadowania modułu module2 z modułu module1 moduł module2 jest ładowany do stanu sesji modułu module1, a nie do stanu sesji globalnej. Wszystkie eksporty z modułu module2 są umieszczane w górnej części stanu sesji modułu module1. Jeśli używasz obiektu Import-Module -Scope local, eksporty są umieszczane w bieżącym obiekcie zakresu, a nie na najwyższym poziomie. Jeśli jesteś w module i używasz (lub ) do załadowania innego modułu, ten moduł i jego eksporty są ładowane do stanu sesji globalnej, a Import-Module -Scope global Import-Module -Globalnie do stanu sesji lokalnej modułu. Ta funkcja została zaprojektowana do pisania modułu, który manipuluje modułami. Moduł WindowsCompatibility umożliwia importowanie modułów serwera proxy do stanu sesji globalnej.

W stanie sesji moduły mają własny zakres. Rozważmy następujący moduł C:\temp\mod1.psm1:

$a = "Hello"

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

Teraz utworzymy zmienną globalną $a, nadamy jej wartość i wywołamy funkcję foo.

$a = "Goodbye"
foo

Moduł deklaruje zmienną w $a zakresie modułu, a następnie funkcja foo wyprowadza wartość zmiennej w obu zakresach.

$a = Hello
$global:a = Goodbye

Monity zagnieżdżone

Monity zagnieżdżone nie mają własnego zakresu. Po wprowadzeniu monitu zagnieżdżony monit jest podzbiorem środowiska. Pozostaniesz jednak w zakresie lokalnym.

Skrypty mają własny zakres. Jeśli podczas debugowania skryptu dotrzesz do punktu przerwania w skrypcie, wprowadź zakres skryptu.

Opcja prywatna

Aliasy i zmienne mają właściwość Option , która może przyjmować wartość Private. Elementy z opcją Prywatny można wyświetlać i zmieniać w zakresie, w którym zostały utworzone, ale nie można ich wyświetlać ani zmieniać poza tym zakresem.

Jeśli na przykład utworzysz zmienną, która ma opcję prywatną w zakresie globalnym, a następnie uruchamiasz skrypt, Get-Variable polecenia w skrypcie nie będą wyświetlać zmiennej prywatnej. Użycie modyfikatora zakresu globalnego w tym wystąpieniu nie powoduje wyświetlenia zmiennej prywatnej.

Aby ustawić wartość właściwości Option na New-VariablePrivate, można użyć parametru Option polecenia cmdlet , Set-Variable, New-Alias``Set-Alias i .

Widoczność

Właściwość Visibility zmiennej lub aliasu określa, czy element jest widoczny poza kontenerem, w którym został utworzony. Kontenerem może być moduł, skrypt lub przystawka. Widoczność jest przeznaczona dla kontenerów w taki sam sposób, jak wartość Private właściwości Option dla zakresów.

Właściwość Widoczność przyjmuje wartości Publiczne i Prywatne. Elementy z widocznością prywatną można wyświetlać i zmieniać tylko w kontenerze, w którym zostały utworzone. Jeśli kontener zostanie dodany lub zaimportowany, nie będzie można wyświetlać ani zmieniać elementów z widocznością prywatną.

Ponieważ widoczność jest przeznaczona dla kontenerów, działa inaczej w zakresie.

  • Jeśli tworzysz element, który ma widoczność prywatną w zakresie globalnym, nie możesz wyświetlić ani zmienić elementu w żadnym zakresie.
  • Jeśli spróbujesz wyświetlić lub zmienić wartość zmiennej o widoczności prywatnej, program PowerShell zwróci komunikat o błędzie.

Za pomocą polecenia New-Variable cmdlet i Set-Variable można utworzyć zmienną o widoczności prywatnej.

Przykłady

Przykład 1: zmiana wartości zmiennej tylko w skrypcie

Następujące polecenie zmienia wartość zmiennej w $ConfirmPreference skrypcie. Zmiana nie ma wpływu na zakres globalny.

Najpierw, aby wyświetlić wartość zmiennej w $ConfirmPreference zakresie lokalnym, użyj następującego polecenia:

PS>  $ConfirmPreference
High

Utwórz skrypt Scope.ps1, który zawiera następujące polecenia:

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

Uruchom skrypt. Skrypt zmienia wartość zmiennej, a $ConfirmPreference następnie raportuje jej wartość w zakresie skryptu. Dane wyjściowe powinny wyglądać następująco:

The value of $ConfirmPreference is Low.

Następnie przetestuj bieżącą wartość zmiennej $ConfirmPreference w bieżącym zakresie.

PS>  $ConfirmPreference
High

W tym przykładzie pokazano, że zmiany wartości zmiennej w zakresie skryptu nie wpływają na wartość zmiennej w zakresie nadrzędnym.

Przykład 2: Wyświetlanie wartości zmiennej w różnych zakresach

Modyfikatory zakresu mogą być służące do wyświetlania wartości zmiennej w zakresie lokalnym i w zakresie nadrzędnym.

Najpierw zdefiniuj $test zmienną w zakresie globalnym.

$test = "Global"

Następnie utwórz skrypt Sample.ps1, który definiuje zmienną $test . W skrypcie użyj modyfikatora zakresu, aby odwołać się do globalnej lub lokalnej wersji zmiennej $test .

W Sample.ps1:

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

Po uruchomieniu Sample.ps1 dane wyjściowe powinny przypominać następujące dane wyjściowe:

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

Po zakończeniu wykonywania skryptu w $test sesji jest definiowana tylko wartość globalna .

PS>  $test
Global

Przykład 3: zmiana wartości zmiennej w zakresie nadrzędnym

O ile nie chronisz elementu za pomocą opcji Private lub innej metody, możesz wyświetlić i zmienić wartość zmiennej w zakresie nadrzędnym.

Najpierw zdefiniuj $test zmienną w zakresie globalnym.

$test = "Global"

Następnie utwórz skrypt Sample.ps1, który definiuje zmienną $test . W skrypcie użyj modyfikatora zakresu, aby odwołać się do globalnej lub lokalnej wersji zmiennej $test .

W Sample.ps1:

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

Po zakończeniu wykonywania skryptu globalna wartość jest $test zmieniana.

PS>  $test
Local

Przykład 4. Tworzenie zmiennej prywatnej

Zmienna prywatna to zmienna, która ma właściwość Option o wartości Private. Zmienne prywatne są dziedziczone przez zakres podrzędny, ale można je wyświetlać lub zmieniać tylko w zakresie, w którym zostały utworzone.

Następujące polecenie tworzy zmienną prywatną o nazwie $ptest w zakresie lokalnym.

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

Można wyświetlić i zmienić wartość w $ptest zakresie lokalnym.

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

Następnie utwórz skrypt Sample.ps1, który zawiera następujące polecenia. Polecenie próbuje wyświetlić i zmienić wartość $ptest.

W Sample.ps1:

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

Zmienna $ptest nie jest widoczna w zakresie skryptu, a dane wyjściowe są puste.

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

Przykład 5: Używanie zmiennej lokalnej w poleceniu zdalnym

Dla zmiennych w zdalnym poleceniu utworzonym w sesji lokalnej użyj modyfikatora Using zakresu. Program PowerShell zakłada, że zmienne w poleceniach zdalnych zostały utworzone w sesji zdalnej.

Składnia jest następująca:

$Using:<VariableName>

Na przykład następujące polecenia tworzą zmienną w sesji lokalnej, a $Cred następnie używają $Cred zmiennej w poleceniu zdalnym:

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

Zakres Using został wprowadzony w programie PowerShell 3.0. Aby w programie PowerShell 2.0 wskazać, że zmienna została utworzona w sesji lokalnej, użyj następującego formatu polecenia.

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

Zobacz też