Connect with us

Wie man

Wie sich Bereiche auf PowerShell-Skripts auswirken

Wie sich Bereiche auf PowerShell-Skripts auswirken

In Batch-Skripten wirken sich Änderungen an Umgebungsvariablen standardmäßig global auf die aktuelle Sitzung aus. Für PowerShell gilt genau das Gegenteil, da Bereiche verwendet werden, um die Änderungen eines Skripts zu isolieren. Hier untersuchen wir, 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. Scopes werden verwendet, um bestimmte Objekte innerhalb der Umgebung vor unbeabsichtigten Änderungen durch Skripte oder Funktionen zu schützen. Insbesondere die folgenden Dinge sind vor Änderungen durch Befehle geschützt, die von einem anderen Geltungsbereich ausgeführt werden, sofern nicht anders durch Parameter in diesen Befehlen 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 Ausführen von Skripten und Funktionen erstellt werden, haben eine «übergeordnete/untergeordnete» Beziehung zu dem Bereich, aus dem sie erstellt wurden. Es gibt einige Bereiche, die eine besondere Bedeutung haben und mit Namen aufgerufen werden können:

  • Das Global scope ist der Bereich, der beim Start von PowerShell erstellt wird. Es enthält die Variablen, Aliase, Funktionen und PSDrives, die in PowerShell integriert sind, sowie alle, die von Ihrem PowerShell-Profil erstellt werden.
  • Das Lokal Geltungsbereich bezieht sich auf den aktuellen Geltungsbereich. Wenn Sie PowerShell starten, bezieht es sich auf den globalen Bereich, innerhalb eines Skripts ist es der Skriptbereich usw.
  • Das Skript Scope wird erstellt, wenn ein Skript ausgeführt wird. Die einzigen Befehle, die innerhalb dieses Bereichs ausgeführt werden, sind diejenigen, die im Skript enthalten sind.
  • Privat 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 ansonsten Zugriff hätten.

Auf Bereiche kann in bestimmten Befehlen auch durch Zahlen verwiesen werden, wobei der aktuelle Bereich als Null bezeichnet wird und auf seine Vorfahren durch aufsteigende Ganzzahlen verwiesen wird. Beispiel: In einem Skript, das vom globalen Gültigkeitsbereich ausgeführt wird, wäre der Skriptbereich 0 und der globale Gültigkeitsbereich 1. Ein weiter innerhalb des Skriptbereichs verschachtelter Bereich, z. B. eine Funktion, würde den globalen Gültigkeitsbereich als 2 . bezeichnen Negative Zahlen funktionieren jedoch nicht, um auf untergeordnete Bereiche zu verweisen – der Grund dafür wird in Kürze ersichtlich.

Wie Bereiche sich auf Befehle auswirken

Wie bereits erwähnt, wirken sich Befehle, die in einem Bereich ausgeführt werden, nicht auf Dinge in einem anderen Bereich aus, es sei denn, Sie werden ausdrücklich dazu aufgefordert. Wenn beispielsweise $MyVar im globalen Gültigkeitsbereich vorhanden ist und ein Skript einen Befehl ausführt, um $MyVar auf einen anderen Wert zu setzen, bleibt die globale Version von $MyVar unverändert, während eine Kopie von $MyVar mit dem neuen im Script-Bereich platziert wird Wert. Wenn eine $MyVar nicht vorhanden ist, erstellt ein Skript sie standardmäßig im Skriptbereich – nicht im globalen Bereich. Dies ist wichtig, wenn Sie mehr über die tatsächliche Eltern-/Kind-Beziehung zwischen Bereichen erfahren.

Die Eltern-Kind-Beziehung von Bereichen in PowerShell ist unidirektional. Befehle können den aktuellen Bereich, seinen Elternbereich und alle darüber liegenden Bereiche einsehen und optional ändern. Sie können jedoch keine Elemente in untergeordneten Elementen des aktuellen Bereichs sehen oder ändern. Dies liegt in erster Linie daran, dass nach dem Wechsel in einen übergeordneten Geltungsbereich der untergeordnete Geltungsbereich bereits zerstört wurde, da er seinen Zweck erfüllt hat. Warum müssen Sie beispielsweise eine Variable im Gültigkeitsbereich Skript im Gültigkeitsbereich Global anzeigen oder ändern, nachdem das Skript beendet wurde? Es gibt viele Fälle, in denen die Änderungen eines Skripts oder einer Funktion über den Abschluss hinaus bestehen bleiben müssen, aber nicht so viele, in denen Sie vor oder nach der Ausführung Änderungen an Objekten innerhalb des Gültigkeitsbereichs des Skripts oder der Funktion vornehmen müssen. (Normalerweise werden solche Dinge sowieso als Teil des Skripts oder der Funktion selbst behandelt.)

Natürlich, was sind Regeln ohne Ausnahmen? Eine Ausnahme von den oben genannten sind private Bereiche. Objekte in den privaten Bereichen sind nur für Befehle zugänglich, die in dem Bereich ausgeführt werden, aus dem sie erstellt wurden. Eine weitere wichtige Ausnahme sind Elemente mit der AllScope-Eigenschaft. Dies sind spezielle Variablen und Aliase, für die eine Änderung in einem Bereich alle Bereiche betrifft. 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 über die Befehlszeile auf eine Zeichenfolge „Ich bin eine globale Variable!“ gesetzt wurde. Anschließend wird das folgende Skript aus einer Datei namens Scope-Demo.ps1 ausgeführt:

Function FunctionScope
{
    'Changing $MyVar with a function.'
    $MyVar="I got set by a function!"
    "MyVar says $MyVar"
}
''
'Checking current value of $MyVar.'
"MyVar says $MyVar"
''
'Changing $MyVar by script.'
$MyVar="I got set by a script!"
"MyVar says $MyVar"
''
FunctionScope
''
'Checking final value of MyVar before script exit.'
"MyVar says $MyVar"
''

Wenn PowerShell-Skripte genauso funktionieren würden wie Batch-Skripte, würden wir erwarten, dass sich der Wert von $MyVar (oder %MyVar% in der Batch-Syntax) von „Ich bin eine globale Variable!“ zu „Ich wurde von einem Skript gesetzt!“ ändert. , und schließlich zu ‘Ich wurde von einer Funktion gesetzt!’ wo es bleiben würde, bis es wieder explizit geändert wird oder die Sitzung beendet wird. Sehen Sie sich jedoch an, was hier tatsächlich passiert, wenn wir uns durch die einzelnen Bereiche bewegen – insbesondere, nachdem die FunctionScope-Funktion ihre Arbeit abgeschlossen hat und wir die Variable erneut aus dem Skript und später aus dem globalen Bereich überprüfen.

Wie Sie sehen, schien sich die Variable zu ändern, als wir uns durch das Skript bewegten, da wir bis zum Abschluss der FunctionScope-Funktion die Variable innerhalb des gleichen Bereichs überprüften, in dem sie zuletzt geändert wurde. Nachdem FunctionScope jedoch fertig war, sind wir zurück in den Script-Bereich gegangen, wo $MyVar von der Funktion unberührt gelassen wurde. Als das Skript dann beendet wurde, kamen wir zurück in den globalen Bereich, wo es überhaupt nicht geändert wurde.

Außerhalb des lokalen Geltungsbereichs erreichen

Das ist also alles schön und gut, um zu verhindern, dass Sie versehentlich Änderungen an der Umgebung über Ihre Skripts und Funktionen hinaus vornehmen, aber was ist, wenn Sie solche Änderungen tatsächlich vornehmen möchten? Es gibt eine spezielle und ziemlich einfache Syntax zum Erstellen und Ändern von Objekten außerhalb des lokalen Geltungsbereichs. Sie setzen einfach den Bereichsnamen an den Anfang des Variablennamens und setzen einen Doppelpunkt zwischen Bereichs- und Variablennamen. So was:

$global:MyVar
$script:MyVar
$local:MyVar

Sie können diese Modifikatoren sowohl beim Anzeigen als auch beim Festlegen von Variablen verwenden. Sehen wir uns an, was mit diesem Demonstrationsskript passiert:

Function FunctionScope
{
    ''
    'Changing $MyVar in the local function scope...'
    $local:MyVar = "This is MyVar in the function's local scope."
    'Changing $MyVar in the script scope...'
    $script:MyVar="MyVar used to be set by a script. Now set by a function."
    'Changing $MyVar in the global scope...'
    $global:MyVar="MyVar was set in the global scope. Now set by a function."
    ''
    'Checking $MyVar in each scope...'
    "Local: $local:MyVar"
    "Script: $script:MyVar"
    "Global: $global:MyVar"
    ''
}
''
'Getting current value of $MyVar.'
"MyVar says $MyVar"
''
'Changing $MyVar by script.'
$MyVar="I got set by a script!"
"MyVar says $MyVar"

FunctionScope

'Checking $MyVar from script scope before exit.'
"MyVar says $MyVar"
''

Wie zuvor beginnen wir mit dem Festlegen der Variablen im globalen Gültigkeitsbereich und enden mit der Überprüfung des endgültigen Ergebnisses des globalen Gültigkeitsbereichs.

Hier sehen Sie, dass FunctionScope die Variable im Script-Bereich ändern konnte und die Änderungen nach Abschluss bestehen bleiben. Außerdem blieb die Änderung der Variablen im Gültigkeitsbereich Global auch nach dem Beenden des Skripts bestehen. Dies kann besonders nützlich sein, wenn Sie Variablen innerhalb eines Skripts oder innerhalb des globalen Gültigkeitsbereichs wiederholt mit demselben Code ändern müssen – Sie definieren einfach eine Funktion oder ein Skript, das geschrieben wurde, um die Variable zu ändern, wo und wie Sie es tun müssen, und rufen Sie dies immer dann auf, wenn diese Änderungen erforderlich sind.

Wie bereits erwähnt, können Bereichsnummern in bestimmten Befehlen auch verwendet werden, um die Variable auf verschiedenen Ebenen in Bezug auf den lokalen Bereich zu ändern. Hier ist das gleiche Skript, das im zweiten Beispiel oben verwendet wurde, jedoch mit geänderter Funktion, um die Befehle Get-Variable und Set-Variable mit Bereichsnummern zu verwenden, anstatt direkt auf die Variable mit benannten Bereichen zu verweisen:

Function FunctionScope
{
    ''
    'Changing $MyVar in scope 0, relative to FunctionScope...'
    Set-Variable MyVar "This is MyVar in the function's scope 0." –Scope 0
    'Changing $MyVar in scope 1, relative to FunctionScope...'
    Set-Variable MyVar 'MyVar was changed in scope 1, from a function.' –Scope 1
    'Changing $MyVar in scope 2, relative to Functionscope...'
    Set-Variable MyVar 'MyVar was changed in scope 2, from a function.' –Scope 2
    ''
    'Checking $MyVar in each scope...'
    ‘Scope 0:’
    Get-Variable MyVar –Scope 0 –ValueOnly
    ‘Scope 1:’
    Get-Variable MyVar –Scope 1 –ValueOnly
    ‘Scope 2:’
    Get-Variable MyVar –Scope 2 –ValueOnly
    ''
}
''
'Getting current value of $MyVar.'
"MyVar says $MyVar"
''
'Changing $MyVar by script.'
$MyVar="I got set by a script!"
"MyVar says $MyVar"

FunctionScope

'Checking $MyVar from script scope before exit.'
"MyVar says $MyVar"
''

Ähnlich wie zuvor können wir hier sehen, wie Befehle in einem Geltungsbereich Objekte in seinem übergeordneten Geltungsbereich ändern können.

zusätzliche Information

Es gibt noch viel mehr, das mit Scopes gemacht werden kann, als in diesen Artikel passt. Gültigkeitsbereiche betreffen mehr als nur Variablen, und es gibt noch mehr zu lernen über private Gültigkeitsbereiche und die AllScope-Variablen. Für weitere nützliche Informationen können Sie den folgenden Befehl in PowerShell ausführen:

Get-Help about_scopes

Dieselbe Hilfedatei ist auch verfügbar auf TechNet.

Umfang Bildnachweis: spadassin auf openclipart

Continue Reading
Click to comment

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Tendencia