Uso de Invoke-Command-ScriptBlock en una función con argumentos


Estoy escribiendo un script de PowerShell que ejecutará comandos en un host remoto utilizando Invoke-Command y su parámetro -ScriptBlock. Por ejemplo,

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

Esto funciona bien. Lo que me gustaría hacer ahora es lo mismo, pero llamar a una función con argumentos locales. Por ejemplo,

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

Pero esto no funciona:

Invoke-Command : No se puede validar el argumento en el parámetro 'ScriptBlock'. El argumento es null. Proporcione un argumento no nulo y pruebe el comando nuevo.

¿Cómo puedo usar Invoke-Command con una -ScriptBlock que es una función local con argumentos?

Me doy cuenta de que puedo envolver toda la función y los parámetros en un gran bloque de código, pero esa no es una forma limpia de hacerlo, en mi opinión.

Author: Peter Mortensen, 2011-12-09

3 answers

Creo que quieres:

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

$x = "abc"
$y= 123

Invoke-Command -Credential $c -ComputerName $fqdn -ScriptBlock ${function:Foo} -ArgumentList $x,$y
 42
Author: manojlds,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 17:17:51

Puede envolver las funciones en un bloque y pasar el bloque;

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

$a.invoke() // Locally

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

Aunque no es elegante.

 7
Author: reconbot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-09 17:10:31

Esto también funciona:

function foo
{
    param([string]$hosts, [string]$commands)
    $scriptblock = $executioncontext.invokecommand.NewScriptBlock($commands)
    $hosts.split(",") |% { Invoke-Command -Credential $cred -ComputerName $_.trim() -Scriptblock $scriptblock }
}
 2
Author: prophesional,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-15 12:49:29