解析参数中的 PowerShell 函数参数值

发布于 2024-12-06 08:01:08 字数 781 浏览 1 评论 0原文

我试图弄清楚在将包含另一个参数值的参数传递给函数时如何强制 PowerShell 运行时以表达式模式解析字符串。例如,我想将两个参数传递给一个函数,其中第二个参数使用第一个参数的值。我知道我需要让解析器在表达式模式下评估第二个参数值,但输出似乎无法解析第一个参数的值。

PowerShell 命令#1 此示例按预期工作,并证明当使用 2 + 2 周围的子表达式时,该命令是在表达式模式下计算的

& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $(2 + 2)"

输出

foo
Test 1 value: 4

PowerShell 命令 #2 现在,当我尝试相同的操作以使参数二 ($test2) 引用参数一 ($test1) 的值时,表达式似乎不会被计算,或者至少 $test1 的值是空白或 null。

& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $($test1)"

输出

foo
Test 1 value:

请注意,当我认为 Test 1 值应该是“foo”(在 $test1 参数中传递的值)时,它是空白的。关于 PowerShell 函数中的参数范围,我缺少什么?为什么 $test1 值无法在作为 $test2 值传递的表达式中引用?有没有更优雅的方法来做到这一点?

I'm trying to figure out how to force the PowerShell runtime to parse a string in expression mode when passing a parameter that includes another parameter's value to a function. For example, I want to pass two parameters to a function with the second parameter using the first parameter's value. I know I need to have the parser evaluate the second parameter value in expression mode but the output doesn't seem to resolve the first parameter's value.

PowerShell Command #1
This example works as desired and proves the command is evaluated in expression mode when using a sub-expression around 2 + 2

& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $(2 + 2)"

Output

foo
Test 1 value: 4

PowerShell Command #2
Now when I try the same things to have parameter two ($test2) reference the value for parameter one ($test1), the expression doesn't seem to be evaluated or at least the value for $test1 is blank or null.

& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $($test1)"

Output

foo
Test 1 value:

Note how the Test 1 value is blank when I think it should be "foo", the value passed in the $test1 parameter. What am I missing about parameter scope in a PowerShell function? Why is the $test1 value not available to be referenced in the expression passed as the value for $test2? Is there a more elegant way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

2024-12-13 08:01:08

这是因为在将参数传递给脚本块之前,“表达式”是在脚本块外部求值的。

所以像这样的东西:

$test1 = 4
& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $($test1)"

将给出输出:

foo
Test 1 value: 4

解决方法:

& { param($test1,$test2); $test1; & $test2 } "foo" {"Test 1 value: $test1"}

但我想在实际情况下,您不想更改正在使用的脚本块(或函数等)。

我也会质疑这种情况的必要性,因为你真正想做的是:

$test1 = "foo"
$test2 = "Test 1 value: $test1"
& { param($test1,$test2); $test1; $test2 } $test1 $test2

This is because the "expression" is evaluated outside the scriptblock, before even passing the arguments to the scriptblock.

So something like:

$test1 = 4
& { param($test1,$test2); $test1; $test2 } "foo" "Test 1 value: $($test1)"

will give the output:

foo
Test 1 value: 4

Workarounds:

& { param($test1,$test2); $test1; & $test2 } "foo" {"Test 1 value: $test1"}

But I suppose in the real situation, you wouldn't want to change the scriptblock ( or function etc. ) you are working with.

I would also question the need for this situation, as what you really want to do is this:

$test1 = "foo"
$test2 = "Test 1 value: $test1"
& { param($test1,$test2); $test1; $test2 } $test1 $test2
も让我眼熟你 2024-12-13 08:01:08

感谢您的回复,这有助于澄清一些事情。最终,我想将参数从数据库传递给脚本。参数值包括对其他 PowerShell 参数的引用,并且在脚本运行之前无法解析它们。我正在 IIS 中运行 PowerShell 运行空间,但我无法弄清楚如何强制解析器使用标准的“”字符来计算表达式。

唉,我发现 PowerShell 中的 $ExecutionContext.InvokeCommand.ExpandString() 函数完全可以满足我的需要。该函数实际上是通过“”字符在幕后执行的,如 http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-12-command-discovery-and-scriptblocks.aspx#executioncontext

完成我想要的操作需要一些额外的工作,但我能够使用以下模式来解析脚本中的值。这会强制解析器在表达式模式下重新计算 $test2 并执行变量替换,从而生成包含正确变量值的字符串。

$test2 = $ExecutionContext.InvokeCommand.ExpandString($test2)

再次感谢您的意见和指导!

Thanks for the responses and that helps clarify some things. Ultimately, I want to pass parameters to a script from a database. The parameter values include references to other PowerShell parameters and they can't be resolved until the script runs. I'm running a PowerShell runspace in IIS and I couldn't figure out how to force the parser to evaluate an expression using the standard "" characters.

Alas, I found the $ExecutionContext.InvokeCommand.ExpandString() function in PowerShell that does exactly what I need. This function actually is executed under the covers by the "" characters as documented at http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-12-command-discovery-and-scriptblocks.aspx#executioncontext.

It takes a little extra work to do what I want but I was able to use the following pattern to resolve the values in the script. This forces the parser to re-evaluate $test2 in expression mode and perform the variable subsitution, resulting in a string that includes the proper variable values.

$test2 = $ExecutionContext.InvokeCommand.ExpandString($test2)

Thanks again for the comments and guidance!

ι不睡觉的鱼゛ 2024-12-13 08:01:08

让我想起 schema\lisp!您可以在该语言中将函数作为参数传递 - 我不知道您是否可以在 PS 中将脚本块作为参数传递。

无论如何,引用变量的名称有什么关系吗?

如果没有,您只想引用第一个变量(或您选择的变量),您可以执行以下操作:

 & { $args[0]; $args[1]; "Value of arg #$($args[1]): $($args[$($args[1])])"} "foo" "0"

与其他多个变量一起使用:

& { $args[0]; $args[1]; "Value of arg #$($args[1]): $($args[$($args[1])])"} "foo" "3" 23 24 25 26

reminds me of schema\lisp! You can pass functions as parameters in that language - I don't know if you can pass a scriptblock as a parameter in PS though.

Anyway, does it matter what that you refer to the name of the variable?

If not and you just want to refer to the first variable (or the variable of your choice) you could do something like this:

 & { $args[0]; $args[1]; "Value of arg #$($args[1]): $($args[$($args[1])])"} "foo" "0"

works with other multiple variables:

& { $args[0]; $args[1]; "Value of arg #$($args[1]): $($args[$($args[1])])"} "foo" "3" 23 24 25 26
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文