Sorry if I'm being a dumb powershell noob, but what's wrong with jobs apparently being unable to write to the terminal? And how can I fix that?
# test.ps1
function myjob {
Write-Host "Hello, World!" # doesn't show
}
Start-Job -Name MyJob -ScriptBlock ${function:myjob}
Wait-Job MyJob
Remove-Job MyJob
It sounds like you're trying to use
Write-Hostto directly, synchronously write to the console (terminal) from a background job.However, PowerShell jobs do not allow direct access to the caller's console. Any output - even to the PowerShell host (which in foreground use is the console, if run in one) is routed through PowerShell's system of output streams (see the conceptual about_Redirection help topic).
Therefore, you always need the
Receive-Jobcmdlet in order to receive output from a PowerShell job.The following example receives the job output synchronously, i.e. it blocks execution until the job finishes (
-Wait) and then removes it (-AutoRemoveJob); see the bottom section for an asynchronous (polling, non-blocking) approach.Caveat re use of
Write-Hostin jobs:In foreground use,
Write-Hostoutput - even though primarily designed to go to the host (console) - can be redirected or captured via the information stream (whose number is6, available in PSv5+); e.g.:Write-Hostoutput received via a (child-process-based) background job, however, can not be redirected or captured, as of PowerShell 7.2.1:By contrast, it can be redirected/captured when using a (generally preferable) thread-based background job (as opposed to a child-process-based background job), via
Start-ThreadJob:Waiting for a job to complete in a non-blocking fashion, passing job output through as it becomes available:
Note: In this simple case, the expected termination states are
Completed(either no or only non-terminating errors occurred) orFailed(a script-terminating error was generated withthrow(and not caught inside the job)).[System.Management.Automation.JobState]enumeration for the complete list of possible states.The job object returned by
Start-Job- rather than a self-chosen name via the-Nameparameter - is used to interact with the job. This eliminates the ambiguity of possibly multiple jobs being present with a given-Name, all of which would be targeted.