Search code examples
c#powershellwindows-10.net-4.8

WMI query from Win32_Process succeeds by some criteria but fails by another


I use the following lines, in a console project, to query WMI for running processes:

var wmiQuery = $"select ProcessId from Win32_Process where {field} like '%{value}%'";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery);
ManagementObjectCollection foundProcesses = searcher.Get();

They work fine if I supply the field of 'CommandLine' or 'ExecutablePath' but return nothing if I supply 'Description' and the value of 'Host Process'. If I supply 'Console', 'ServiceHub', or any other description that I can see in Task Manager, then I get results back but wrong number of them:

In Task Manager, for 'Console', I can see 6x conhost.exe under my name and 1x more under NETWORK SERVICE, but I get only 2 foundProcesses. For 'Host Process' I always get exactly 0.

The literal values for the column filter are obtained by copying and pasting from the Task Manager's Property dialog, so no typing error is possible. This is also not an access issue because both under a regular user and Administrator the result is an empty collection. On the contrary, 'CommandLine' or 'ExecutablePath' every time return correct results respectively for processes that regular users or Administrators have access to, so the query can be assumed working, and the problem seems to be with the field Description. Do any changes have to be made to the code above, to allow it to work reliably with that field?

Tried to run the above query under regular user and Administrator.

Tried to validate c# in Powershell and got this:

PS C:\WINDOWS\system32> Get-WmiObject -Query "select ProcessId from Win32_Process where Description like '%Console%'"


__GENUS          : 2
__CLASS          : Win32_Process
__SUPERCLASS     :
__DYNASTY        :
__RELPATH        :
__PROPERTY_COUNT : 1
__DERIVATION     : {}
__SERVER         :
__NAMESPACE      :
__PATH           :
ProcessId        : 7132
PSComputerName   :

This seems like not even 2x but 1x result only instead of 6-7. Correct me if I am wrong.


Solution

  • As explained in comments, there is no correlation between the Description from your Task Manager and the .Description property of the Win32_Process Management Object, this is the reason why your WQL query fails.

    You can find the Process Description from Task Manager in the FileVersionInfo.FileDescription Property of a Process instance.

    An alternative you could use for your current implementation is first filter by a field that you know correlates with the information on Task Manager and then use .GetProcessById to filter by .MainModule.FileVersionInfo.FileDescription.

    You could also query all processes and then filter for the process having the target Description:

    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    Regex re = new("Console Window Host");
    Process[] processes =  Process.GetProcesses();
    IEnumerable<Process> filtered = processes
        .Where(e => re.IsMatch(e.MainModule.FileVersionInfo.FileDescription));