How to get Command Line info for a process in PowerShell or C#
Solution 1
In PowerShell you can get the command line of a process via WMI:
$process = "notepad.exe"
Get-WmiObject Win32_Process -Filter "name = '$process'" | Select-Object CommandLine
Note that you need admin privileges to be able to access that information about processes running in the context of another user. As a normal user it's only visible to you for processes running in your own context.
Solution 2
This answer is excellent, however for futureproofing and to do future you a favor, Unless you're using pretty old powershell (in which case I recommend an update!) Get-WMIObject has been superseded by Get-CimInstance Hey Scripting Guy reference
Try this
$process = "notepad.exe"
Get-CimInstance Win32_Process -Filter "name = '$process'" | select CommandLine
Solution 3
if you put the following code in your powershell $profile file you can permanently extend the "process" object class and use the "CommandLine" property
example:
get-process notepad.exe | select-object ProcessName, CommandLine
code:
$TypeData = @{
TypeName = 'System.Diagnostics.Process'
MemberType = 'ScriptProperty'
MemberName = 'CommandLine'
Value = {(Get-CimInstance Win32_Process -Filter "ProcessId = $($this.Id)").CommandLine}
}
Update-TypeData @TypeData
Solution 4
I'm using powershell 7.1 and this seems to be built in to the process object now as a scripted property:
> (Get-Process notepad)[0].CommandLine
"C:\WINDOWS\system32\notepad.exe"
Interestingly, you can view its implementation and see that it partially uses the answer from 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"
}
;}
Running Get-Member on a process shows that it is an instance of System.Diagnostics.Process, but that it has several properties that are scripted.
The other properties are FileVersion, Path, Product, and ProductVersion.
victorwoo
Updated on March 22, 2021Comments
-
victorwoo about 3 years
e.g: if I run
notepad.exe c:\autoexec.bat
,How can I get
c:\autoexec.bat
inGet-Process notepad
in PowerShell?Or how can I get
c:\autoexec.bat
inProcess.GetProcessesByName("notepad");
in C#? -
CJBS about 10 yearsThere is a permissions aspect to this too. The Powershell process needs to have permissions at least equivalent to the target process. So a regular Powershell session won't be able to get such information for a process running elevated (e.g. as Administrator). in this case, CommandLine (the response) will just be blank.
-
Ansgar Wiechers about 10 years@CJBS To be precise you need admin privileges to be able to access that information about processes running in the context of another user. As a normal user it's only visible to you for processes running in your own context.
-
Shannon almost 10 yearsThe value is still truncated to a certain length of characters. You can work around it by piping the result to "out-string -Width 2000" or something similar.
-
mbrownnyc almost 9 yearsJust a general syntax note, you can also use
| where name -eq $process
instead of-filter
and it compiles the same before execution. I prefer this way as it's more extensible. -
Ansgar Wiechers almost 9 years@mbrownnyc Using
-Filter
does the filtering on the remote host if your runGet-WmiObject
against remote computers (using the-ComputerName
parameter), reducing the amount of data that is transferred over the network (thus improving performance). UsingWhere-Object
filters locally, after all WMI data was fetched from the remote host(s). It doesn't make a difference when runningGet-WmiObject
locally, though, like in this case. Also note that the syntaxwhere property <op> value
only works in PowerShell v3 or newer. Prior to that you must usewhere { $_.property <op> value }
. -
mbrownnyc almost 9 years@AnsgarWiechers thanks for that point! Very important with get-wmiobject indeed!
-
Kay Zed about 7 years
-
ahwm almost 7 yearsThis didn't take much to figure out, but to save someone a few keystrokes, if you already have the process id (like from looking at CPU usage, etc) you can use
"processid = 1234"
- I use it for seeing which website is going rogue on our server (and there are 200w3wp.exe
processes) -
Sajuuk over 5 yearshow to I cast the type of "Selected.System.Management.ManagementObject" to int32, provided I selected processid rather than commandline?
-
Ansgar Wiechers over 5 years@Sajuuk That has nothing to do with this question or answer. Please ask a new question.
-
Ross Presser over 4 yearsNote that with
Get-CimInstance Win32_Process
, thename
includes the .exe extension. That's different fromGet-Process
. -
minus one over 3 yearsAppreciated the idea to use
Get-Member
to get more details on how pwsh works. We can also use$process | Get-TypeData | ConvertTo-Json
for similar reasons.