Search code examples
powershellclosurespowershell-2.0powershell-3.0jobs

Elegant way to get around scoping issues with powershell jobs


I have functions in separate files I need to run as jobs in one main file.

I need to be able to pass these functions arguments.

This is what I have:

testJobsMain.ps1:

$Functions = {
    . c:\.ps\func1.ps1
    . c:\.ps\func2.ps1
}

$arrOutput = @()
foreach($i in ('aaa','bbb','ccc','ddd','eee') ) {

    $ExecutionBlock = {
        FOO -myArg $i
        FOO2 -blah 'zzzzzzz'
    }

    $arrOutput += Start-Job -InitializationScript $Functions `
        -ScriptBlock $ExecutionBlock | 
            Wait-Job | Receive-Job
}

$arrOutput

func1.ps1

function FOO( $myArg ) { write-output $myArg }

func2.ps1

function FOO2( $blah ) { write-output $blah }

This is the output of testJobsMain.ps1:

PS> .\testjobsMain.ps1
zzzzzzz
zzzzzzz
zzzzzzz
zzzzzzz

It $i is not getting passed to the function. How can I do this?


Solution

  • You will have to pass it as parameter like this

    $ExecutionBlock = {
        param($passedI)
        FOO -myArg $passedI
        FOO2 -blah 'zzzzzzz'
    }
    $arrOutput += Start-Job -InitializationScript $Functions `
        -ScriptBlock $ExecutionBlock -ArgumentList $i | 
            Wait-Job | Receive-Job
    

    or use the using modifier (credits go to Eris) like so

    ...
    FOO -myArg $using:i
    ...