3

Assuming Get-Foo and Get-Foo2 and Deploy-Jobs are 3 functions that are part of a very large module. I would like to use Get-Foo and Get-Foo2 in Deploy-Jobs's Start-ThreadJob (below) without reloading the entire module each time.

Is an working example available for how to do this?

function Deploy-Jobs {

    foreach ($Device in $Devices) {

        Start-ThreadJob -Name $Device -ThrottleLimit 50 -InitializationScript $initScript -ScriptBlock {
            param($Device)

            Get-Foo | Get-Foo2 -List
        
        } -ArgumentList $Device | out-null
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
MKANET
  • 573
  • 6
  • 27
  • 51
  • Hopefully the linked duplicate explains what you need to do to overcome this. – Santiago Squarzon Apr 15 '22 at 02:19
  • 1
    Thank you. However, I can't figure out how to use function with normal PS Verb-Noun functions that use hyphens instead of using `CustomFunction` – MKANET Apr 15 '22 at 17:52
  • 1
    I'm not sure if I need to open another question to ask how to do this. I really would like to know. – MKANET Apr 15 '22 at 17:53
  • You can use curly braces, like this: `${function:Verb-Noun}` – Santiago Squarzon Apr 15 '22 at 17:57
  • I added another link to duplicates that shows this, give that one a look and let me know if you're able to follow it (the last example from the answer is the one that you need to follow) – Santiago Squarzon Apr 15 '22 at 18:04
  • Thank you so much for the quick reply. Just one more question.... Im still not sure how to get `${function:Verb-Noun} = $using:funcDef` within `Start-ThreadJob`. I would really appreciate an example. All the examples use `ForEach-Object -Parallel`; which I can't use and not familiar with. – MKANET Apr 15 '22 at 18:04
  • You can also follow the example from the other linked duplicated that shows how you can pass 2 functions at once – Santiago Squarzon Apr 15 '22 at 18:08
  • I'd really appreciate an example using `Start-ThreadJob` to do this. I'm not sure if I need to use `-InitializationScript` or what I need to do in order to get the function within `Start-ThreadJob`. I don't have any experience with `ForEach-Object -Parallel`; and, can't use it anyway. – MKANET Apr 15 '22 at 18:14

1 Answers1

3

The method you can use to pass the function's definition to a different scope is the same for Invoke-Command (when PSRemoting), Start-Job, Start-ThreadJob and ForeEach-Object -Parallel. Since you want to invoke 2 different functions in your job's script block, I don't think -InitializationScript is an option, and even if it is, it might make the code even more complicated than it should be.

You can use this as an example of how you can store 2 function definitions in an array ($def), which is then passed to the scope of each TreadJob, this array is then used to define each function in said scope to be later used by each Job.

function Say-Hello {
    "Hello world!"
}

function From-ThreadJob {
    param($i)
    "From ThreadJob # $i"
}

$def = @(
    ${function:Say-Hello}.ToString()
    ${function:From-ThreadJob}.ToString()
)

function Run-Jobs {
    param($numerOfJobs, $functionDefinitions)

    $jobs = foreach($i in 1..$numerOfJobs) {
        Start-ThreadJob -ScriptBlock {
            # bring the functions definition to this scope
            $helloFunc, $threadJobFunc = $using:functionDefinitions
            # define them in this scope
            ${function:Say-Hello} = $helloFunc
            ${function:From-ThreadJob} = $threadJobFunc
            # sleep random seconds
            Start-Sleep (Get-Random -Maximum 10)
            # combine the output from both functions
            (Say-Hello) + (From-ThreadJob -i $using:i)
        }
    }

    Receive-Job $jobs -AutoRemoveJob -Wait
}

Run-Jobs -numerOfJobs 10 -functionDefinitions $def
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37