Matando o processo de violação de memória, mas mantendo o pai seguro em Powershell

1

Preciso de ajuda para matar o processo infantil, mas mantenha os pais seguros. Eu sou novo no script powershell [obviamente]. Aqui está exatamente o que eu preciso:

Eu tenho processos que estão usando mais de 500.000K de memória e quero colocá-los abaixo pelo script que será executado diariamente. Mas ao mesmo tempo eu quero evitar matar o processo pai, que também pode cair na categoria "acima de 500.000". Eu quero usá-lo para outra coisa, mas como um exemplo que eu estou mostrando árvore iexplore.exe.

Doisprocessosfilhosestãoviolandominhamemóriamax.Eusoucapazdemataraquelesporscript,maseuprecisocolocaraopçãodefalhaseguranoprocessopaicasotambémvaiacimadolimiteespecificadoequeeunãoseicomoabordar.

Issoéoqueeutenhoatéagora.Oprimeiropassoéobtertodososprocessosdeviolação:

Get-WmiObject-ComputerName$[listofservers]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]}

O próximo passo seria pará-los.

Eu ficaria grato por qualquer dica.

Jules

    
por jules d 12.12.2017 / 08:24

2 respostas

1

Usando o WMI, você pode obter o ParentProcessID do processo

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

Em uma nota secundária: embora seja improvável no caso do iexplore, é totalmente possível que um processo pai seja interrompido e o id seja reutilizado por outro processo.

    
por 12.12.2017 / 09:09
0

Esta é uma maneira de criar esse tipo de lista. Primeiro, armazene todos os PIDs para o nome do processo em questão em uma matriz. Em seguida, filtre a lista de processos para incluir apenas aqueles em que o PID principal também está nessa matriz. Isso funciona porque o pai dos filhos iexplore será outro iexplore que está na matriz PID, e o pai do PRIMEIRO proce iexplore provavelmente era o Explorer, cujo PID não está nessa matriz.

$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

Observe que você não pode fazer isso com um único pipeline que começa com Get-WmiObject -ComputerName $[list of servers] . Isso cria uma coleção única de processos em vários dispositivos. Não há relacionamento de processo pai entre processos em diferentes dispositivos. Você precisará aninhar a enumeração do processo dentro de um loop que é executado em cada servidor.

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() }
}
    
por 13.12.2017 / 21:33