Get Process Location Path using PowerShell
Asked Answered
H

5

14

I am trying to get the location of currently running process on your computer using PowerShell.

Example

C:\Program Files (x86)\Mozilla Firefox
C:\Windows\sysWOW64\WindowsPowerShell\v1.0
C:\Program Files (x86)\Internet Explorer

When I run the command

$path = Get-Process | Select-Object Path
Split-Path $path

I get the following output, which I not what I want. Why does it add @{Path=?

@{Path=C:\Program Files (x86)\Mozilla Firefox
@{Path=C:\Windows\sysWOW64\WindowsPowerShell\v1.0
@{Path=C:\Program Files (x86)\Internet Explorer

When I run Split-Path as follows, it gives me the correct output C:\Windows\sysWOW64\WindowsPowerShell\v1.0.

$pshpath = "C:\Windows\sysWOW64\WindowsPowerShell\v1.0\powershell.exe"
Split-Path $pshpath
Heliotype answered 13/7, 2015 at 2:25 Comment(1)
If PID is needed too, use Get-Process -name java | % { $_.Path + " " + $_.Id}Mckeon
E
16
$path = Get-Process | Select-Object Path

returns an array of objects. Each object in the array will have the property 'Path' along with an optional value.

The 'path' parameter of split-path takes 'string' arguments so when you run Split-Path $path

i guess each object is being converted to type string so you get the hashtable format output.

split-path can accept path values from pipeline by property name so you can do:

 $path | Split-path

if you just want the path perhaps you could try:

Get-Process | Select-Object -ExpandProperty Path
Effective answered 13/7, 2015 at 3:6 Comment(1)
For me, this just shows weird paths that are just C... :|Isopleth
O
8

To get a list of all paths just use:

ps | % {$_.Path}

or full syntax:

Get-Process | ForEach-Object {$_.Path}

when using:

$path = Get-Process | Select-Object Path

lets look at what $path is:

$path | Get-Member

and you get:

   TypeName: Selected.System.Diagnostics.Process

Name        MemberType   Definition
----        ----------   ----------
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()
GetType     Method       type GetType()
ToString    Method       string ToString()
Path        NoteProperty System.String Path=C:\windows\system32\atieclxx.exe

so Path is not a String but a NoteProperty, I guess that's why you can't use Split-Path directly.

Objurgate answered 13/7, 2015 at 3:14 Comment(1)
For those using the first syntax, it can even be cut down to ps | % Path as the pipeline variable and braces aren't required here.Nusku
P
4

Another way of getting the path is by doing something like this:

(Get-Process -Name firefox).path

But, since one process can appear multiple times (I'm looking at you, chrome.exe), you'd get the same path repeated as many times as the process appears in the process list. IMO, a better way of getting the path is by process id (1234 as an example):

(Get-Process -Id 1234).path

Or, if you're not sure what your process' id is, you could loop through all the running processes, and then check each of them individually, piping the results to a file, for later analysis. For example:

$processList = Get-Process #let's get all the processes at once
$newline = "`r`n"
$tabChar = "`t"
$separator = "--------"
$file = "C:\Users\Admin\Desktop\proc-loc.txt" # where do we want to pipe out the output

Write-Output "Processes $newLine $separator" > $file # out with the previous contents of the file, let's start anew 

# let's loop through the list, and pick out the stuff we need
foreach($item in $processList) {
    $itemObject =  $item | Select-Object

    $itemName = $itemObject.Name
    $itemId = $itemObject.Id
    $itemPath = (Get-Process -Id $itemId).path

    Write-Output "$itemId $tabChar $itemName $tabChar $itemPath"  >> $file
}

If you're interested in getting the running services as well, you could expand on the previous bit, with this:

$serviceList = Get-WmiObject win32_service | Where {$_.state -eq "Running"}
Write-Output "$newline $newline Services $newline $separator" >> $file

foreach($item in $serviceList) {
    $itemName = $item.Name
    $itemId = $item.ProcessId
    $itemPath = $item.PathName

    Write-Output "$itemId $tabChar $itemName $tabChar $itemPath" >> $file
}

One thing to note, though - this won't give you a path for each and every process currently running on your system. For example, SgrmBroker, smss, System and some instances of svchost won't have a path attached to them in your output file.

Pendley answered 7/4, 2022 at 21:19 Comment(0)
P
1

Just remove that split-path command and give a object parameter as stated below.

$path = Get-Process | Select-Object Path
$path.path

And output would be as stated below.

C:\Program Files (x86)\Citrix\ICA Client\SelfServicePlugin\SelfServicePlugin.exe
C:\WINDOWS\system32\SettingSyncHost.exe
C:\Windows\SystemApps\ShellExperienceHost_cw5n1h2txyewy\ShellExperienceHost.exe
C:\WINDOWS\system32\sihost.exe
C:\WINDOWS\system32\svchost.exe
C:\WINDOWS\system32\svchost.exe
C:\WINDOWS\system32\svchost.exe
Penetralia answered 9/9, 2022 at 15:54 Comment(0)
B
0

For me none of the other solutions were working in situations where the process was launched as a service or via local system (empty path).

This was the most stable solution for me at the end:

$result = @{} # used to remove duplicates
foreach($process in get-process) {
    try {
        $file = $process.MainModule.FileName
        $path = [System.IO.Path]::GetDirectoryName($file)
        $result[$file] = [PsCustomObject]@{
            file = $file
            PID  = $process.Id
            path = $path 
        }
    } catch {}
}
$result.values | sort file | ft -AutoSize
Blent answered 6/5 at 9:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.