Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I pass a scriptblock as one of the parameters in start-job

Tags:

I'm trying to create a background job, which executes a scriptblock. I need to pass this scriptblock in as a parameter, but I can't seem to get the syntax to work. The scriptblock is being converted to a string somewhere along the way.

It works fine when I pass the script block to a local function, but not through start-job

The following syntax works:

function LocalFunction
{
    param (
        [parameter(Mandatory=$true)]
        [ScriptBlock]$ScriptBlock
    )

    &$ScriptBlock | % { echo "got $_" }
}

LocalFunction -ScriptBlock { echo "hello" }

This outputs "got hello" as expected.

But the following fails:

$job = start-job -argumentlist { echo "hello" } -scriptblock {
    param (
        [parameter(Mandatory=$true)]
        [ScriptBlock]$ScriptBlock
    )
    &$ScriptBlock | % { echo "got $_" }
}
start-sleep -s 1
receive-job $job

The error it returns is

Receive-Job : Cannot process argument transformation on parameter 'ScriptBlock'. Cannot convert the " echo "hello" " value of type "System.String" to type "System.Management.Automation.ScriptBlock".

So if I'm reading the error right, it appears that -argumentlist is somehow forcing its arguments into strings.

Any powershell gurus know how to make this syntax work?

Thanks in advance,

Ben

like image 944
ben Avatar asked Aug 07 '12 10:08

ben


1 Answers

Here's one way to solve this, pass the scriptblock code as a string, then create a scriptblock from the string inside the job and execute it

Start-Job -ArgumentList "write-host hello"  -scriptblock {

    param (
        [parameter(Mandatory=$true)][string]$ScriptBlock
    )

    & ([scriptblock]::Create($ScriptBlock))

} | Wait-Job | Receive-Job
like image 102
Shay Levy Avatar answered Sep 24 '22 20:09

Shay Levy