This post is part of the Second Wednesday Demo Session, Click here for more info about additional demo posts.
In PowerShell V2 you can use background jobs to perform various tasks. You can start a new job by using the Start-Job CmdLet.
PS > Start-Job -Name MyJob -ScriptBlock { Get-Process powershell }
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
1 MyJob Running True localhost Get-Process powershell
We can use Get-Job to display the jobs that are available.
PS > Get-Job Id Name State HasMoreData Location Command -- ---- ----- ----------- -------- ------- 1 MyJob Completed True localhost Get-Process powershellNotice that the State chenges from Running to Complete after the job completes. To check the result of the Job we use the Receive-Job CmdLet.
PS > Receive-Job -Id 1
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
256 24 53372 60192 566 0,58 1304 powershell
466 25 61036 71124 570 1,37 5404 powershell
If we run Receive-Job again nothing is returned.
PS > Receive-Job -Id 1This is because the job results are deleted from the system after you receive them. You can use the Keep parameter to save the results so that you can receive them again. We can remove a job by using the Remove-Job CmdLet. Here’s a short example.
PS > Get-Job -Id 1 | Remove-Job PS > Get-JobIf we want to wait for a job to complete we use the Wait-Job CmdLet.
PS > Start-Job -Name MyJob -ScriptBlock { "Hello"; Start-Sleep -s 5 } | Wait-Job
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
1 MyJob Completed True localhost "Hello"; Start-Sleep ...
Once the job completes we can use Receive-Job to check the result.
PS > Receive-Job -Name MyJob HelloHere’s another example where we add Receive-Job to the pipeline.
PS > Start-Job -Name MyJob -ScriptBlock { "Hello"; Start-Sleep -s 5 } | Wait-Job | Receive-Job
Another cool thing with jobs is that they can be run on Remote Computers. In the Example below we use Invoke-Command and add the AsJob parameter to run the commands as background jobs. Here’s an example.
PS > Invoke-Command -ComputerName DC01,SP01 -ScriptBlock { Get-Process } -AsJob -Credential powershell\administrator
Id Name State HasMoreData Location Command
-- ---- ----- ----------- -------- -------
1 Job1 Running True dc01,sp01 Get-Process
When running jobs on multiple computers remote each job is stored as a childjob. If we check out the ChildJob parameter on our job we’ll see that there are currently 2 childjobs available, one for each remote computer.
PS > (Get-Job -Id 1).ChildJobs Id Name State HasMoreData Location Command -- ---- ----- ----------- -------- ------- 2 Job2 Completed True dc01 Get-Process 3 Job3 Completed True sp01 Get-ProcessIf we want to see the result from DC01 we use the Receive-Job CmdLet and point out the Id or Name of that job.
PS > Receive-Job -Name Job2
[?]