1

I am trying to run the following Powershell command via CMD:

powershell -command "Get-WmiObject Win32_Process | Where-Object {$_.CommandLine -like \"*C:\Windows\Test*\" } | Select-Object ProcessName, CommandLine"

The command above runs fine directly on Powershell, but only causes problems when I try to run it on CMD. In my testing, I discovered that the * symbol fails to process correctly, I tried to put a backslash before the symbol for testing and that has not done the trick. Is there a way to get this to work with the * symbol in CMD?

Edit: This command is used to view processes that contain a command-line of C:\Windows\Test

Help
  • 161
  • 1
  • 2
  • 14

2 Answers2

3

Simpler still, no need for PowerShell:

wmic process where "commandline like '%c:\\windows\\test%'" get name, commandline

And just for completeness, to remain properly on topic, using PowerShell from cmd.exe, I'd do it more like this:

powershell -noprofile "get-ciminstance -query \"select * from win32_process where commandline like '%c:\\windows\\test%'\" | select-object -property processname, commandline"
Compo
  • 36,585
  • 5
  • 27
  • 39
2

Compo's helpful wmic solution is both simpler and more efficient than a call to the Windows PowerShell CLI (powershell.exe), but it's worth noting that:

  • The wmic.exe CLI is deprecated, as evidenced by WMIC is deprecated. printing in red when you invoke its command-line help (wmic /?) as of Windows 10 20H2; curiously, however, the docs do not mention deprecation. That said, wmic.exe probably won't go away.

  • Undoubtedly, however, from inside PowerShell the CIM cmdlets (e.g., Get-CimInstance) are preferable,[1] not least because they return rich objects rather than mere text.


As for what you tried:

  • Your command does work from cmd.exe (and, conversely, does not from PowerShell, because inside PowerShell you need `" or "" - not \" - to embed " characters in a "..." string)

  • The only problem is that powershell.exe process executing the Get-WmiObject call is invariably included in the search results, because it itself contains the search term.

Therefore, the only tweak needed is to exclude the powershell.exe process itself from the results, using the automatic $PID variable, which reflects the session's own process ID:

  • Note: For the reasons discussed above, I'm using Get-CimInstance instead of Get-WmiObject. Note the addition of the Where-Object ProcessId -ne $PID pipeline segment.
powershell -c "Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like \"*C:\Windows\Test*\" } | Where-Object ProcessId -ne $PID | Select-Object ProcessName, CommandLine"

A slightly more efficient alternative is to filter at the WMI source, using Get-CimInstance's -Filter parameter, which accepts (part of) a WQL query (note the use of % as the wildcard character, and the need to double literal \ instances; as a side effect, the Where-Object ProcessId -ne $PID filter is no longer needed):

powershell -c "Get-CimInstance Win32_Process -Filter 'CommandLine like \"%C:\\Windows\\Test%\"' | Select-Object ProcessName, CommandLine"

[1] The CIM cmdlets (e.g., Get-CimInstance) superseded the WMI cmdlets (e.g., Get-WmiObject) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell (Core) (v6+), where all future effort will go, doesn't even have them anymore. Note that WMI still _underlies the CIM cmdlets, however. For more information, see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775