Jak zakresy wpływają na skrypty PowerShell
W skryptach wsadowych zmiany zmiennych środowiskowych mają globalny wpływ na bieżącą sesję domyślnie. W przypadku programu PowerShell dokładne przeciwieństwo jest prawdziwe, ponieważ zakresy służą do izolowania modyfikacji skryptu. W tym artykule omawiamy, w jaki sposób zakresy wpływają na skrypty PowerShell i jak pracować w nich i wokół nich.
Co to jest zakres?
W PowerShell "zakres" odnosi się do bieżącego środowiska, w którym działa skrypt lub warstwa poleceń. Zakresy służą do ochrony pewnych obiektów w środowisku przed niechcący zmodyfikowanym przez skrypty lub funkcje. W szczególności następujące rzeczy są chronione przed modyfikacją przez polecenia uruchamiane z innego zakresu, chyba że parametry w tych komendach określają inaczej:
- Zmienne
- Aliasy
- Funkcje
- Dyski PowerShell (PSDrives)
Nowe zakresy są tworzone za każdym razem, gdy uruchamiasz skrypt lub funkcję, lub gdy tworzysz nową sesję lub wystąpienie PowerShell. Zakresy tworzone przez uruchamianie skryptów i funkcji mają relację "nadrzędny / podrzędny" z zakresem, w którym zostały utworzone. Istnieje kilka zakresów, które mają szczególne znaczenie i można je uzyskać po nazwie:
- The Światowy scope to zakres tworzony podczas uruchamiania PowerShell. Zawiera zmienne, aliasy, funkcje i pliki PSDrives, które są wbudowane w PowerShell, a także wszystkie, które są tworzone przez twój profil PowerShell.
- The Lokalny zakres odnosi się do dowolnego obecnego zakresu. Po uruchomieniu PowerShell będzie odnosić się do zasięgu globalnego, w skrypcie będzie to zakres skryptu itp.
- The Scenariusz Zakres jest tworzony podczas uruchamiania skryptu. Jedynymi komendami działającymi w tym zakresie są te, które znajdują się w skrypcie.
- Prywatny zakresy można definiować w ramach bieżącego zakresu, aby uniemożliwić komendom z innych zakresów odczytanie lub modyfikację elementów, które w przeciwnym razie mogłyby mieć dostęp do.
Zakresy mogą być również określane numerami w niektórych poleceniach, gdzie bieżący zakres jest określany jako zero, a do jego przodków odwołują się rosnące liczby całkowite. Na przykład w skrypcie uruchamianym z zasięgu globalnego zasięg skryptu będzie wynosił 0, a zasięg globalny będzie wynosił 1. Zakres, który był dalej zagnieżdżony w zasięgu Skryptu, taki jak funkcja, odnosiłby się do zakresu globalnego jako 2. Liczby ujemne nie będą jednak działały w odniesieniu do zakresów potomnych - przyczyna tego będzie widoczna wkrótce.
Jak zakresy wpływają na polecenia
Jak wspomniano wcześniej, polecenia wykonywane w ramach jednego zakresu nie będą miały wpływu na rzeczy w innym zakresie, chyba że zostanie im to wyraźnie powiedziane. Na przykład, jeśli $ MyVar istnieje w zasięgu globalnym, a skrypt uruchamia polecenie ustawienia zmiennej $ MyVar na inną wartość, wersja globalna zmiennej $ MyVar pozostanie niezmieniona, podczas gdy kopia zmiennej $ MyVar zostanie umieszczona w zakresie Skrypt z nowym wartość. Jeśli plik $ MyVar nie istnieje, skrypt utworzy go domyślnie w zakresie Skrypt - nie w zasięgu globalnym. Należy o tym pamiętać, ponieważ dowiesz się o rzeczywistej relacji rodzic / dziecko między zakresami.
Relacja rodzic / dziecko zakresów w PowerShell jest jednokierunkowa. Polecenia mogą przeglądać i opcjonalnie modyfikować bieżący zakres, jego rodzica i wszelkie zakresy powyżej. Jednak nie mogą widzieć ani modyfikować rzeczy w żadnych dzieciach z bieżącego zakresu. Dzieje się tak przede wszystkim dlatego, że po przejściu do zakresu nadrzędnego zakres podrzędny został już zniszczony, ponieważ spełnił swój cel. Na przykład, dlaczego musiałbyś widzieć lub modyfikować zmienną w zakresie Skrypt, z zakresu globalnego, po zakończeniu działania skryptu? Istnieje wiele przypadków, w których potrzebne są zmiany skryptu lub funkcji, które utrzymają się poza końcem, ale nie tak wiele, gdy trzeba wprowadzić zmiany do obiektów w zakresie skryptu lub funkcji przed lub po uruchomieniu. (Zwykle takie rzeczy będą mimo wszystko obsługiwane jako część samego skryptu lub funkcji).
Oczywiście, czym są reguły bez wyjątków? Wyjątkiem od powyższego są Prywatne zakresy. Obiekty w zakresach prywatnych są dostępne tylko dla poleceń uruchamianych w zakresie, w którym zostały utworzone. Innym ważnym wyjątkiem są elementy, które mają właściwość AllScope. Są to specjalne zmienne i aliasy, dla których zmiana dowolnego zakresu dotyczy wszystkich zakresów. Poniższe polecenia pokażą, które zmienne i aliasy mają właściwość AllScope:
Pobierz zmienną | Where-Object $ _. Opcje -match 'AllScope' Get-Alias | Gdzie-obiekt $ _. Opcje-zestaw "AllScope")
Zakresy w działaniu
Nasze pierwsze spojrzenie na zakresy w akcji rozpoczniemy w sesji PowerShell, w której zmienna $ MyVar została ustawiona na łańcuch "Jestem zmienną globalną!" Z poziomu wiersza poleceń. Następnie poniższy skrypt zostanie uruchomiony z pliku o nazwie Scope-Demo.ps1:
Funkcja FunctionScope 'Zmiana $ MyVar za pomocą funkcji.' $ MyVar = 'Ustawiłem przez funkcję!' "MyVar mówi $ MyVar" "Sprawdzanie bieżącej wartości $ MyVar." "MyVar mówi" MyVar "" "Zmienia $ MyVar według skryptu". $ MyVar = 'Ustawiłem przez skrypt! " "MyVar mówi" MyVar "" "FunctionScope" Sprawdzanie końcowej wartości MyVar przed zakończeniem skryptu. " "MyVar mówi $ MyVar" "
Gdyby skrypty PowerShell działały tak samo jak skrypty wsadowe, spodziewalibyśmy się, że zmienna $ MyVar (lub% MyVar% w składni wsadowej) zmieni się z "Jestem zmienną globalną!", Na "Ustawiłem przez skrypt!". , a na końcu "Ustawiłem przez funkcję!" gdzie pozostanie, dopóki nie zostanie wyraźnie zmieniony ponownie lub sesja zostanie zakończona. Zobacz jednak, co faktycznie się dzieje tutaj, gdy przechodzimy przez każdy z zakresów - w szczególności po zakończeniu funkcji FunctionScope i ponownie sprawdzamy zmienną ze Skryptu, a następnie Globalny, zakres.
Jak widać, zmienna zmieniła się, gdy przechodziliśmy przez skrypt, ponieważ aż do zakończenia funkcji FunctionScope sprawdzaliśmy zmienną z tego samego zakresu, w którym została ona ostatnio zmieniona. Po zakończeniu działania funkcji FunctionScope wróciliśmy do zakresu skryptu, w którym funkcja $ MyVar została nietknięta przez funkcję. Następnie, gdy skrypt został zakończony, wróciliśmy do zasięgu globalnego, w którym nie zostało ono w ogóle zmodyfikowane.
Osiągnięcie poza zasięgiem lokalnym
Jest więc dobrze i dobrze, aby zapobiec przypadkowemu wprowadzeniu zmian w środowisku poza skrypty i funkcje, ale co, jeśli rzeczywiście chcesz wprowadzić takie modyfikacje? Istnieje specjalna i dość prosta składnia do tworzenia i modyfikowania obiektów poza zasięgiem lokalnym. Po prostu wstaw nazwę zakresu na początku nazwy zmiennej i wstaw dwukropek między nazwą zakresu i zmienną. Lubię to:
$ global: skrypt MyVar $: MyVar $ local: MyVar
Możesz użyć tych modyfikatorów zarówno podczas przeglądania i ustawiania zmiennych. Zobaczmy, co stanie się z tym skryptem demonstracyjnym:
Funkcja FunctionScope "Zmiana $ MyVar w lokalnym zakresie funkcji ... '$ local: MyVar =" To jest MyVar w zasięgu lokalnym funkcji. "" Zmiana $ MyVar w zakresie skryptu ...' $ script: MyVar = 'MyVar był kiedyś ustawione przez skrypt, teraz ustawione przez funkcję. "Zmiana $ MyVar w zasięgu globalnym ..." $ global: MyVar = 'MyVar został ustawiony w zasięgu globalnym. Teraz ustawione przez funkcję. "Sprawdzanie MyVar w każdym zakresie ..." "Lokalne: $ local: MyVar" "Script: $ script: MyVar" "Global: $ global: MyVar" "" Uzyskiwanie aktualnej wartości $ MyVar. " "MyVar mówi" MyVar "" "Zmienia $ MyVar według skryptu". $ MyVar = 'Ustawiłem przez skrypt! " "MyVar mówi" MyVar "" FunctionScope "Sprawdzanie $ MyVar z zakresu skryptu przed zakończeniem." "MyVar mówi $ MyVar" "
Tak jak poprzednio, zaczniemy od ustawienia zmiennej w zasięgu globalnym i zakończymy sprawdzaniem końcowego wyniku globalnego zasięgu.
Tutaj widać, że FunctionScope był w stanie zmienić zmienną w zakresie Skrypt, a zmiany pozostały po jej zakończeniu. Również zmiana zmiennej w zasięgu globalnym trwała nawet po wyjściu skryptu. Może to być szczególnie użyteczne, jeśli musisz wielokrotnie zmieniać zmienne w skrypcie lub w zasięgu globalnym, używając tego samego kodu - po prostu definiujesz funkcję lub skrypt, który został napisany w celu zmodyfikowania zmiennej gdzie i jak tego potrzebujesz, oraz wzywaj tego, kiedy tylko konieczne są te zmiany.
Jak wspomniano wcześniej, numery zakresów mogą być również używane w niektórych poleceniach do modyfikowania zmiennej na różnych poziomach w odniesieniu do zasięgu lokalnego. Oto ten sam skrypt, który został użyty w drugim przykładzie powyżej, ale z funkcją zmodyfikowaną tak, aby używać poleceń Get-Variable i Set-Variable z numerami zakresu, zamiast bezpośrednio odwoływać się do zmiennej o nazwanych zakresach:
Funkcja FunctionScope "Zmiana $ MyVar w zakresie 0, w stosunku do FunctionScope ..." Set-Variable MyVar "To jest MyVar w zakresie funkcji 0." -Scope 0 "Zmiana $ MyVar w zakresie 1, w stosunku do FunctionScope ... 'Set-Variable MyVar "MyVar został zmieniony w zakresie 1, z funkcji." -Scope 1 'Zmienianie $ MyVar w zakresie 2, względem Functionscope ...' Set-Variable MyVar 'MyVar został zmieniony w zakresie 2, z funkcji.' -Scope 2 "Sprawdzanie wartości $ MyVar w każdym z zakresów ..." Zakres 0: "Zmienna" Get MyVar -Scope 0 -ValueOnly "Zakres 1:" Zmienna "Get MyVar -Scope 1 -ValueOnly" Zakres 2: "Get-Variable MyVar -Scope 2 -ValueOnly "" Pobranie aktualnej wartości MyVar $. " "MyVar mówi" MyVar "" "Zmienia $ MyVar według skryptu". $ MyVar = 'Ustawiłem przez skrypt! " "MyVar mówi" MyVar "" FunctionScope "Sprawdzanie $ MyVar z zakresu skryptu przed zakończeniem." "MyVar mówi $ MyVar" "
Podobnie jak wcześniej, możemy zobaczyć tutaj, jak polecenia w jednym zakresie mogą modyfikować obiekty w zakresie nadrzędnym.
Dodatkowe informacje
Nadal można zrobić o wiele więcej, niż można to zrobić w tym artykule. Zakresy dotyczą więcej niż tylko zmiennych, a jeszcze więcej można się dowiedzieć o zakresach prywatnych i zmiennych AllScope. Aby uzyskać więcej przydatnych informacji, możesz uruchomić następujące polecenie z poziomu PowerShell:
Uzyskaj pomoc about_scopes
Ten sam plik pomocy jest również dostępny w witrynie TechNet.
Zakres obrazu kredyt: spadassin na openclipart