Michael M. Michael M. - 10 months ago 52
PowerShell Question

How to do something if a job has finished

I'm trying to implement a GUI to my PowerShell script to simplify a certain process for other users. I have following PowerShell script:

if ($checkBox1.Checked) {
Start-Job { & K:\sample\adp.cmd }
$listBox1.Items.Add("ADP-Job started...")
}catch [System.Exception]{
$listBox1.Items.Add("ADP --> .cmd File not found!")}

if ($checkBox2.Checked) {
Start-Job { & K:\sample\kdp.cmd }
$listBox1.Items.Add("KDP-Job started...")
}catch [System.Exception]{
$listBox1.Items.Add("KDP --> .cmd File not found!")}

Is there a way to continuously check all running Jobs and do something for each Job that has finished? For Example to print out something like this in my listbox:
ADP-Files have been uploaded

Since each Job takes around 5 minutes - 4 hours I thought of a while Loop that checks every 5 minutes if a Job is finished, but I can't figure out how to distinguish each Job to do something specific.


You can either specifiy a name for the job using the -Name parameter:

Start-Job { Write-Host "hello"} -Name "HelloWriter"

And receive the job status using the Get-Job cmdlet:

Get-Job -Name HelloWriter


Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
3      HelloWriter     BackgroundJob   Completed     True            localhost             Write-Host "hello"

Or you assign the Start-Job cmdlet to a variable and use it to retrieve the job:

$worldJob = Start-Job { Write-Host "world"}

So you can just write $woldJob and receive:

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
7      Job7            BackgroundJob   Completed     True            localhost             Write-Host "world" 

You also don't have to poll the Job state. Instead use the Register-ObjectEvent cmdlet to get notificated when the job has finished:

$job = Start-Job { Sleep 3; } -Name "HelloJob"

$jobEvent = Register-ObjectEvent $job StateChanged -Action {
    Write-Host ('Job #{0} ({1}) complete.' -f $sender.Id, $sender.Name)
    $jobEvent | Unregister-Event