TechNet Blog Deutschland

News für IT-Pros: Neues aus dem TechNet-Team

PowerShell Quick-Tip: lokale und globale Variablen

PowerShell Quick-Tip: lokale und globale Variablen

  • Comments 4
  • Likes

Dieser Gastbeitrag wurde uns freundlicherweise vom Education Support Center (ESCde) zur Verfügung gestellt. Autor ist Moritz Baer.

Das ESCde betreibt im Auftrag von Microsoft Deutschland die TechNet Support Hotline. Mehr Infos unter www.technet.de/hotline.

Beim Erstellen eines Skripts ist es oft hilfreich einzelne Programmteile als eine Funktion im Code anzulegen. Hier kann man in unerwartete Probleme mit Variablen geraten.
Das Szenario
Wie in fast jeder Programmiersprache, gibt es auch in der PowerShell die Unterscheidung zwischen lokalen und globalen Variablen bzw. entsprechenden Unterformen. Eine, innerhalb eines Klammer-Blocks deklarierte, Variable überschreibt für den Klammer-Block eine außerhalb definierte Variable mit dem selben Namen. Dies ist normal und auch so gewünscht.
Das Problem
Da in der Powershell das Zuweisen von Werten gleichbedeutend mit der Deklaration einer Variable ist, bekommt man jetzt allerdings ein Problem:
$variable = "test"
if($true) {
$variable = "neuer Test"
}
echo $variable
Echo gibt hier unerwarteter Weise test aus.  Die äußere Variable $variable bekommt außerhalb des IF-Blocks den Wert test. Da mit $variable auch eine neue Variable innerhalb des IF-Blocks instanziiert wird, wird der Wert neuer Test in die neue Variable und nicht in die außerhalb deklarierte Variable geschrieben. Die äußere Variable bleibt also unangetastet.
Die Lösung
Um ein solches ungewolltest Dilemma zu vermeiden, kann man in der PowerShell den Zugriff konkret auf den globalen-Kontext legen. Anstatt mit $NAME legt man die Variablen mit $global:NAME an:
$global:variable = "test"
if($true) {
$global:variable = "neuer Test"
}
echo $global:variable
Nun gibt echo wie gewünscht neuer Test aus.
 

Korrektur:

Im Beispiel zur Problembeschreibung ist unserem Gastautor ein Fehler unterlaufen - korrekt sieht das Beispiel so aus:

Das Problem

In der PowerShell gibt es sogenannte Scopes, die den Zugriff auf Variablen, Aliase, Funktionen und PowerShell Skripte schützen.

$variable = "test"
function test($foo) {
   $variable = $foo
}

test(“neuer Test”)
echo $variable

Echo gibt hier unerwarteter Weise test aus. Die äußere Variable $variable bekommt außerhalb der Funktion den Wert test. Mit $variable wird auch eine neue Variable innerhalb der Funktion instanziiert. Diese Variable ist allerdings nur in dem Scope der Funktion sichtbar, in der sie erstellt wurde, und in allen Child Scopes. Die äußere Variable bleibt also unangetastet.

Comments
  • bitte entfernt dieses Beispiel da es falsch ist. Ein if-Block führt zu keinem neuen Scope, der Wert der Variable wird also auch ohne $global gesetzt.

    PS D:\> $variable = "test"; if($true) { $variable = "neuer Test" }; echo $variable
    neuer Test

  • Hallo,

    habe deinen Testfall (Problem) angeschaut. Im If-Block wird keine neue Variable instanziiert. Hier wird lediglich einer Variablen einen anderen Wert zugewiesen.
    Beide beispiele liefern das gleiche Ergebnis.
    Global:-Variablen kann man verwenden, wenn man ein anderes Skript aufruft.

    Die Aussage, dass "Zuweisen von Werten gleichbedeutend mit der Deklaration einer Variable ist", ist falsch. Variablen, die noch nicht instanziiert wurden werden bei erstmaliger Verwendung instanziiert.

    Viele Grüße
    Phil

  • Hallo!
    $global muss nur in der Klammer verwendet werden, danach kann der Variablenname alleine wieder verwendet werden.

    $variable1="test"
    if ($true) {$global:variable1="Neuer Test"}
    echo $variable1

  • Hallo,

    das Beispiel ist tatsächlich nicht ideal gewählt, da sich der Scope hier nicht ändert. Wir werden den Beitrag überarbeiten. Wer in der Zwischenzeit etwas mehr über das Thema lesen möchte: https://technet.microsoft.com/de-de/library/hh847849.aspx

    Beste Grüße
    Jonathan vom Education Support Center (ESCde)

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment