如何在 PowerShell 或 C# 中获取进程的命令行信息

Posted

技术标签:

【中文标题】如何在 PowerShell 或 C# 中获取进程的命令行信息【英文标题】:How to get Command Line info for a process in PowerShell or C# 【发布时间】:2013-07-07 22:56:44 【问题描述】:

例如:如果我运行notepad.exe c:\autoexec.bat

如何在 PowerShell 中获取 c:\autoexec.bat 中的 Get-Process notepad

或者我如何在 C# 中获得 c:\autoexec.bat 中的 Process.GetProcessesByName("notepad");

【问题讨论】:

也许这会对你有所帮助:How to get the command line parameters from a different process 不清楚。你能更清楚地说明你到底想做什么吗? @victorwoo 请退后一步,描述您要解决的实际问题,而不是您认为的解决方案。 如果我们已经启动了一个进程并传递了一些参数,那么如何通过C#或PowerShell获取正在运行的进程的命令行参数? 【参考方案1】:

在 PowerShell 中,您可以通过 WMI 获取进程的命令行:

$process = "notepad.exe"
Get-WmiObject Win32_Process -Filter "name = '$process'" | Select-Object CommandLine

请注意,您需要管理员权限才能访问有关在另一个用户的上下文中运行的进程的信息。作为普通用户,只有在您自己的上下文中运行的进程才能看到它。

【讨论】:

这也有权限方面的问题。 Powershell 进程需要拥有至少与目标进程相同的权限。因此,常规的 Powershell 会话将无法为运行提升的进程(例如以管理员身份)获取此类信息。在这种情况下,命令行(响应)将只是空白。 @CJBS 准确地说,您需要管理员权限才能访问有关在另一个用户的上下文中运行的进程的信息。作为普通用户,只有在您自己的上下文中运行的进程才能看到它。 该值仍被截断为一定长度的字符。您可以通过将结果传递给“out-string -Width 2000”或类似的东西来解决它。 @mbrownnyc 如果您对远程计算机运行Get-WmiObject(使用-ComputerName 参数),则使用-Filter 在远程主机上进行过滤(使用-ComputerName 参数),从而减少通过网络传输的数据量(从而提高性能)。在从远程主机获取所有 WMI 数据之后,在本地使用Where-Object 过滤器。但是,在本地运行 Get-WmiObject 并没有什么不同,就像在这种情况下一样。另请注意,语法 where property <op> value 仅适用于 PowerShell v3 或更新版本。在此之前,您必须使用where $_.property <op> value 这并没有花太多时间来弄清楚,但是为了节省一些击键,如果你已经有了进程 ID(比如查看 CPU 使用率等),你可以使用 "processid = 1234" -我用它来查看我们的服务器上哪个网站正在流氓(并且有 200 个w3wp.exe 进程)【参考方案2】:

这个答案非常好,但是对于未来的验证和对你的帮助,除非你使用的是相当旧的 powershell(在这种情况下我建议更新!) Get-WMIObject 已被 Get-CimInstance Hey Scripting Guy reference 取代

试试这个

$process = "notepad.exe"
Get-CimInstance Win32_Process -Filter "name = '$process'" | select CommandLine 

【讨论】:

请注意,对于 Get-CimInstance Win32_Processname 包含 .exe 扩展名。这与Get-Process 不同。【参考方案3】:

我正在使用 powershell 7.1,这似乎已作为脚本属性内置到进程对象中:

> (Get-Process notepad)[0].CommandLine
"C:\WINDOWS\system32\notepad.exe"

有趣的是,您可以查看它的实现并看到它部分使用了 PsychoData 的答案:

($process | Get-Member -Name CommandLine).Definition
System.Object CommandLine get=
                        if ($IsWindows) 
                            (Get-CimInstance Win32_Process -Filter "ProcessId = $($this.Id)").CommandLine
                         elseif ($IsLinux) 
                            Get-Content -LiteralPath "/proc/$($this.Id)/cmdline"
                        
                    ;

在进程上运行 Get-Member 表明它是 System.Diagnostics.Process 的一个实例,但它有几个脚本化的属性。

其他属性是 FileVersion、Path、Product 和 ProductVersion。

【讨论】:

赞赏使用 Get-Member 获取有关 pwsh 工作原理的更多详细信息的想法。出于类似的原因,我们也可以使用$process | Get-TypeData | ConvertTo-Json【参考方案4】:

如果您将以下代码放入您的 powershell $profile 文件中,您可以永久扩展“进程”对象类并使用“命令行”属性

示例:

get-process notepad.exe | select-object ProcessName, CommandLine

代码:

$TypeData = @
    TypeName = 'System.Diagnostics.Process'
    MemberType = 'ScriptProperty'
    MemberName = 'CommandLine'
    Value = (Get-CimInstance Win32_Process -Filter "ProcessId = $($this.Id)").CommandLine

Update-TypeData @TypeData

【讨论】:

以上是关于如何在 PowerShell 或 C# 中获取进程的命令行信息的主要内容,如果未能解决你的问题,请参考以下文章

c# - 如何在运行时从模块代码中获取 PowerShell 模块版本

Powershell:如何从 C# 代码中获取凭据?

如何使用 C# 按组策略检查 PowerShell 禁用

在 C# 中无法获取 PowerShell 命令的结果

如何使用 PowerShell 或 VBScript 获取正在运行的应用程序列表

如何在 C# 中获取打开端口的进程名称?