2011-12-09 9 views
25

私はInvoke-Commandとその-ScriptBlockパラメータを使用してリモートホスト上でコマンドを実行するPowerShellスクリプトを作成しています。たとえば、引数のある関数でのInvoke-Command -ScriptBlockの使用

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

これは問題なく動作します。私が今やりたいことは同じことですが、ローカル引数で関数を呼び出します。例えば、

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

しかし、これは動作しません:

Invoke-Commandコマンド:パラメーター 'のScriptBlock' に引数を検証することはできません。 引数がnullです。ヌル以外の引数を指定して、 コマンドを再度実行してください。

引数を持つローカル関数である-ScriptBlockでInvoke-Commandを使用するにはどうすればよいですか?

大規模なコードブロックで関数とパラメータ全体をラップすることができることはわかっていますが、これはきれいな方法ではありません。

答えて

41

私はあなたがしたいと思う:

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

ありがとう、完璧に動作します!私は運がないparam()+ -Argumentsのコンボを使いこなしていました。 –

+0

はこのソリューションを見つけるのに数時間かかりました; セッションのエクスポート/インポートよりもずっと優れています ありがとうございました! – icnivad

+0

正しいフォーマットは '-ScriptBlock {$ function:Foo}'( '$'の位置に注意してください)としてください。 – Mourndark

7

ブロック内の関数をラップしてブロックを渡すことができます。

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

$a.invoke() // Locally 

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

でも、それほど優雅です。

+0

を。 –

2

また、これは動作します:私はこの問題を回避したいと思います

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