5

I have a powershell script that launches an exe process. I have a task scheduled to run this powershell script on computer idle, and I have it set to stop it when it's not idle.

The problem is task schedule doesn't kill the launched exe process, I'm assuming it's just trying to kill the powershell process.

I can't seem to find a way to make the launched exe as a subprocess of a powershell.exe when it's launched from task scheduler

I've tried launching the process with invoke-expression, start-proces, I've also tried to pipe to out-null, wait-process, etc.. nothing seems to work when ps1 is launched from task scheduler.

Is there a way to accomplish this?

Thanks

fenderog
  • 314
  • 1
  • 3
  • 9
  • `start-process` uses a Job object to be able to wait on an entire process tree, but it doesn't configure this Job as `JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`. So terminating PowerShell has no effect on processes in the Job. – Eryk Sun Dec 31 '17 at 04:24
  • This is not even an easy thing to do in C#: https://stackoverflow.com/questions/3342941/kill-child-process-when-parent-process-is-killed – Bacon Bits Dec 31 '17 at 05:59

1 Answers1

5

I don't think there is an easy solution for your problem since when a process is terminated it doesn't receive any notifications and you don't get the chance to do any cleanup.

But you can spawn another watchdog process that watches your first process and does the cleanup for you:

The launch script waits after it has nothing else to do:

#store pid of current PoSh
$pid | out-file -filepath C:\Users\you\Desktop\test\currentposh.txt
$child = Start-Process notepad -Passthru
#store handle to child process
$child | Export-Clixml -Path (Join-Path $ENV:temp 'processhandle.xml')

$break = 1
do
{
    Sleep 5 # run forever if not terminated
}
while ($break -eq 1)

The watchdog script kills the child if the launch script got terminated:

$break = 1
do
{
    $parentPid = Get-Content C:\Users\you\Desktop\test\currentposh.txt
    #get parent PoSh1
    $Running = Get-Process -id $parentPid -ErrorAction SilentlyContinue
    if($Running -ne $null) {
        $Running.waitforexit()
        #kill child process of parent posh on exit of PoSh1
        $child = Import-Clixml -Path (Join-Path $ENV:temp 'processhandle.xml')
        $child | Stop-Process
    }
    Sleep 5
}
while ($break -eq 1)

This is maybe a bit complicated and depending on your situation can be simplified. Anyways, I think you get the idea.

wp78de
  • 18,207
  • 7
  • 43
  • 71