32

On a database, I can get a list of all the currently running processes, and the sql command that kicked them off.

I'd like to do a similar thing on a windows box.

I can get the list of processes, but not the command line that kicked them off.

My question is: Given a PID on Windows - how do I find the command line instruction that executed it?

Assumptions:

  • Windows 7 and equivalent servers
Hawkeye
  • 2,669
  • 9
  • 30
  • 34

4 Answers4

44

Powershell and WMI.

Get-WmiObject Win32_Process | Select ProcessId,CommandLine

Or

Get-WmiObject -Query "SELECT CommandLine FROM Win32_Process WHERE ProcessID = 3352"

Note that you have to have permissions to access this information about a process. So you might have to run the command as admin if the process you want to know about is running in a privileged context.

Ryan Ries
  • 55,011
  • 9
  • 138
  • 197
  • I find it truncates the path - is there a way around that? – Hawkeye Jun 03 '15 at 23:37
  • 1
    @Hawkeye Try adding `| FL` to the end of the command. That expands all of the command line for me. Might also want to play with `| Select -ExpandProperty CommandLine` – Ryan Ries Jun 03 '15 at 23:56
  • Interestingly, you cannot get this information from the native Get-Process cmdlet. – Davidw Jun 04 '15 at 01:02
  • 3
    Get-process uses the system.diagnostics.process class which doesn't have that property. The help for get-process also has an example of using wmi to get the process object – Jim B Jun 04 '15 at 02:26
  • 2
    It's worth noting that there's [no officially supported](http://blogs.msdn.com/b/oldnewthing/archive/2009/02/23/9440784.aspx) way of getting the command line of another process. While [there are ways](http://blogs.msdn.com/b/oldnewthing/archive/2009/11/25/9928372.aspx) to get a string that *could* be the command line, it's not guaranteed by the operating system and the result could be "chicken chicken chicken" for all you know. – Nick Jun 05 '15 at 22:31
  • @RyanRies `| Format-Table -AutoSize` is much better if you want multiple attributes. – jpmc26 May 10 '17 at 16:49
  • @Nick Think you're spot on, but I'm seeing **blanks** much more than chickens. ;) – jpmc26 May 10 '17 at 16:51
  • @Nick: Good point, but perhaps a better way of framing it is to say that the unsupported ways _typically_ work and only fail if the target process _has gone out of its way_ to modify / erase the command-line string (an intentional act of obfuscation). – mklement Dec 18 '18 at 17:26
22

You can use the WMI subsystem, using WMIC.EXE to get to this information. Assuming a PID of 600:

wmic.exe path Win32_Process where handle='600' get name, commandline  /format:list

You can also search for name, or other characteristic of the process. Use this command to list all attributes:

wmic.exe path Win32_Process get  /format:list
RobW
  • 2,766
  • 1
  • 17
  • 22
  • 1
    That's handy; you can shorten it a bit with the `process` alias instead of `path Win32_Process`; e.g., `wmic.exe process get` – mklement Dec 18 '18 at 23:01
16

The other answers are certainly good options that will serve you well in an automated system because of their command line nature (and I see from the tag that that's what you wanted). Of course, some folks might want to explore this kind of info with a GUI, so here's an alternative along those lines.

Process Explorer is a Sysinternals tool maintained by Microsoft. It can display the command line of the process in the process's properties dialog as well as the parent that launched it, though the name of that process may no longer be available. Here's the process properties dialog:

process properties dialog

If you want a more detailed audit trail of when a process was launched and under what conditions, you can turn to another Sysinternals tool called Process Monitor. Here you can filter for "Process started" events, learn about the environment the process was launched in, and see what other events were occurring around that time. It's quite a powerful program. Here's the event properties dialog:

event properties dialog

BE77Y
  • 2,577
  • 3
  • 17
  • 23
Corrodias
  • 261
  • 1
  • 3
  • 10
    Or just change the columns on Task Manager to show the PID and the "Command Line". And done. – Ismael Miguel Jun 04 '15 at 10:47
  • @IsmaelMiguel The Command Line column in Task Manager does truncate really long argument strings, don't know if Process Explorer does – JG in SD Jun 05 '15 at 20:41
  • @JGinSD I've never seen a truncated argument. – Ismael Miguel Jun 05 '15 at 20:45
  • 1
    @IsmaelMiguel Looks like the limit is around 200 characters for the Command Line column – JG in SD Jun 05 '15 at 21:04
  • @JGinSD You are correct. I used the following command to try it: `start cmd.exe /C pause "12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz12345467890abcdefghijklmnopqrstuvwxyz"` – Ismael Miguel Jun 05 '15 at 21:29
  • 1
    The actual limit in Task Manager is 259 chars. (verified on Windows 10). Task Manager has one advantage, however: it shows you command lines of other users' / elevated processes even when it itself runs without elevation (not as administrator). While Process Explorer and Process Monitor do not have the 259-character limit, as of v16.22 they can _hang_ with overly long command lines if the `Command Line` column has been added if you mouse over that column. – mklement Dec 18 '18 at 22:59
4

To complement Ryan Ries' helpful PowerShell answer with a shorter alternative via the -Filter parameter that also uses Get-CimInstance instead of the deprecated-since-v3 Get-WmiObject cmdlet.

# Target a process by its PID (process ID) and report its command line, 
# using the PowerShell session's own PID as an example ($PID).
(Get-CimInstance Win32_Process -Filter "ProcessId=$PID").CommandLine

# Alternatively, target process(es) by name (may return multiple processes), 
# using Notepad.exe as an example.
# Select-Object is used to report both the PID and the command line.
Get-CimInstance Win32_Process -Filter "Name='Notepad.exe'" |
  Select-Object ProcessId, CommandLine

The -Filter parameter essentially allows you to pass the WHERE clause of a WQL statement instead of passing a full query statement via -Query.

mklement
  • 514
  • 4
  • 11