我正在尝试通过 CMD 运行以下 Powershell 命令:
powershell -command "Get-WmiObject Win32_Process | Where-Object {$_.CommandLine -like \"*C:\Windows\Test*\" } | Select-Object ProcessName, CommandLine"
上面的命令直接在 Powershell 上运行良好,但只有当我尝试在 CMD 上运行它时才会出现问题。在我的测试中,我发现 * 符号无法正确处理,我尝试在该符号前加一个反斜杠进行测试,但没有成功。有没有办法让它与 CMD 中的 * 符号一起使用?
编辑: 该命令用于查看包含 C:\Windows\Test
命令行的进程更简单,无需 PowerShell:
wmic process where "commandline like '%c:\\windows\\test%'" get name, commandline
为了完整起见,为了正确地讨论主题,使用 cmd.exe 中的 PowerShell,我会这样做:
powershell -noprofile "get-ciminstance -query \"select * from win32_process where commandline like '%c:\\windows\\test%'\" | select-object -property processname, commandline"
wmic
解决方案 比调用 Windows PowerShell CLI (powershell.exe
) 更简单、更高效,但值得注意的是:
wmic.exe
CLI 已弃用,从 Windows 10 20H2 开始调用其命令行帮助 (WMIC is deprecated.
) 时以红色打印 wmic /?
也证明了这一点。也就是说,wmic.exe
可能不会消失。
然而,毫无疑问,来自内部PowerShell的CIM cmdlet(例如,
Get-CimInstance
)更可取,[1]尤其是因为它们返回丰富的对象而不是仅仅文本。
至于你尝试过的:
您的命令在 cmd.exe
`"
或 ""
- 而不是 \"
- 来嵌入 "
"..."
字符串中的字符)
唯一的问题是执行
powershell.exe
调用的 Get-WmiObject
进程总是包含在搜索结果中,因为它本身包含搜索词。
因此,唯一需要的调整是从结果中
powershell.exe
进程本身,使用自动$PID
变量,它反映了会话自己的进程ID:
Get-CimInstance
而不是 Get-WmiObject
。请注意添加了 Where-Object ProcessId -ne $PID
管道段。powershell -c "Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like \"*C:\Windows\Test*\" } | Where-Object ProcessId -ne $PID | Select-Object ProcessName, CommandLine"
稍微更有效的替代方法是 在 WMI 源进行过滤,使用
Get-CimInstance
的 -Filter
参数,该参数接受(部分)WQL 查询(请注意使用 %
作为通配符,并且需要 double 文字 \
实例;作为副作用,不再需要 Where-Object ProcessId -ne $PID
过滤器):
powershell -c "Get-CimInstance Win32_Process -Filter 'CommandLine like \"%C:\\Windows\\Test%\"' | Select-Object ProcessName, CommandLine"
[1] CIM cmdlet(例如,
Get-CimInstance
)取代了 PowerShell v3(2012 年 9 月发布)中的 WMI cmdlet(例如,Get-WmiObject
)。因此,应该避免使用 WMI cmdlet,尤其是因为未来所有工作都将集中在的 PowerShell(核心)(v6+)甚至不再有它们了。但请注意,WMI 仍然是 CIM cmdlet 的基础。有关更多信息,请参阅此答案。