I am looking for a way to find processes that do not have a parent process running (orphaned processes). Im attempting to do this using win32_process. I have the query that returns the attributes needed, its the comparison im struggling with:

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

I have tried compare-object -includeequal against the two arrays and get an overwhelming number of results- so much so i doubt truth of the operator given the arrays i'm feeding it. I think there is value added in the diff command, but am not familiar with the usage other than feeding it arrays as well. Does anyone have experience with the diff command and/or another solution?

The end goal is to compare or diff the two arrays from the above wmi call:

$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

And then return only the ones that do not appear in both (orphaned). Thanks in advance!

| improve this question | | | | |

Probably not very efficient, but it seems to work:

$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 {$_}
| improve this answer | | | | |

I know this is an oldie, but following solution performs quite well:

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
| improve this answer | | | | |
  • NOTE: you might want to use Get-CimInstance instead of Get-WmiObject – mwallner Oct 31 '19 at 9:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.