开发者

Resolve PowerShell Function Parameter Values Among Parameters

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 t开发者_如何学Che 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?


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


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!


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜