Reputation: 8292
I'm writing a PowerShell script that will execute commands on a remote host using Invoke-Command and its -ScriptBlock
parameter. For example,
function Foo {
...
return "foo"
}
$rv = Invoke-Command --Credential $c --ComputerName $fqdn -ScriptBlock ${function:Foo}
This works fine. What I'd like to do now is the same thing, but call a function with local arguments. For example,
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)}
But this does not work:
Invoke-Command : Cannot validate argument on parameter 'ScriptBlock'. The argument is null. Supply a non-null argument and try the command again.
How can I use Invoke-Command with a -ScriptBlock
that is a local function with arguments?
I realize that I can wrap the entire function and the parameters in a big code block, but that is not a clean way of doing it, in my opinion.
Upvotes: 30
Views: 86166
Reputation: 1
$Log = "PowerShellCore/Operational"
Invoke-Command -ComputerName Server01 -ScriptBlock {Get-WinEvent -LogName $Using:Log -MaxEvents 10}\
Upvotes: 0
Reputation: 21
This also works:
function foo
{
param([string]$hosts, [string]$commands)
$scriptblock = $executioncontext.invokecommand.NewScriptBlock($commands)
$hosts.split(",") |% { Invoke-Command -Credential $cred -ComputerName $_.trim() -Scriptblock $scriptblock }
}
Upvotes: 2
Reputation: 301607
I think you want:
function Foo ( $a,$b) {
$a
$b
return "foo"
}
$x = "abc"
$y= 123
Invoke-Command -Credential $c -ComputerName $fqdn -ScriptBlock ${function:Foo} -ArgumentList $x,$y
Upvotes: 53
Reputation: 5297
You can wrap the functions in a block and pass the block;
$a = {
function foo{}
foo($args)
}
$a.invoke() // Locally
$rv = Invoke-Command --Credential $c --ComputerName $fqdn -ScriptBlock $a //remotely
It's hardly elegant though.
Upvotes: 9