给定进程ID,在PowerShell中终止进程树

时间:2019-04-29 03:10:32

标签: powershell

可以说我从PowerShell运行几个过程:

$p1 = $(Start-Process -PassThru ./example.exe)
$p2 = $(Start-Process -PassThru ./example.exe)

example.exe将产生几个具有相同名称的子进程。

如何杀死 just $p1及其子进程,而不杀死$p2及其子进程?

仅运行Stop-Process $p1只会杀死父进程$p1,而其子进程仍在运行。

到目前为止,我看到的所有答案都涉及杀死具有特定名称的所有进程,但这在这里不起作用。

3 个答案:

答案 0 :(得分:0)

带有Start-Process

-Passthru返回一个System.Diagnostics.Process对象。该对象具有Id property,由Windows生成并且是唯一的。

Stop-Process具有multiple signatures,其中一个按ID查找流程,一个按名称查找流程,另一个按Process对象查找流程。

您正在使用-Passthru并将start-process的输出捕获到$p1中,因此您可以将该对象传递给Stop-Process。

Stop-Process $p1

答案 1 :(得分:0)

所以我找不到真正的好方法,所以我写了一个使用递归来遍历进程树的辅助函数:

function Kill-Tree {
    Param([int]$ppid)
    Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq $ppid } | ForEach-Object { Kill-Tree $_.ProcessId }
    Stop-Process -Id $ppid
}

要使用它,请将其放在PowerShell脚本中的某个位置,然后像这样调用它:

Kill-Tree <process_id>

答案 2 :(得分:0)

如果登陆此处的任何人都通过指定父进程的名称来寻找杀死进程树的脚本,则可以像这样使用@wheeler的Kill-Tree递归函数。

注意:默认情况下,我发现自己不得不不断杀死eclipse及其子java进程。因此,如果没有通过$ procName调用参数提供父进程名称,则“ eclipse”是此脚本杀死的进程树的默认名称,即 killProcTree.ps1

名为“ killProcTree.ps1”的Powershell脚本:

 
param(
    [string]$procName    = 'eclipse'
)

function Kill-Tree {
    Param([int]$ppid)
    echo "Kill-Tree: killing $ppid ..."
    Get-CimInstance Win32_Process | Where-Object { $_.ParentProcessId -eq $ppid } | ForEach-Object { Kill-Tree $_.ProcessId }
    Stop-Process -Id $ppid
}

[int]$mypid = 0
[string]$myProcessToKill = (Get-Process -Name $procName -ErrorAction 0)

if ($myProcessToKill -eq "") {
    echo "$procName is not running."
} else {
    $mypid = (Get-Process -Name $procName -ErrorAction 0).Id
    echo "The $procName PID is: $mypid"
    if ($mypid -gt 1) {
        echo "Killing $procName and its children..."
        Kill-Tree $mypid
    }
}
echo "Done!"