Powershell: get output from Receive-Job

Justin Holbrook picture Justin Holbrook · Aug 15, 2012 · Viewed 68.8k times · Source

I have a collection of jobs that are running. When they complete I use receive-job and it writes the output to the screen. I'd like to take that output and log it to a file. I don't want to tee the output produced while the jobs are running because with multiple jobs running at once the logging would be interspersed. Get-Job | Receive-Job prints the output in a nice organized manner.

I have tried all of the following and no output is written to the file or stored in a variable, it just goes to the screen:

#Wait for last job to complete
While (Get-Job -State "Running") {    
    Log "Running..." -v $info
    Start-Sleep 10        
}    
Log ("Jobs Completed. Output:") -v $info

# Getting the information back from the jobs
foreach($job in Get-Job){
    Receive-Job -Job $job | Out-File c:\Test.log -Append
    $output = Receive-Job -Job $job        
    Log ("OUTPUT: "+$output)
    Receive-Job -Job $job -OutVariable $foo
    Log ("FOO: "+$foo)
}

EDIT: I have removed the extra Receive-Job calls in the foreach to the following after seeing Keith's comment:

# Getting the information back from the jobs
foreach($job in Get-Job){
    Receive-Job -Job $job -OutVariable temp
    Write-Host ("Temp: "+$temp)
    $temp | Out-File -FilePath c:\Test.log -Append 
}

I also verified I'm not using Receive-Job anywhere else in the script. The write-host $temp and the out-file still produce no output though.

Answer

doer picture doer · Jan 28, 2015

If the job uses Write-Host to produce output, Receive-Job returns $null, but the results get written to the host. However, if the job uses Write-Output to produce output in lieu of Write-Host, Receive-Job returns a string array [string[]] of the job output.

To demonstrate, enter this innocuous code at the PowerShell prompt:

$job = Start-Job -ScriptBlock {
    [int] $counter = 0
    while ($counter -lt 10) {
        Write-Output "Counter = $counter."
        Start-Sleep -Seconds 5
        $counter++
    }
}

Wait about 20-30 seconds for the job to produce some output, then enter this code:

$result = Receive-Job -Job $job
$result.Count
$result
$result | Get-Member

The $result object contains the strings produced by the job.