Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)    { 
    Try{
    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)    { 
    Try{ 
    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.

like image 595
Tehc Avatar asked Aug 12 '16 07:08

Tehc


2 Answers

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

Output:

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
}
like image 81
Martin Brandl Avatar answered Sep 19 '22 15:09

Martin Brandl


Multiple possible ways here:

$Var = Start-Job { & K:\sample\kdp.cmd }

an then check

$Var.State

Or give the job a name

Start-Job { & K:\sample\kdp.cmd } -Name MyJob

and then check

Get-Job MyJob
like image 44
whatever Avatar answered Sep 20 '22 15:09

whatever