从函数中设置全局PowerShell变量,其中全局变量名是传递给函数的变量

时间:2022-06-01 16:44:37

I need to set a global variable from a function and am not quite sure how to do it.

我需要从函数设置一个全局变量,我不太清楚如何做到这一点。

# 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
}

Call the function:

调用函数:

foo 1 2 $global:var3

End result:

最终结果:

$global:var3 is set to 3

$ global:var3设置为3

Or if I called the function like this:

或者如果我这样调用函数:

foo 1 2 $global:var2

End result:

最终结果:

$global:var2 is set to 3

$ global:var2设置为3

I hope this example makes sense. The third variable passed to the function is the name of the variable it is to set.

我希望这个例子有意义。传递给函数的第三个变量是要设置的变量的名称。

7 个解决方案

#1


72  

You can use the Set-Variable cmdlet. Passing $global:var3 sends the value of $var3, which is not what you want. You want to send the name.

您可以使用Set-Variable cmdlet。传递$ global:var3发送$ var3的值,这不是你想要的。你想发送名字。

$global:var1 = $null

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

foo 1 2 var1

This is not very good programming practice, though. Below would be much more straightforward, and less likely to introduce bugs later:

不过,这不是很好的编程习惯。下面会更简单,以后不太可能引入错误:

$global:var1 = $null

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

$global:var1 = ComputeNewValue 1 2

#2


35  

As simple as:

很简单:

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

#3


14  

You'll have to pass your arguments as reference types.

您必须将参数作为引用类型传递。

#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

#4


9  

I ran across this question while troubleshooting my own code.

我在对自己的代码进行故障排除时遇到了这个问题

So this does NOT work...

所以这不起作用......

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

This APPEARS to work, but only in the PowerShell ISE:

这个APPEARS可以工作,但只能在PowerShell ISE中使用:

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

This is actually what works in both ISE and command line:

这实际上适用于ISE和命令行:

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

#5


1  

@zdan. Good answer. I'd improve it like this... I think that the closest you can come to a true return value in PoSH is to use a local variable to pass the value and never to use return as it may be 'corrupted' by any manner of output situations

@zdan。好答案。我会像这样改进它...我认为在PoSH中最接近真正的返回值是使用局部变量来传递值而永远不会使用返回,因为它可能被任何方式“损坏”输出情况

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

The $restart variable is used either side of the call to the function CheckRestart making clear the scope of the variable. The return value can by convention be either the first or last parameter declared. I prefer last.

$ restart变量用于调用函数CheckRestart的任一侧,以明确变量的范围。按照惯例,返回值可以是声明的第一个或最后一个参数。我最后喜欢。

#6


1  

Unfortunately I can't comment on latkin's answer because of reputation so I had to add my own answer. His first suggestion seems good, although I would suggest the less long-winded way below.

不幸的是,由于声誉,我无法对latkin的答案发表评论所以我不得不添加自己的答案。他的第一个建议似乎很好,虽然我建议下面不那么冗长的方式。

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

His 2nd suggestion however about being bad programming practice, is fair enough in a simple computation like this one, but what if you want to return a more complicated output from your variable? For example what if you wanted the function to return an array or an object? That's where, for me, powershell functions seem to fail woefully. Meaning you have no choice other than to pass it back from the function using a global variable. For example:

然而,他的第二个建议是关于编程实践不好,在这样的简单计算中是公平的,但是如果你想从变量返回更复杂的输出呢?例如,如果您希望函数返回数组或对象,该怎么办?对我来说,这就是powershell功能似乎失败的地方。这意味着除了使用全局变量从函数传回它之外别无选择。例如:

PS c:\temp> function changet([byte]$a,[byte]$b,[byte]$c) {$global:test=@(($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

I know this might feel like a bit of a digression, but I feel in order to answer the original question we need to establish whether global variables are bad programming practice and whether, in more complex functions, there is a better way. (If there is one I'd be interested to here it.)

我知道这可能感觉有点像题外话,但我觉得为了回答原始问题,我们需要确定全局变量是否是错误的编程实践,以及在更复杂的函数中是否有更好的方法。 (如果有的话我会对它感兴趣。)

#7


0  

For me it worked:

对我来说它有效:

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

#1


72  

You can use the Set-Variable cmdlet. Passing $global:var3 sends the value of $var3, which is not what you want. You want to send the name.

您可以使用Set-Variable cmdlet。传递$ global:var3发送$ var3的值,这不是你想要的。你想发送名字。

$global:var1 = $null

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

foo 1 2 var1

This is not very good programming practice, though. Below would be much more straightforward, and less likely to introduce bugs later:

不过,这不是很好的编程习惯。下面会更简单,以后不太可能引入错误:

$global:var1 = $null

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

$global:var1 = ComputeNewValue 1 2

#2


35  

As simple as:

很简单:

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

#3


14  

You'll have to pass your arguments as reference types.

您必须将参数作为引用类型传递。

#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

#4


9  

I ran across this question while troubleshooting my own code.

我在对自己的代码进行故障排除时遇到了这个问题

So this does NOT work...

所以这不起作用......

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

This APPEARS to work, but only in the PowerShell ISE:

这个APPEARS可以工作,但只能在PowerShell ISE中使用:

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

This is actually what works in both ISE and command line:

这实际上适用于ISE和命令行:

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

#5


1  

@zdan. Good answer. I'd improve it like this... I think that the closest you can come to a true return value in PoSH is to use a local variable to pass the value and never to use return as it may be 'corrupted' by any manner of output situations

@zdan。好答案。我会像这样改进它...我认为在PoSH中最接近真正的返回值是使用局部变量来传递值而永远不会使用返回,因为它可能被任何方式“损坏”输出情况

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

The $restart variable is used either side of the call to the function CheckRestart making clear the scope of the variable. The return value can by convention be either the first or last parameter declared. I prefer last.

$ restart变量用于调用函数CheckRestart的任一侧,以明确变量的范围。按照惯例,返回值可以是声明的第一个或最后一个参数。我最后喜欢。

#6


1  

Unfortunately I can't comment on latkin's answer because of reputation so I had to add my own answer. His first suggestion seems good, although I would suggest the less long-winded way below.

不幸的是,由于声誉,我无法对latkin的答案发表评论所以我不得不添加自己的答案。他的第一个建议似乎很好,虽然我建议下面不那么冗长的方式。

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

His 2nd suggestion however about being bad programming practice, is fair enough in a simple computation like this one, but what if you want to return a more complicated output from your variable? For example what if you wanted the function to return an array or an object? That's where, for me, powershell functions seem to fail woefully. Meaning you have no choice other than to pass it back from the function using a global variable. For example:

然而,他的第二个建议是关于编程实践不好,在这样的简单计算中是公平的,但是如果你想从变量返回更复杂的输出呢?例如,如果您希望函数返回数组或对象,该怎么办?对我来说,这就是powershell功能似乎失败的地方。这意味着除了使用全局变量从函数传回它之外别无选择。例如:

PS c:\temp> function changet([byte]$a,[byte]$b,[byte]$c) {$global:test=@(($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

I know this might feel like a bit of a digression, but I feel in order to answer the original question we need to establish whether global variables are bad programming practice and whether, in more complex functions, there is a better way. (If there is one I'd be interested to here it.)

我知道这可能感觉有点像题外话,但我觉得为了回答原始问题,我们需要确定全局变量是否是错误的编程实践,以及在更复杂的函数中是否有更好的方法。 (如果有的话我会对它感兴趣。)

#7


0  

For me it worked:

对我来说它有效:

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