A D
A D

Reputation: 25

Increment a variable in a job

I want to increment a variable in a PowerShell job with a number defined before the job starts.

I tried with a global variable but it didn't work, so now I try to write in a file and load it in my job but that didn't work either. I summarize my loop:

$increment = 1
$Job_Nb = 1..3

foreach ($nb in $Job_Nb) {
    $increment > "C:\increment.txt"

    Start-Job -Name $nb -ScriptBlock {
        $increment_job = Get-Content -Path "C:\increment.txt"
        $increment_job
    }

    $increment++
}

I want my 2 variables $increment_job and $increment to be equal. I obtain the good result with the command Wait-Job, like that:

$increment = 1
$Job_Nb = 1..3

foreach ($nb in $Job_Nb) {
    $increment > "C:\increment.txt"

    Start-Job -Name $nb -ScriptBlock {
        $increment_job = Get-Content -Path "C:\increment.txt"
        $increment_job
    } | Wait-Job | Receive-Job

    $increment++
}

But I can't wait each job to finish before starting the next, it's too long... I need to execute a lot of jobs in the background.

For me, even $nb, $increment and $increment_job can be equal.

If it can help you to understand, a really simple way to put it:

$nb = 1
$Job_Nb = 1..3
foreach ($nb in $Job_Nb) {
    Start-Job -Name $nb -ScriptBlock {$nb}
    $nb++
}

Upvotes: 0

Views: 359

Answers (1)

AdminOfThings
AdminOfThings

Reputation: 25031

If you want the two variables to be equal, you can just pass $increment into your script block as an argument.

# Configure the Jobs
$increment = 1
$Job_Nb = 1..3

Foreach ($nb in $Job_Nb) {

    Start-Job -Name $nb -ScriptBlock {
      $increment_job = $args[0]
      $increment_job
    } -ArgumentList $increment

$increment++
}

# Retrieve the Jobs After Waiting For All to Complete
Wait-Job -Name $job_nb | Receive-Job

The problem with your initial approach as you have discovered is that PowerShell processes the entire loop before a single job completes. Therefore, the job doesn't read the increment.txt file until after its contents are set to 3.

Passing values into the -ArgumentList parameter of a script block without a parameter block will automatically assign the arguments to the $args array. Space delimited arguments will each become an element of the array. A value not space-separated can simply be retrieved as $args or $args[0] with the difference being $args will return a type of Object[] and $args[0] will return the type of the data you passed into it.

Obviously, you do not need to wait for all jobs to complete. You can just use Get-Job to retrieve whichever jobs you want at any time.

Upvotes: 1

Related Questions