How to get Command Line info for a process in PowerShell or C#

118,637

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.

Share:
118,637
victorwoo
Author by

victorwoo

Updated on March 22, 2021

Comments

  • victorwoo
    victorwoo about 3 years

    e.g: if I run notepad.exe c:\autoexec.bat,

    How can I get c:\autoexec.bat in Get-Process notepad in PowerShell?

    Or how can I get c:\autoexec.bat in Process.GetProcessesByName("notepad"); in C#?

  • CJBS
    CJBS about 10 years
    There 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
    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
    Shannon almost 10 years
    The 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
    mbrownnyc almost 9 years
    Just 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
    Ansgar Wiechers almost 9 years
    @mbrownnyc Using -Filter does the filtering on the remote host if your run Get-WmiObject against remote computers (using the -ComputerName parameter), reducing the amount of data that is transferred over the network (thus improving performance). Using Where-Object filters locally, after all WMI data was fetched from the remote host(s). It doesn't make a difference when running Get-WmiObject locally, though, like in this case. Also note that the syntax where property <op> value only works in PowerShell v3 or newer. Prior to that you must use where { $_.property <op> value }.
  • mbrownnyc
    mbrownnyc almost 9 years
    @AnsgarWiechers thanks for that point! Very important with get-wmiobject indeed!
  • Kay Zed
    Kay Zed about 7 years
    To avoid long line truncation you can also use | fl or | ft -auto (from here)
  • ahwm
    ahwm almost 7 years
    This 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 200 w3wp.exe processes)
  • Sajuuk
    Sajuuk over 5 years
    how to I cast the type of "Selected.System.Management.ManagementObject" to int32, provided I selected processid rather than commandline?
  • Ansgar Wiechers
    Ansgar Wiechers over 5 years
    @Sajuuk That has nothing to do with this question or answer. Please ask a new question.
  • Ross Presser
    Ross Presser over 4 years
    Note that with Get-CimInstance Win32_Process, the name includes the .exe extension. That's different from Get-Process.
  • minus one
    minus one over 3 years
    Appreciated 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.