Я ищу способ найти процессы, у которых не запущен родительский процесс (осиротевшие процессы). Я пытаюсь сделать это с помощью 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 {$_}