1

Мне нужна помощь в уничтожении дочерних процессов, но я должен держать родителей в безопасности. Я новичок в скриптах PowerShell [очевидно]. Вот именно то, что мне нужно:

У меня есть процессы, которые используют более 500 000 КБ памяти, и я хочу записать их с помощью сценария, который будет выполняться ежедневно. Но в то же время я хочу избежать убийства родительского процесса, который также может попасть в категорию "выше 500 000". Я хочу использовать его для чего-то другого, но в качестве примера я показываю дерево iexplore.exe. Iexplore

Два из дочерних процессов нарушают мою память макс. Я могу убить их с помощью скрипта, но мне нужно установить опцию отказоустойчивости на тот случай, если родительский процесс также превысит указанный лимит, и я не знаю, как к нему подойти.

Это то, что я до сих пор. Первый шаг - получить все процессы нарушения:

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]}

Следующим шагом будет остановить их.

Буду благодарен за любые подсказки.

Жюль

2 ответа2

1

Используя WMI, вы можете получить ParentProcessID процесса

gwmi -Class win32_process -Filter 'name like "%iexplore%"' | 
    select Name, ProcessID, ParentProcessID

На заметку: хотя это маловероятно в случае iexplore, родительский процесс может полностью остановиться, а идентификатор может быть использован другим процессом.

0

Это один из способов создания такого списка. Во-первых, сохраните все PID для рассматриваемого имени процесса в массиве. Затем отфильтруйте список процессов, чтобы включить только те, в которых PID PID также находится в этом массиве. Это работает, потому что родительский объект дочерних элементов iexplore будет другим iexplore, который находится в массиве PID, а родительским процессом FIRST 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() }
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .