Seltsames Verhalten mit Powershell-Skriptblocks Geltungsbereich von Variablen und Modulen, irgendwelche Vorschläge?

HINWEIS: ich bin mit PowerShell 2.0 unter Windows Vista.

Ich versuche, hinzufügen von Unterstützung für die Angabe build Argumente zu psake, aber ich ' ve stoßen einige seltsame PowerShell-variable scoping-Verhalten, das sich speziell mit den Aufruf von Funktionen, die exportiert wurden, mit Export-ModuleMember (das ist, wie psake macht es die main-Methode). Folgende ist ein einfaches PowerShell-Modul zur Veranschaulichung (benannt repoCase.psm1):

function Test {
    param(
        [Parameter(Position=0,Mandatory=0)]
        [scriptblock]$properties = {}
    )

    $defaults = {$message = "Hello, world!"}

    Write-Host "Before running defaults, message is: $message"

    . $defaults

    #At this point, $message is correctly set to "Hellow, world!"
    Write-Host "Aftering running defaults, message is: $message"

    . $properties

    #At this point, I would expect $message to be set to whatever is passed in,
    #which in this case is "Hello from poperties!", but it isn't.  
    Write-Host "Aftering running properties, message is: $message"
}

Export-ModuleMember -Function "Test"

Um das Modul zu testen, führen Sie die folgende Sequenz von Befehlen (werden Sie sicher, dass Sie in das gleiche Verzeichnis wie die repoCase.psm1):

Import-Module .\repoCase.psm1

#Note that $message should be null
Write-Host "Before execution - In global scope, message is: $message"

Test -properties { "Executing properties, message is $message"; $message = "Hello from properties!"; }

#Now $message is set to the value from the script block.  The script block affected only the global scope.
Write-Host "After execution - In global scope, message is: $message"

Remove-Module repoCase

Dem Verhalten, dass ich erwartet wurde für den script-block habe ich weitergegeben zum Testen, um auf den lokalen Rahmen zu Testen. Es wird 'dotsourced' in, so dass alle änderungen, die er macht, sollte im Rahmen der Anrufer. Aber das ist nicht das, was passiert, scheint es zu sein, die den Umfang, wo es erklärt wurde. Hier ist die Ausgabe:

Before execution - In global scope, message is:
Before running defaults, message is:
Aftering running defaults, message is: Hello, world!
Executing properties, message is
Aftering running properties, message is: Hello, world!
After execution - In global scope, message is: Hello from properties!

Interessanterweise, wenn ich nicht die export-Test als Modul und stattdessen lediglich die Funktion deklarieren und aufrufen, es funktioniert alles so wie ich es erwarten würden. Der Skript-block wirkt sich nur auf Test-Bereich, und nicht ändern (global).

Ich bin kein PowerShell-guru, aber kann mir jemand erklären, dies Verhalten zu mir?

  • Haben Sie es gemeldet als bug?
Schreibe einen Kommentar