1

Basically I was searching for solution to list all running processes which have open windows, and one solution was frequently mentioned (in PowerShell):

gps | where {$_.mainwindowtitle}

and I thought, this command listed firstly all running processes and filtered based on criterium mainwindowtitle == True?

However, there is no such a column called mainwindowtitle in the output of either 'gps (get-process)' or 'tasklist' (at least what as output was printed in the terminal) and is it invisible or is the way i understood the code wrong?

Any advice or suggestion will be appreciated.

mklement0
  • 382,024
  • 64
  • 607
  • 775
citron
  • 85
  • 8

1 Answers1

1

The code works as expected, and - thanks to the separation between data and its display representation in PowerShell's object-based pipeline - can easily be adapted to show what you want:

  • The System.Diagnostics.Process objects returned by Get-Process (whose built-in alias is gps) have a .MainWindowTitle property that Where-Object (whose built-in aliases are where and ?) filters by.

  • However, the .MainWindowTitle property values are simply not displayed by default, because the formatting definitions for the output type do not define a display column for it (horizontal space in tables is limited, so only the most important properties are shown.

    • You can select your own display columns by passing the names of the properties of interest to Format-Table (whose built-in alias is ft):
# Find all processes that have a main-window title and 
# show their process ID, name, and main-window title in a table.
Get-Process | 
  Where-Object MainWindowTitle | 
  Format-Table -Property Id, Name, MainWindowTitle

The most concise equivalent of the above, using aliases (recommended for interactive use only):

gps | ? MainWindowTitle | ft Id, Name, MainWindowTitle

Note:

  • Simplified syntax is used in the Where-Object call.

    • That is, MainWindowTitle is equivalent to passing script block { $_.MainWindowTitle }

    • Even though the .MainWindowTitle property contains strings, they are implicitly evaluated as Booleans ($true or $false) by Where-Object, simply based on whether they are empty ($false) or not ($true).
      That is, { $_.MainWindowTitle } is effectively the same as the more verbose { $_.MainWindowTitle -ne '' }
      For a summary of PowerShell's implicit to-Boolean coercion logic, see the bottom section of this answer.

  • It is important to note that Format-* cmdlets should only ever be used for display formatting, and never to supply output for subsequent programmatic processing.

    • If you want to select a subset of properties as data, for later programmatic processing, use Select-Object (whose built-in alias is select) instead.

    • See this answer for more information.

mklement0
  • 382,024
  • 64
  • 607
  • 775