powershellprocesskillspawnresource-cleanup

kill child processes when parent ends


My goal is to kill (or somehow gracefully shutdown) child processes that were started by powershell script, so that nothing will keep running after the parent process dies (either normally by hitting end of script or via crash or ctrl+c or any other way).

I've tried several approaches but none worked as expected:

# only one line was active at time, all other were commented
start-job -scriptblock { & 'notepad.exe' }    # notepad.exe started, script continues to end, notepad.exe keep running
start-job -scriptblock { 'notepad.exe' }      # notepad.exe not started, script continues to end
notepad.exe                                   # notepad.exe started, script continues to end, notepad.exe keep running
& notepad.exe                                 # notepad.exe started, script continues to end, notepad.exe keep running
start-Process -passthru -FilePath notepad.exe # notepad.exe started, script continues to end, notepad.exe keep running

# give script some time before ending
Write-Host "Begin of sleep section"
Start-Sleep -Seconds 5
Write-Host "End of sleep section"

Solution

  • You can to this kind of thing with a finally clause. A finally clause gets executed after a try block, even if the execution of the try block threw an exception or if the execution was aborted by the user.

    So one way to approach your problem would be the following:

    1. keep track of the process ids of the child processes, your script is spawning and

    2. kill these processes in the finally clause.

        try
        {
           $process = Start-Process 'notepad.exe' -PassThru 
    
           # give script some time before ending
            Write-Host "Begin of sleep section"
            Start-Sleep -Seconds 5
            Write-Host "End of sleep section"
    
        }
        finally
        {
            # Kill the process if it still exists after the script ends.
            # This throws an exception, if process ended before the script.
            Stop-Process -Id $process.Id
        }