multithreadingpowershell

What output exactly is captured by -Streaminghost in Start-ThreadJob?


When running code as a ThreadJob in PowerShell 7.2.11 (also applies to 7.2.13), I've noticed that not all output is affected by the -Streaminghost argument.

Start-ThreadJob {
  Write-Host 'Hello'
} -Streaminghost $Host

will output Hello,

but using Write-Output in the thread will not show the output until I do a Get-Job | Receive-Job...

Start-ThreadJob {
  Write-Output 'Hello'
} -Streaminghost $Host
Start-ThreadJob {
  'Hello'
} -Streaminghost $Host

What gives?


Solution

  • Santiago Squarzon has provided the crucial pointers:


    If you truly want to surface all output streams from the thread job instantly, asynchronously, you can use the following technique, which uses redirection *>&1, which merges all outputs streams into the success output stream, and pipes the result to Out-Host for direct-to-host output:

    $job = Start-ThreadJob {
      & {
        Write-Host 'Hello host'
        Write-Output 'Hello success'
        Write-Error 'Hello error'
      } *>&1 | Out-Host
    } -StreamingHost $Host
    

    Note: The above also outputs a (non-terminating) error in addition to host (Write-Host) and success output (Write-Output) to demonstrate that all output surfaces instantly, asynchronously.


    [1] The following commands illustrate this difference: Write-Information info 6>&1 prints info, because info was still emitted and therefore redirected to the success output stream - even though the command by itself, without the redirection, is silent. By contrast, Write-Verbose verbose 4>&1 outputs nothing, because Write-Verbose, in the absence of requesting verbose output (e.g., with -Verbose), emits nothing