web-dev-qa-db-fra.com

Utilisation d'Invoke-Command -ScriptBlock sur une fonction avec des arguments

J'écris un script PowerShell qui exécutera des commandes sur un hôte distant en utilisant Invoke-Command et son -ScriptBlock paramètre. Par exemple,

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

Cela fonctionne bien. Ce que je voudrais faire maintenant, c'est la même chose, mais appelez une fonction avec des arguments locaux. Par exemple,

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

Mais cela ne fonctionne pas:

Invoke-Command: Impossible de valider l'argument sur le paramètre 'ScriptBlock'. L'argument est nul. Fournissez un argument non nul et essayez à nouveau la commande.

Comment puis-je utiliser Invoke-Command avec un -ScriptBlock c'est une fonction locale avec des arguments?

Je me rends compte que je peux envelopper toute la fonction et les paramètres dans un gros bloc de code, mais ce n'est pas une façon propre de le faire, à mon avis.

28
Christopher Neylan

Je pense que tu veux:

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

Vous pouvez envelopper les fonctions dans un bloc et passer le bloc;

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

$a.invoke() // Locally

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

C'est à peine élégant cependant.

7
reconbot

Cela fonctionne également:

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