如何在PowerShell中获取部分进程的CommandLine信息
解决部分进程无法通过Get-CimInstance获取CommandLine的问题
问题说明
你用这条PowerShell命令通过PID获取进程命令行:
Get-CimInstance -ClassName Win32_Process -Filter "ProcessId = '11132'" | Select Name,ProcessId,CommandLine
但部分进程(比如PID 4208、3944)的CommandLine信息无法返回,以下是可行的解决思路:
解决方法
- 提升权限运行PowerShell:很多系统进程、高权限进程的命令行信息需要管理员权限才能读取。右键PowerShell选「以管理员身份运行」,再执行命令,多数情况下能拿到原本读不到的信息。
- 调用Win32_Process的GetCommandLine方法:直接调用进程的原生方法有时能绕过权限限制,示例代码:
$targetPid = 4208 $process = Get-Process -Id $targetPid $cmdLineResult = (Get-CimInstance Win32_Process -Filter "ProcessId = $targetPid").GetCommandLine() [PSCustomObject]@{ Name = $process.Name ProcessId = $targetPid CommandLine = if ($cmdLineResult.ReturnValue -eq 0) { $cmdLineResult.CommandLine } else { "无法获取(权限不足或进程限制)" } } - 区分受保护进程:Windows的部分核心受保护进程(比如Lsass.exe、部分系统服务),哪怕是管理员权限也读不到CommandLine,这是系统安全机制的限制,没法绕过。这类进程的命令行信息本身就不对外暴露。
- 调用原生API NtQueryInformationProcess(进阶):如果上面的方法都不行,可以尝试调用Windows底层API来获取,需要嵌入C#代码到PowerShell中,示例:
注:这个方法同样需要管理员权限,对受保护进程依然无效。Add-Type @" using System; using System.Diagnostics; using System.Runtime.InteropServices; public class ProcessCmdLine { [DllImport("ntdll.dll")] private static extern int NtQueryInformationProcess(IntPtr hProcess, int infoClass, IntPtr buffer, int bufferSize, out int returnSize); private const int ProcessCommandLineInfo = 0x10; public static string Get(int pid) { using (var process = Process.GetProcessById(pid)) { IntPtr buffer = Marshal.AllocHGlobal(1024); int returnSize; int status = NtQueryInformationProcess(process.Handle, ProcessCommandLineInfo, buffer, 1024, out returnSize); if (status != 0) { Marshal.FreeHGlobal(buffer); return null; } string cmdLine = Marshal.PtrToStringUni((IntPtr)((long)buffer + IntPtr.Size)); Marshal.FreeHGlobal(buffer); return cmdLine; } } } "@ # 使用示例 $pid = 4208 [PSCustomObject]@{ Name = (Get-Process -Id $pid).Name ProcessId = $pid CommandLine = [ProcessCmdLine]::Get($pid) ?? "无法获取" }
内容的提问来源于stack exchange,提问作者Mona Coder
相关产品推荐
相关产品推荐

