Auswirkungen von Bereichen auf PowerShell-Skripts
In Batch-Skripts wirken sich Änderungen an Umgebungsvariablen standardmäßig auf die aktuelle Sitzung aus. Für PowerShell ist das genaue Gegenteil der Fall, da Bereiche verwendet werden, um die Änderungen eines Skripts zu isolieren. Hier erfahren Sie, wie sich Bereiche auf PowerShell-Skripts auswirken und wie sie in und um sie herum arbeiten.
Was ist ein Umfang??
In PowerShell bezieht sich ein Bereich auf die aktuelle Umgebung, in der ein Skript oder eine Befehlsshell ausgeführt wird. Bereiche werden verwendet, um bestimmte Objekte in der Umgebung vor unbeabsichtigtem Ändern durch Skripts oder Funktionen zu schützen. Insbesondere die folgenden Dinge sind durch Befehle, die aus einem anderen Bereich ausgeführt werden, vor Änderungen geschützt, sofern nicht durch Parameter in diesen Befehlen anders angegeben:
- Variablen
- Aliase
- Funktionen
- PowerShell-Laufwerke (PSDrives)
Neue Bereiche werden erstellt, wenn Sie ein Skript oder eine Funktion ausführen oder wenn Sie eine neue Sitzung oder Instanz von PowerShell erstellen. Bereiche, die durch das Ausführen von Skripts und Funktionen erstellt werden, haben eine Beziehung zu dem Bereich, in dem sie erstellt wurden. Es gibt einige Bereiche, die eine besondere Bedeutung haben und auf deren Namen zugegriffen werden können:
- Das Global Bereich ist der Bereich, der beim Start von PowerShell erstellt wird. Dazu gehören die in PowerShell integrierten Variablen, Aliasnamen, Funktionen und PS-Laufwerke sowie alle von Ihrem PowerShell-Profil erstellten.
- Das Lokal Gültigkeitsbereich bezieht sich auf den aktuellen Gültigkeitsbereich. Wenn Sie PowerShell starten, bezieht es sich auf den globalen Bereich, innerhalb eines Skripts auf den Skriptbereich usw..
- Das Skript Der Bereich wird erstellt, wenn ein Skript ausgeführt wird. Die einzigen Befehle, die in diesem Bereich ausgeführt werden, sind diejenigen, die im Skript enthalten sind.
- Privatgelände Bereiche können innerhalb des aktuellen Bereichs definiert werden, um zu verhindern, dass Befehle in anderen Bereichen Elemente lesen oder ändern können, auf die sie sonst Zugriff haben.
Gültigkeitsbereiche können auch in bestimmten Befehlen mit der Nummer bezeichnet werden, wobei der aktuelle Gültigkeitsbereich als Null bezeichnet wird und seine Vorfahren durch zunehmende Ganzzahlen referenziert werden. Beispiel: In einem Skript, das aus dem globalen Gültigkeitsbereich ausgeführt wird, wäre der Gültigkeitsbereich "Skript" 0 und der globale Gültigkeitsbereich "1". Ein weiter innerhalb des Gültigkeitsbereichs des Skriptbereichs verschachtelter Gültigkeitsbereich, beispielsweise eine Funktion, würde den globalen Gültigkeitsbereich als 2 bezeichnen Negative Zahlen können jedoch nicht für untergeordnete Bereiche verwendet werden - der Grund dafür wird in Kürze ersichtlich.
Wie Bereiche Auswirkungen auf Befehle haben
Wie bereits erwähnt, wirken sich Befehle, die in einem Bereich ausgeführt werden, nicht auf Dinge in einem anderen Bereich aus, sofern dies nicht ausdrücklich gesagt wird. Wenn beispielsweise $ MyVar im globalen Bereich vorhanden ist und ein Skript einen Befehl zum Festlegen von $ MyVar auf einen anderen Wert ausführt, bleibt die globale Version von $ MyVar unverändert, während eine Kopie von $ MyVar mit dem neuen im Skriptbereich abgelegt wird Wert. Wenn keine $ MyVar vorhanden ist, erstellt ein Skript es standardmäßig im Skriptbereich, nicht im globalen Bereich. Dies ist wichtig, wenn Sie sich über die tatsächliche Beziehung zwischen Eltern und Kindern zwischen den Bereichen informieren.
Die übergeordnete / untergeordnete Beziehung von Bereichen in PowerShell ist einseitig. Befehle können den aktuellen Bereich, seinen übergeordneten Bereich und alle darüber liegenden Bereiche anzeigen und optional ändern. Sie können jedoch in keinem der untergeordneten Elemente des aktuellen Bereichs Dinge sehen oder ändern. Dies ist in erster Linie darauf zurückzuführen, dass der untergeordnete Bereich, nachdem Sie in einen übergeordneten Bereich übergegangen sind, bereits zerstört wurde, da er seinen Zweck erfüllt hat. Warum sollten Sie beispielsweise eine Variable im Gültigkeitsbereich "Skript" im Bereich "Global" anzeigen oder ändern, nachdem das Skript beendet wurde? Es gibt viele Fälle, in denen Sie die Änderungen eines Skripts oder einer Funktion benötigen, um über die Fertigstellung hinaus bestehen zu bleiben, aber nicht so viele, in denen Sie vor oder nach der Ausführung des Objekts oder der Funktion Änderungen an Objekten innerhalb des Skriptbereichs oder der Funktion vornehmen müssen. (Normalerweise werden solche Dinge trotzdem als Teil des Skripts oder der Funktion selbst behandelt.)
Was sind natürlich Regeln ohne Ausnahmen? Eine Ausnahme von den oben genannten sind private Bereiche. Auf Objekte in den privaten Bereichen kann nur auf Befehle zugegriffen werden, die in dem Bereich ausgeführt werden, in dem sie erstellt wurden. Eine weitere wichtige Ausnahme sind Elemente mit der AllScope-Eigenschaft. Hierbei handelt es sich um spezielle Variablen und Aliasnamen, für die eine Änderung in einem beliebigen Bereich Auswirkungen auf alle Bereiche hat. Die folgenden Befehle zeigen Ihnen, welche Variablen und Aliase die AllScope-Eigenschaft haben:
Get-Variable | Where-Object $ _. Options -match 'AllScope' Get-Alias | Where-Object $ _. Options -match 'AllScope')
Bereiche in Aktion
Für unseren ersten Blick auf Bereiche in Aktion beginnen wir in einer PowerShell-Sitzung, in der die Variable $ MyVar von der Befehlszeile aus auf die Zeichenfolge "Ich bin eine globale Variable!" Gesetzt wurde. Dann wird das folgende Skript aus einer Datei namens Scope-Demo.ps1 ausgeführt:
Function FunctionScope '$ MyVar mit einer Funktion ändern.' $ MyVar = 'Ich wurde von einer Funktion eingestellt!' "MyVar sagt $ MyVar" "Der aktuelle Wert von $ MyVar wird überprüft." "MyVar sagt $ MyVar" "$ MyVar durch Skript ändern. ' $ MyVar = 'Ich wurde von einem Skript gesetzt!' "MyVar sagt $ MyVar" "FunctionScope" Endgültigen Wert von MyVar prüfen, bevor das Skript beendet wird. ' "MyVar sagt $ MyVar" "
Wenn PowerShell-Skripts genauso funktionieren wie Batch-Skripts, würden wir erwarten, dass der Wert von $ MyVar (oder% MyVar% in Batch-Syntax) von "Ich bin eine globale Variable!" In "Ich wurde von einem Skript festgelegt" geändert wurde. und schließlich zu "Ich wurde von einer Funktion eingestellt!" Dort würde es bleiben, bis es erneut explizit geändert wird oder die Sitzung beendet wird. Sehen Sie jedoch, was hier tatsächlich passiert, während wir uns durch die einzelnen Bereiche bewegen - insbesondere nachdem die FunctionScope-Funktion ihre Arbeit beendet hat und wir die Variable erneut aus dem Skriptbereich und später aus dem globalen Bereich prüfen.
Wie Sie sehen, hat sich die Variable scheinbar geändert, als wir uns durch das Skript bewegten, denn bis zum Abschluss der FunctionScope-Funktion haben wir die Variable innerhalb des Bereichs geprüft, in dem sie zuletzt geändert wurde. Nachdem FunctionScope jedoch fertig war, gingen wir zurück in den Skriptbereich, in dem $ MyVar von der Funktion nicht berührt wurde. Dann, als das Skript beendet war, kamen wir wieder in den globalen Bereich, wo es überhaupt nicht geändert wurde.
Außerhalb des lokalen Bereichs erreichen
Das ist also gut und gut, damit Sie nicht versehentlich Änderungen an der Umgebung vornehmen, die über Ihre Skripte und Funktionen hinausgehen. Was aber, wenn Sie solche Änderungen tatsächlich vornehmen möchten? Es gibt eine spezielle und relativ einfache Syntax zum Erstellen und Ändern von Objekten außerhalb des lokalen Bereichs. Sie setzen einfach den Bereichsnamen an den Anfang des Variablennamens und setzen einen Doppelpunkt zwischen den Bereichs- und Variablennamen. So was:
$ global: MyVar $ -Skript: MyVar $ local: MyVar
Sie können diese Modifizierer sowohl beim Anzeigen als auch beim Festlegen von Variablen verwenden. Mal sehen, was mit diesem Demo-Skript passiert:
Function FunctionScope "$ MyVar im lokalen Funktionsbereich ändern ... '$ local: MyVar =" Dies ist MyVar im lokalen Gültigkeitsbereich der Funktion. "' $ MyVar im Script-Bereich ändern '' $ script: MyVar = 'Früher war MyVar Von einem Skript festgelegt. Jetzt von einer Funktion festgelegt. "$ MyVar im globalen Gültigkeitsbereich ändern ... '$ global: MyVar =' MyVar wurde im globalen Gültigkeitsbereich festgelegt. Jetzt von einer Funktion gesetzt. "$ MyVar in jedem Bereich prüfen ... '" Local: $ local: MyVar "" Skript: $ script: MyVar "" Global: $ global: MyVar "" "Aktuellen Wert von $ MyVar abrufen." "MyVar sagt $ MyVar" "$ MyVar durch Skript ändern. ' $ MyVar = 'Ich wurde von einem Skript gesetzt!' "MyVar sagt $ MyVar" FunctionScope '$ MyVar wird vor dem Beenden aus dem Skriptbereich geprüft.' "MyVar sagt $ MyVar" "
Wie zuvor beginnen wir mit dem Festlegen der Variablen im globalen Gültigkeitsbereich und enden mit der Überprüfung des endgültigen globalen Gültigkeitsbereichs.
Hier können Sie sehen, dass FunctionScope die Variable im Skriptbereich ändern konnte und die Änderungen beibehalten werden, nachdem sie abgeschlossen wurde. Die Änderung der Variablen im globalen Bereich blieb auch nach dem Beenden des Skripts erhalten. Dies kann besonders nützlich sein, wenn Sie Variablen innerhalb eines Skripts oder innerhalb des globalen Gültigkeitsbereichs mit demselben Code wiederholt ändern müssen. Sie definieren lediglich eine Funktion oder ein Skript, das geschrieben wird, um die Variable zu ändern, wo und wie Sie sie benötigen, und rufen Sie das an, wenn diese Änderungen erforderlich sind.
Wie bereits erwähnt, können Bereichsnummern auch in bestimmten Befehlen verwendet werden, um die Variable auf verschiedenen Ebenen in Bezug auf den lokalen Bereich zu ändern. Hier dasselbe Skript, das im zweiten Beispiel oben verwendet wurde, jedoch mit der Funktion so modifiziert wurde, dass die Befehle Get-Variable und Set-Variable mit Bereichsnummern verwendet werden, anstatt die Variable direkt mit benannten Bereichen zu referenzieren:
Function FunctionScope "$ MyVar im Gültigkeitsbereich 0 relativ zu FunctionScope ändern ... 'Set-Variable MyVar" Dies ist MyVar im Funktionsumfang 0. "-Scope 0' $ MyVar im Gültigkeitsbereich 1 ändern, relativ zu FunctionScope ... 'Set-Variable MyVar 'MyVar wurde im Gültigkeitsbereich 1 von einer Funktion geändert.' -Scope 1 '$ MyVar in Geltungsbereich 2 relativ zum Funktionsbereich ändern ...' Set-Variable MyVar 'MyVar wurde im Gültigkeitsbereich 2 von einer Funktion geändert.' -Scope 2 "$ MyVar wird in jedem Bereich überprüft ..." Scope 0: 'Get-Variable MyVar - Scope 0' 2 -ValueOnly "" Aktuellen Wert von $ MyVar abrufen. ' "MyVar sagt $ MyVar" "$ MyVar durch Skript ändern. ' $ MyVar = 'Ich wurde von einem Skript gesetzt!' "MyVar sagt $ MyVar" FunctionScope '$ MyVar wird vor dem Beenden aus dem Skriptbereich geprüft.' "MyVar sagt $ MyVar" "
Ähnlich wie zuvor können Sie hier sehen, wie Befehle in einem Bereich Objekte im übergeordneten Bereich ändern können.
zusätzliche Information
Es gibt noch viel mehr Möglichkeiten für Bereiche, als in diesen Artikel passen. Bereiche wirken sich nicht nur auf Variablen aus, sondern es gibt noch weitere Informationen zu privaten Bereichen und den AllScope-Variablen. Für weitere nützliche Informationen können Sie den folgenden Befehl in PowerShell ausführen:
Get-Help about_scopes
Die gleiche Hilfedatei ist auch im TechNet verfügbar.
Scope Image Credit: Spadassin auf openclipart