我需要帮助来终止子进程,但要保证父进程的安全。我对 powershell 脚本还不熟悉 [显然]。这正是我所需要的:
我有一些进程占用了超过 500 000K 的内存,我想通过每天运行的脚本来关闭它们。但同时我想避免终止父进程,因为父进程也可能属于“超过 500 000”类别。我想将它用于其他用途,但作为示例,我显示了 iexplore.exe 树。
两个子进程超出了我的内存上限。我可以通过脚本终止它们,但我需要设置故障安全选项,以防父进程也超出指定限制,而我不确定该如何处理。
这是我目前所掌握的。第一步是获取所有违规流程:
Get-WmiObject -ComputerName $[list of servers] Win32_Process -Filter "name = '[app name]'" | Select-Object __Server,Name,@{Name='WorkingSet';Expression={[math]::Round(($_.WS/1MB),2)}},@{Name='VirtualMemory';Expression={[math]::Round(($_.VM/1MB),2)}} | Where-Object {$_.WorkingSet -gt $[my threshold]}
下一步就是阻止他们。
如有任何提示我将不胜感激。
朱尔斯
答案1
使用 WMI,您可以获取进程的 ParentProcessID
gwmi -Class win32_process -Filter 'name like "%iexplore%"' |
select Name, ProcessID, ParentProcessID
附注:虽然在 iexplore 情况下不太可能发生,但父进程完全有可能停止并且 id 被另一个进程重用。
答案2
这是创建此类列表的一种方法。首先,将相关进程名称的所有 PID 存储在一个数组中。然后过滤进程列表以仅包含父 PID 也位于该数组中的进程。这样做之所以有效,是因为 iexplore 子进程的父进程将是 PID 数组中的另一个 iexplore,而第一个 iexplore 进程的父进程可能是 Explorer,其 PID 不在该数组中。
$pids = (gwmi -Class win32_process -Filter 'name like "%iexplore%"' | select processid).processid
"PIDs"
$pids
"All Children"
gwmi -Class win32_process -Filter 'name like "%iexplore%"' | where { $_.parentprocessid -in $pids } | select -prop commandline,processid
"Children > Size"
gwmi -Class win32_process -Filter 'name like "%iexplore%"' | where { $_.parentprocessid -in $pids -and $_.ws -gt 500MB } | select -prop commandline,processid
"Parent(s)"
gwmi -Class win32_process -Filter 'name like "%iexplore%"' | where { $_.parentprocessid -notin $pids } | select -prop commandline,processid
请注意,您无法使用以 开头的单个管道执行此操作Get-WmiObject -ComputerName $[list of servers]
。这会在多个设备上创建单个进程集合。不同设备上的进程之间没有父进程关系。您需要将进程枚举嵌套在针对每个服务器运行的循环内。
foreach ($server in $listOfServers) {
$pids = (gwmi -comp $server win32_process -Filter 'name like "%iexplore%"' | select processid).processid
# Report only, no kill
gwmi -comp $server win32_process -Filter 'name like "%iexplore%"' | where { $_.parentprocessid -in $pids -and $_.ws -gt 500MB } | select -prop commandline,processid
# Kill, uncomment to enable
# gwmi -comp $server win32_process -Filter 'name like "%iexplore%"' | where { $_.parentprocessid -in $pids -and $_.ws -gt 500MB } | foreach { $_.terminate() }
}