在一个复杂的脚本中,我有一堆重复相同模式的调用:准备,执行,清理。
只有执行部分不同,所以我只想定义一次准备和干净来电。
为了达到这个目的,我想把它包装在一个函数中,将执行部分作为参数传递。
我试过了:
function SomeFunc{
param(
[scriptblock]$Action,
[int]$x,
[int]$y
)
Write-Host "Before"
Invoke-Command -ScriptBlock $Action -PipelineVariable ($x*$y)
Write-Host "After"
}
SomeFunc -x 2 -y 4 -Action { Write-Host -ForegroundColor Yellow "Result is $_" }
但这不起作用。 $_
始终为空。
我如何实现目标?
答案 0 :(得分:1)
您可以不通过管道传递ScriptBlock的参数,而是将数组中的参数作为ArgumentList
cmdlet的Invoke-Command
参数传递。然后,您将能够通过$''进程中的$ args变量访问参数。脚本块。
function SomeFunc {
param ($x, $y, $sb)
Write-Host "Before";
Invoke-Command -ScriptBlock $sb -ArgumentList @("Some string", $x, ($x * $y))
Write-Host "After";
}
SomeFunc -x 4 -y 2 -sb { foreach ($a in $args) { Write-Host ("Parameter: $a") } }
输出为
Before
Parameter: Some string
Parameter: 4
Parameter: 8
After
您还可以在ScriptBlock中包含param()
块。这种方式允许您轻松地对参数进行其他限制,例如强类型
function SomeFunc {
param ($x, $y, $sb)
Write-Host "Before";
Invoke-Command -ScriptBlock $sb -ArgumentList @("Not x", $y, ($x * $y));
Write-Host "After";
}
SomeFunc -x 4 -y 2 -sb { param ([int]$a, $b, $c) Write-Host ("a is {0}, c is {1}, b is {2}" -f $a, $c, $b)}
输出显示错误
Before
Invoke-Command : Cannot convert value "Not x" to type "System.Int32". Error: "Input string was not in a correct format."
At line:4 char:5
+ Invoke-Command -ScriptBlock $sb -ArgumentList @("Not x", $y, ($x * $y));
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], PSInvalidCastException
+ FullyQualifiedErrorId : InvalidCastFromStringToInteger,Microsoft.PowerShell.Commands.InvokeCommandCommand
After
答案 1 :(得分:0)
如果你真的不需要传递给它,你可以使用一个设置的变量:
function SomeFunc{
param(
[scriptblock]$Action,
[int]$x,
[int]$y
)
$s = $x*$y
Invoke-Command -ScriptBlock $Action
}
[scriptblock]$sb = { Write-Host -ForegroundColor Yellow "Result is $s" }
SomeFunc -x 2 -y 4 -Action $sb