2011-12-09 14 views
25

Sto scrivendo uno script PowerShell che eseguirà i comandi su un host remoto utilizzando Invoke-Command e il suo parametro -ScriptBlock. Ad esempio,Utilizzo di Invoke-Command -ScriptBlock su una funzione con argomenti

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

Questo funziona correttamente. Quello che mi piacerebbe fare ora è la stessa cosa, ma chiamare una funzione con argomenti locali. Ad esempio,

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

Ma questo non funziona:

Invoke-Command: Impossibile convalidare l'argomento del parametro 'ScriptBlock'. L'argomento è nullo. Fornire un argomento non nullo e provare di nuovo il comando .

Come è possibile utilizzare Invoke-Command con un -ScriptBlock che è una funzione locale con argomenti?

Mi rendo conto che posso avvolgere l'intera funzione ei parametri in un grande blocco di codice, ma non è un modo pulito di farlo, secondo me.

risposta

41

Penso che si desidera:

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

$x = "abc" 
$y= 123 

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

grazie amico, funziona perfettamente! Stavo scherzando con le combinazioni di param() + -Arguments senza fortuna. –

+0

mi ci sono volute diverse ore per trovare questa soluzione ;-) Molto meglio di esportare/importare sessioni Grazie! – icnivad

+0

Credo che il formato corretto dovrebbe essere '-ScriptBlock {$ function: Foo}' (nota '$ posizione') – Mourndark

7

È possibile disporre le funzioni in un blocco e passare il blocco;

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

$a.invoke() // Locally 

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

Tuttavia, non è elegante.

+0

vorrei evitare questo. –

2

questo funziona anche:

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