webentwicklung-frage-antwort-db.com.de

Verwenden von Invoke-Command -ScriptBlock für eine Funktion mit Argumenten

Ich schreibe ein PowerShell-Skript, das Befehle auf einem Remote-Host mithilfe von Invoke-Command und seinem Parameter -ScriptBlock Ausführt. Beispielsweise,

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

Das funktioniert gut. Was ich jetzt tun möchte, ist dasselbe, aber eine Funktion mit lokalen Argumenten aufrufen. Beispielsweise,

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

Das geht aber nicht:

Invoke-Command: Argument für Parameter 'ScriptBlock' kann nicht validiert werden. Das Argument ist null. Geben Sie ein Argument ein, das nicht null ist, und wiederholen Sie den Befehl.

Wie kann ich Invoke-Command mit einem -ScriptBlock Verwenden, das eine lokale Funktion mit Argumenten ist?

Mir ist klar, dass ich die gesamte Funktion und die Parameter in einen großen Codeblock packen kann, aber das ist meiner Meinung nach keine saubere Methode.

28

Ich denke du willst:

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

$x = "abc"
$y= 123

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

Sie können die Funktionen in einen Block einschließen und den Block übergeben.

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

$a.invoke() // Locally

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

Es ist jedoch kaum elegant.

7
reconbot

Das funktioniert auch:

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