2011-12-09 11 views
25

Piszę skrypt PowerShell, który będzie wykonywać polecenia na zdalnym hoście przy użyciu parametru Invoke-Command i jego parametru -ScriptBlock. Na przykład:Używanie polecenia-wywołania -ScriptBlock w funkcji z argumentami

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

Działa to dobrze. To, co chciałbym teraz zrobić, to to samo, ale zadzwoń do funkcji z lokalnymi argumentami. Na przykład,

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

Ale to nie działa:

Invoke-Command: Nie można zweryfikować tezę o parametrze 'ScriptBlock'. Argument ma wartość zerową. Podaj argument o wartości innej niż NULL i ponownie wypróbuj komendę .

Jak mogę używać Invoke-Command z -ScriptBlock że jest lokalnym funkcji z argumentami?

Zdaję sobie sprawę, że mogę zawinąć całą funkcję i parametry w dużym bloku kodu, ale to nie jest czysty sposób robienia tego, moim zdaniem.

Odpowiedz

41

Myślę, że chcesz:

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

dzięki człowiek, działa idealnie! Zmywałem kombinacje param() + -Arguments bez powodzenia. –

+0

zajęło mi kilka godzin, aby znaleźć to rozwiązanie ;-) Znacznie lepiej niż eksportowanie/importowanie sesji Dziękujemy! – icnivad

+0

Uważam, że poprawnym formatem powinna być "-ScriptBlock {$ function: Foo}' (uwaga '$' position) – Mourndark

7

Możesz zawinąć funkcje w bloku i przekazać blok;

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

$a.invoke() // Locally 

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

To jednak nie jest eleganckie.

+0

Chciałbym tego uniknąć. –

2

Działa to również:

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