2

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!

2 Answers 2

1

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
}
1
  • NOTE: you might want to use Get-CimInstance instead of Get-WmiObject
    – mwallner
    Commented Oct 31, 2019 at 9:40
0

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .