在带参数的函数上使用Invoke-Command -ScriptBlock

时间:2022-06-14 21:48:14

I'm writing a PowerShell script that will execute commands on a remote host using Invoke-Command and its -ScriptBlock parameter. For example,

我正在编写一个PowerShell脚本,它将使用Invoke-Command及其-ScriptBlock参数在远程主机上执行命令。例如,

function Foo {
    ...
    return "foo"
}
$rv = Invoke-Command --Credential $c --ComputerName $fqdn -ScriptBlock ${function:Foo}

This works fine. What I'd like to do now is the same thing, but call a function with local arguments. For example,

这很好用。我现在想做的是同样的事情,但用本地参数调用一个函数。例如,

function Bar {
    param( [String] $a, [Int] $b )
    ...
    return "foo"
}
[String] $x = "abc"
[Int] $y = 123
$rv = Invoke-Command --Credential $c --ComputerName $fqdn -ScriptBlock ${function:Foo($x,$y)}

But this does not work:

但这不起作用:

Invoke-Command : Cannot validate argument on parameter 'ScriptBlock'. The argument is null. Supply a non-null argument and try the command again.

Invoke-Command:无法验证参数'ScriptBlock'的参数。参数为null。提供非null参数并再次尝试该命令。

How can I use Invoke-Command with a -ScriptBlock that is a local function with arguments?

如何将Invoke-Command与带有参数的本地函数的-ScriptBlock一起使用?

I realize that I can wrap the entire function and the parameters in a big code block, but that is not a clean way of doing it, in my opinion.

我意识到我可以将整个函数和参数包装在一个大的代码块中,但在我看来,这不是一种干净的方式。

3 个解决方案

#1


42  

I think you want:

我想你想要:

function Foo ( $a,$b) {
    $a
    $b
    return "foo"
}

$x = "abc"
$y= 123

Invoke-Command -Credential $c -ComputerName $fqdn -ScriptBlock ${function:Foo} -ArgumentList $x,$y

#2


7  

You can wrap the functions in a block and pass the block;

您可以将函数包装在一个块中并传递该块;

$a = {
  function foo{}
  foo($args)
}

$a.invoke() // Locally

$rv = Invoke-Command --Credential $c --ComputerName $fqdn -ScriptBlock $a //remotely

It's hardly elegant though.

虽然这很不优雅。

#3


2  

This also works:

这也有效:

function foo
{
    param([string]$hosts, [string]$commands)
    $scriptblock = $executioncontext.invokecommand.NewScriptBlock($commands)
    $hosts.split(",") |% { Invoke-Command -Credential $cred -ComputerName $_.trim() -Scriptblock $scriptblock }
}

#1


42  

I think you want:

我想你想要:

function Foo ( $a,$b) {
    $a
    $b
    return "foo"
}

$x = "abc"
$y= 123

Invoke-Command -Credential $c -ComputerName $fqdn -ScriptBlock ${function:Foo} -ArgumentList $x,$y

#2


7  

You can wrap the functions in a block and pass the block;

您可以将函数包装在一个块中并传递该块;

$a = {
  function foo{}
  foo($args)
}

$a.invoke() // Locally

$rv = Invoke-Command --Credential $c --ComputerName $fqdn -ScriptBlock $a //remotely

It's hardly elegant though.

虽然这很不优雅。

#3


2  

This also works:

这也有效:

function foo
{
    param([string]$hosts, [string]$commands)
    $scriptblock = $executioncontext.invokecommand.NewScriptBlock($commands)
    $hosts.split(",") |% { Invoke-Command -Credential $cred -ComputerName $_.trim() -Scriptblock $scriptblock }
}