Udostępnij za pośrednictwem


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 (PSDrives), ograniczając miejsce ich odczytywania i zmieniania. Program PowerShell używa reguł zakresu, aby upewnić się, że nie przypadkowo zmieniasz 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 to zakresy podrzędne tego elementu nadrzędnego.

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

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

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

Jeśli utworzysz element w zakresie, a element udostępni jego nazwę elementowi w innym zakresie, oryginalny element może być ukryty w nowym elemencie, ale nie zostanie zastąpiony ani zmieniony.

Zakresy programu PowerShell

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

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

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

  • Skrypt: zakres utworzony podczas uruchamiania pliku skryptu. Tylko polecenia w skrycie są uruchamiane w zakresie skryptu. Do poleceń w skrycie zakres skryptu jest zakresem lokalnym.

Uwaga

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

Zakresy nadrzędne i podrzędne

Możesz utworzyć nowy zakres podrzędny, wywołując skrypt lub funkcję. Zakres wywołania jest zakresem nadrzędnym. Wywoływany skrypt lub funkcja to zakres podrzędny. Wywoływane funkcje lub skrypty mogą wywoływać inne funkcje, tworząc hierarchię zakresów podrzędnych, których zakres główny jest zakresem globalnym.

Jeśli nie zostanie jawnie udostępnione elementy prywatne, elementy w zakresie nadrzędnym są dostępne dla zakresu podrzędnego. Jednak elementy tworzone i zmieniane w zakresie podrzędnym nie mają wpływu 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ływania. Moduły mają własny stan sesji połączony z zakresem globalnym. Cały kod modułu jest uruchamiany w hierarchii specyficznej dla modułu zakresów, które mają 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. Ponadto może zmienić 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 wszystkie aliasy, które mają opcję AllScope . Ta opcja zostanie omówiona w dalszej części tego artykułu. Zawiera wszystkie zmienne, które mają opcję AllScope , a także niektóre zmienne automatyczne.

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

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

Get-Variable -Scope local

Aby uzyskać wszystkie zmienne w zakresie globalnym, wpisz:

Get-Variable -Scope global

Modyfikatory zakresu

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

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

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

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

  • script: - Określa, że nazwa istnieje w zakresie skryptu . Zakres skryptu to zakres pliku skryptu najbliższego modułu ancestor lub globalny, jeśli nie ma najbliższego pliku skryptu programu ancestor.

  • using: — Służy do uzyskiwania dostępu do zmiennych zdefiniowanych w innym zakresie podczas uruchamiania skryptów za pomocą poleceń 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 nowszych.

  • <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 skrycie.

Używanie modyfikatorów zakresu

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

Składnia modyfikatora zakresu w zmiennej to:

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

Składnia modyfikatora zakresu w funkcji to:

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 zakresu global: :

$global:a = "one"

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

$script:a = "one"

Można również użyć modyfikatora zakresu z funkcjami. Poniższa definicja funkcji tworzy funkcję w zakresie globalnym :

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

Modyfikatory zakresu umożliwiają również odwoływanie 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

Using: Modyfikator zakresu

Using to specjalny modyfikator zakresu, który identyfikuje zmienną lokalną w zdalnym poleceniu. Bez modyfikatora program PowerShell oczekuje zmiennych w poleceniach zdalnych zdefiniowanych w sesji zdalnej.

Modyfikator Using zakresu jest wprowadzany w programie PowerShell 3.0.

W przypadku dowolnego skryptu lub polecenia wykonywanego poza sesją potrzebny jest Using modyfikator zakresu do osadzania wartości zmiennych z zakresu sesji wywołującej, dzięki czemu kod sesji poza sesją może uzyskiwać do nich dostęp. Modyfikator Using zakresu jest obsługiwany w następujących kontekstach:

  • Polecenia wykonywane zdalnie, uruchamiane Invoke-Command przy użyciu parametrów ComputerName, HostName, SSHConnection lub Session (sesja zdalna)
  • Zadania w tle, rozpoczęte (sesja poza procesem Start-Job )
  • Zadania wątków, uruchamiane za pośrednictwem Start-ThreadJob lub 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 procesem są one zawsze niezależnymi kopiami.

Aby uzyskać więcej informacji, zobacz about_Remote_Variables.

W sesjach wątków są przekazywane przez odwołanie. Oznacza to, że można zmodyfikować zmienne zakresu wywołań w innym wątku. Aby bezpiecznie modyfikować zmienne, wymagana jest synchronizacja wątków.

Aby uzyskać więcej informacji, zobacz:

Serializacja wartości zmiennych

Zdalnie wykonywane polecenia i zadania w tle kończą się poza procesem. Sesje poza procesem używają serializacji i deserializacji opartej na kodzie XML w celu udostępnienia wartości zmiennych w granicach procesu. Proces serializacji konwertuje obiekty na obiekt PSObject , który zawiera oryginalne właściwości obiektów, ale nie jego metody.

W przypadku ograniczonego zestawu typów deserializacja przywraca obiekty z powrotem do oryginalnego typu. Obiekt z ponownym wypełnianiem jest kopią oryginalnego wystąpienia obiektu. Ma właściwości i metody typu. 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 obiekty certyfikatów z ponownym wypełnianiem nie zawierają klucza prywatnego.

Wystąpienia wszystkich innych typów to wystąpienia obiektu PSObject . Właściwość PSTypeNames zawiera oryginalną nazwę typu poprzedzoną deserializacji, na przykład Deserialized.System.Data.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ą wszelkich utworzonych zakresów podrzędnych, chociaż nie są one dziedziczone z mocą wsteczną 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 zmienna jest zdefiniowana.

Zarządzanie zakresem

Kilka poleceń cmdlet ma parametr Zakres , który umożliwia pobieranie 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 Zakres :

Get-Help * -Parameter scope

Aby znaleźć zmienne, które są widoczne w określonym zakresie, użyj Scope parametru 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 widoczne w zakresie lokalnym:

Get-Variable -Scope local

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

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

Możesz również użyć parametru New-AliasZakres poleceń cmdlet , Set-Aliaslub Get-Alias , 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 Zakres .

Uwaga

W przypadku poleceń cmdlet, które używają parametru Zakres , można również odwołać się do zakresów według liczby. Liczba opisuje względną pozycję jednego zakresu do drugiego. 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 itd. Zakresy numerowane są przydatne, jeśli utworzono wiele zakresów cyklicznych.

Używanie notacji źródła kropkowego 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 używasz parametru polecenia cmdlet lub modyfikatora zakresu, aby zmienić ten zakres.

Można jednak dodać skrypt lub funkcję do bieżącego zakresu przy użyciu notacji źródła kropkowego. Następnie po uruchomieniu skryptu w bieżącym zakresie wszystkie funkcje, aliasy i zmienne tworzone przez 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 z katalogu C:\Scripts w zakresie skryptu (ustawienie domyślne 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

Jeśli używasz operatora wywołania (&) do uruchomienia 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 połączeń można dowiedzieć się w about_operators.

Wszystkie aliasy, funkcje lub zmienne tworzone przez skrypt Sample.ps1 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 autonomicznymi, ale nie są zakresami podrzędnymi zakresu globalnego w sesji.

Sesje

Sesja to środowisko, w którym działa program PowerShell. Podczas tworzenia sesji na komputerze zdalnym program PowerShell nawiązuje trwałe połączenie z komputerem zdalnym. Trwałe połączenie umożliwia użycie 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 nie zdefiniowano jawnie, elementy w module nie są dostępne poza modułem. W związku z tym można dodać moduł do sesji i użyć 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. Jeśli załadujesz moduł module2 z poziomu modułu1, moduł module2 zostanie załadowany do stanu sesji modułu1, a nie do stanu sesji globalnej. Wszystkie eksporty z modułu 2 są umieszczane w górnej części stanu sesji moduł1. Jeśli używasz polecenia 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 Import-Module -Scope global (lub Import-Module -Global) do załadowania innego modułu, ten moduł i eksporty są ładowane do stanu sesji globalnej zamiast stanu sesji lokalnej modułu. Ta funkcja została zaprojektowana do pisania modułu, który manipuluje modułami. Moduł WindowsCompatibility umożliwia zaimportowanie modułów 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ą $aglobalną , nadaj jej wartość i wywołamy obiekt foo funkcji.

$a = "Goodbye"
foo

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

$a = Hello
$global:a = Goodbye

Zagnieżdżone monity

Zagnieżdżone monity nie mają własnego zakresu. Po wprowadzeniu monitu zagnieżdżonego monit jest podzbiorem środowiska. Pozostajesz jednak w zakresie lokalnym.

Skrypty mają własny zakres. Jeśli debugujesz skrypt i osiągniesz punkt przerwania w skrycie, wprowadź zakres skryptu.

Opcja prywatna

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

Jeśli na przykład utworzysz zmienną z opcją prywatną w zakresie globalnym, a następnie uruchomisz skrypt, Get-Variable polecenia w skrycie nie wyświetlają zmiennej prywatnej. Użycie modyfikatora zakresu globalnego w tym wystąpieniu nie wyświetla zmiennej prywatnej.

Możesz użyć parametru Option poleceń New-Variablecmdlet , Set-Variable, New-Aliasi Set-Alias , aby ustawić wartość właściwości Option na Private.

Widoczność

Właściwość Widoczność 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ść prywatna właściwości Option jest przeznaczona dla zakresów.

Właściwość Visibility przyjmuje wartości publiczne i prywatne . Elementy, które mają widoczność prywatną, można wyświetlać i zmieniać tylko w kontenerze, w którym zostały utworzone. Jeśli kontener zostanie dodany lub zaimportowany, nie można wyświetlić ani zmienić elementów, które mają widoczność prywatną.

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

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

Polecenia cmdlet i Set-Variable umożliwiają New-Variable utworzenie zmiennej, która ma widoczność prywatną.

Przykłady

Przykład 1. Zmiana wartości zmiennej tylko w skrycie

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

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

PS>  $ConfirmPreference
High

Twórca skrypt Scope.ps1 zawierający następujące polecenia:

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

Uruchom skrypt. Skrypt zmienia wartość zmiennej $ConfirmPreference , a następnie zgłasza jej wartość w zakresie skryptu. Dane wyjściowe powinny przypominać następujące dane wyjściowe:

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 umożliwiają wyświetlanie wartości zmiennej w zakresie lokalnym i w zakresie nadrzędnym.

Najpierw zdefiniuj zmienną $test w zakresie globalnym.

$test = "Global"

Następnie utwórz skrypt Sample.ps1 definiujący zmienną $test . W skrycie użyj modyfikatora zakresu, aby odwołać się do globalnych lub lokalnych 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 działania skryptu w sesji zdefiniowana jest tylko wartość $test globalna.

PS>  $test
Global

Przykład 3. Zmiana wartości zmiennej w zakresie nadrzędnym

Jeśli element nie zostanie chroniony przy użyciu opcji Private lub innej metody, można wyświetlić i zmienić wartość zmiennej w zakresie nadrzędnym.

Najpierw zdefiniuj zmienną $test w zakresie globalnym.

$test = "Global"

Następnie utwórz skrypt Sample.ps1 definiujący zmienną $test . W skrycie użyj modyfikatora zakresu, aby odwołać się do globalnych lub lokalnych wersji zmiennej $test .

W Sample.ps1:

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

Po zakończeniu działania skryptu zostanie zmieniona wartość globalna $test .

PS>  $test
Local

Przykład 4. Tworzenie zmiennej prywatnej

Zmienna prywatna to zmienna, która ma właściwość Option , która ma wartość 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żesz wyświetlić i zmienić wartość $ptest w zakresie lokalnym.

PS>  $ptest
1

PS>  $ptest = 2
PS>  $ptest
2

Następnie utwórz skrypt Sample.ps1 zawierający 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 nie jest widoczna $ptest w zakresie skryptu. 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

W przypadku zmiennych w zdalnym poleceniu utworzonym w sesji lokalnej użyj Using modyfikatora 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ą $Cred w sesji lokalnej, a 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. W programie PowerShell 2.0, aby 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ż