Назад | Перейти на главную страницу

Powershell находит потерянные процессы

Я ищу способ найти процессы, у которых не запущен родительский процесс (осиротевшие процессы). Я пытаюсь сделать это с помощью win32_process. У меня есть запрос, который возвращает необходимые атрибуты, это сравнение, с которым я борюсь:

gwmi win32_process -ComputerName $hostname | select ProcessID,ParentProcessID,@{l="Username";e={$_.getowner().user}} | where{$_.Username -like $username}

Я пробовал compare-object -includeequal с двумя массивами и получил огромное количество результатов - настолько, что я сомневаюсь в истинности оператора, учитывая массивы, которые я его кормлю. Я думаю, что в команде diff есть добавленная стоимость, но я не знаком с ее использованием, кроме подачи ей массивов. Есть ли у кого-нибудь опыт работы с командой diff и / или другим решением?

Конечная цель - сравнить или различить два массива из приведенного выше вызова wmi:

$proc_all = gwmi win32_process -ComputerName $hostname | select ProcessID,ParentProcessID,@{l="Username";e={$_.getowner().user}} | where{$_.Username -like $username}
$sub_procs = $proc_all.Processid #ARRAY1
$par_proces = $proc_all.ParentProcessId #ARRAY2

А затем верните только те, которые не появляются в обоих (осиротевшие). Заранее спасибо!

Я знаю, что это старый, но следующее решение работает довольно хорошо:

function Get-OrphanedProcesses {
  $procsWithParent = Get-WmiObject -ClassName "win32_process" | Select-Object ProcessId,ParentProcessId
  $orphaned = $procsWithParent | Where-Object -Property ParentProcessId -NotIn $procsWithParent.ProcessId

  Get-Process | Where-Object -Property Id -In $orphaned.ProcessId
}

Наверное, не очень эффективно, но вроде работает:

$all_Processes = gwmi win32_process -ComputerName . | select ProcessID,ParentProcessID,Description,@{l="Username";e={$_.getowner().user}} | where{$_.Username -like $env:username}
$all_processIDs = $all_Processes.Processid #ARRAY1
$parent_processIDs = $all_Processes.ParentProcessId #ARRAY2

# create a new Array for parents that are gone
$gone = New-Object System.Collections.ArrayList

# loop through all processes
$parent_processIDs | Sort-Object -Unique | ForEach-Object {
# find the ones where the current parent ID is not running
    if ($all_processIDs -notcontains $_)
    {
        $gone.Add($_) | Out-Null
    }
}
# now we have all parentIDs no longer running

# loop through all processes and find those in that list
$all_Processes | Where-Object {$gone -contains $_.ParentProcessId} | ForEach-Object {$_}