it-swarm.com.de

Festlegen einer globalen PowerShell-Variablen aus einer Funktion, bei der der globale Variablenname eine an die Funktion übergebene Variable ist

Ich muss eine globale Variable aus einer Funktion setzen und bin mir nicht ganz sicher, wie sie ausgeführt wird.

# Set variables
$global:var1
$global:var2
$global:var3

function foo ($a, $b, $c)
{
    # Add $a and $b and set the requested global variable to equal to it
    $c = $a + $b
}

Rufen Sie die Funktion auf:

foo 1 2 $global:var3

Endresultat:

$ global: var3 ist auf 3 gesetzt

Oder wenn ich die Funktion so aufgerufen habe:

foo 1 2 $global:var2

Endresultat:

$ global: var2 ist auf 3 gesetzt

Ich hoffe dieses Beispiel macht Sinn. Die dritte an die Funktion übergebene Variable ist der Name der Variablen, die gesetzt werden soll.

44
Radagast

Sie können das Cmdlet Set-Variable verwenden. Wenn Sie $global:var3 übergeben, wird der Wert von $var3 gesendet, der nicht Ihren Wünschen entspricht. Sie möchten den Namen senden.

$global:var1 = $null

function foo ($a, $b, $varName)
{
   Set-Variable -Name $varName -Value ($a + $b) -Scope Global
}

foo 1 2 var1

Dies ist jedoch keine sehr gute Programmierpraxis. Unten wäre viel einfacher und es ist unwahrscheinlich, dass später Fehler auftreten:

$global:var1 = $null

function ComputeNewValue ($a, $b)
{
   $a + $b
}

$global:var1 = ComputeNewValue 1 2
80
latkin

So einfach wie:

$A="1"
function changeA2 () { $global:A="0"}
changeA2
$A
36
Kirt Carson

Sie müssen Ihre Argumente als Referenztypen übergeben. 

#First create the variables (note you have to set them to something)
$global:var1 = $null
$global:var2 = $null
$global:var3 = $null

#The type of the reference argument should be of type [REF]
function foo ($a, $b, [REF]$c)
{
    # add $a and $b and set the requested global variable to equal to it
    # Note how you modify the value.
    $c.Value = $a + $b
}

#You can then call it like this:
foo 1 2 [REF]$global:var3
17
zdan

Ich stieß bei der Fehlerbehebung meines eigenen Codes auf diese Frage.

Also das funktioniert NICHT ...

$myLogText = ""
function AddLog ($Message)
{
    $myLogText += ($Message)
}
AddLog ("Hello")
Write-Host $myLogText

Diese APPEARS funktionieren, aber nur in der PowerShell ISE :

$myLogText = ""
function AddLog ($Message)
{
    $global:myLogText += ($Message)
}
AddLog ("Hello")
Write-Host $myLogText

Dies funktioniert eigentlich sowohl in der ISE als auch in der Befehlszeile:

$global:myLogText = ""
function AddLog ($Message)
{
    $global:myLogText += ($Message)
}
AddLog ("Hello")
Write-Host $global:myLogText
14
da_jokker

Der erste Vorschlag in latkins Antwort erscheint gut, obwohl ich den weniger langatmigen Weg unten vorschlagen würde.

PS c:\temp> $global:test="one"

PS c:\temp> $test
one

PS c:\temp> function changet() {$global:test="two"}

PS c:\temp> changet

PS c:\temp> $test
two

Sein zweiter Vorschlag, schlechte Programmierpraxis zu sein, ist in einer einfachen Berechnung wie dieser ausreichend, aber was ist, wenn Sie eine kompliziertere Ausgabe aus Ihrer Variablen zurückgeben möchten? Was wäre beispielsweise, wenn Sie möchten, dass die Funktion ein Array oder ein Objekt zurückgibt? An diesem Punkt scheinen die PowerShell-Funktionen äußerst schmerzhaft zu sein. Das heißt, Sie haben keine andere Wahl, als die Funktion über eine globale Variable an die Funktion zurückzuleiten. Zum Beispiel:

PS c:\temp> function changet([byte]$a,[byte]$b,[byte]$c) {$global:[email protected](($a+$b),$c,($a+$c))}

PS c:\temp> changet 1 2 3

PS c:\temp> $test
3
3
4

PS C:\nb> $test[2]
4

Ich weiß, das fühlt sich vielleicht wie ein kleiner Exkurs an, aber ich denke, um die ursprüngliche Frage zu beantworten, müssen wir feststellen, ob globale Variablen schlechte Programmierpraxis sind und ob es bei komplexeren Funktionen einen besseren Weg gibt. (Wenn es einen gibt, wäre ich daran interessiert.)

1
AutoMattTick

@zdan. Gute Antwort. Ich würde es so verbessern ...

Ich denke, der beste Rückgabewert in PowerShell ist die Verwendung einer local -Variable , um den Wert zu übergeben, und niemals return, da dies durch irgendeine Art von Ausgabesituationen "beschädigt" werden kann

function CheckRestart([REF]$retval)
{
    # Some logic
    $retval.Value = $true
}
[bool]$restart = $false
CheckRestart( [REF]$restart)
if ( $restart )
{
    Restart-Computer -Force
}

Die Variable $restart wird auf beiden Seiten des Aufrufs der Funktion CheckRestart verwendet, wodurch der Gültigkeitsbereich der Variablen deutlich wird. Der Rückgabewert kann entweder der erste oder der letzte deklarierte Parameter sein. Ich bevorzuge das Letzte.

1
RobG

Für mich hat es funktioniert:

function changeA2 () { $global:A="0"}
changeA2
$A
0
user3360589