Search code examples
arrayspowershelljobs

Start-Job -ScriptBlock: Retrieving an array that is compiled inside the ScriptBlock


I have a Foreach loop inside a ScriptBlock that builds an array. I cannot figure out how to retrieve the array from the Job once it's finished.

Here is my current code.

$HSMissingEmail = New-Object System.Collections.ArrayList
$HSDataObjects = New-Object System.Collections.ArrayList

$HSMissingEmail = Start-Job -Name HSMissingEmailStatus -ScriptBlock {
    param($HSDataObjects, $HSMissingEmail);
    foreach ($HSDO in $HSDataObjects) {
      $HSDO = $HSDO | Select-Object Name, Location, Telephone, EmailAddress, Comments;
      if ($HSDO | Where-Object {$_.EmailAddress -like ""}) {
        $HSMissingEmail.Add($HSDO)
      }
    }
  } -HSDataObjects $HSDataObjects -HSMissingEmail $HSMissingEmail | Receive-Job -Name HSMissingEmailStatus

I've also tried the following but it didn't do anything either.

$HSMissingEmail = New-Object System.Collections.ArrayList
$HSDataObjects = New-Object System.Collections.ArrayList

$ScriptBlock = 
    {
        param($HSDataObjects,$HSMissingEmail)
        foreach ($HSDO in $HSDataObjects)
        {
            $HSDO = $HSDO | Select-Object Name, Location, Telephone, EmailAddress, Comments

            if ($HSDO | Where-Object {$_.emailaddress -like ""})
                {
                    $HSMissingEmail.Add($HSDO)
                }
        }
    }
    Start-Job -Name HSMissingEmailStatus -ScriptBlock $ScriptBlock -HSDataObjects $HSDataObjects -HSMissingEmail $HSMissingEmail
    ProgressBar ([REF]$HSMissingEmailStatus)
    $HSMissingEmail = Receive-Job -Name HSMissingEmailStatus
    Get-job -Name HSMissingEmailStatus | Remove-Job

I have tried many different ways to form the ScriptBlock but none are returning anything to $HSMissingEmail.

Also the second block of code doesn't get the passed data until I make the ScriptBlock all one line, which I'm unsure if this is a default behavior.

How can I retrieve the array?


Solution

  • You need to write the array out to standard out.

    $HSMissingEmail = New-Object System.Collections.ArrayList
    $HSDataObjects = New-Object System.Collections.ArrayList
    
    $HSMissingEmail = Start-Job -Name HSMissingEmailStatus -ScriptBlock {
        param($HSDataObjects, $HSMissingEmail);
        foreach ($HSDO in $HSDataObjects) {
          $HSDO = $HSDO | Select-Object Name, Location, Telephone, EmailAddress, Comments;
          if ($HSDO | Where-Object {$_.EmailAddress -like ""}) {
            $HSMissingEmail.Add($HSDO)
          }
        }
        $HSMissingEmail    # Drops it out as a result of the script block
      } -HSDataObjects $HSDataObjects -HSMissingEmail $HSMissingEmail
    Receive-Job -Name HSMissingEmailStatus -Wait  # At the appropriate time, or keep cycling until you get it all
    

    As far as the single-line/multiline bit, it might be a problem with not explicitly typing the variable as [ScriptBlock], but I'd have to check.