Find the owner of a process

Powershell MVP Jeffery Hicks recently mentioned how to get processes that belongs to users:

((Get-Process -IncludeUserName).where({$_.username -AND $_.username -notmatch "^NT"}))

The above one-liner requires both Powershell 4.0 and an elevated PS prompt otherwise you end-up with:


Get-Process : The ‘IncludeUsername’ parameter requires elevated user rights. Try running the command again in a session that has been opened with elevated user rights (that is, Run As Administrator).

To get the current user processes, another one-liner would look like:

ps -IncludeUserName|? UserName -m "$env:USERNAME"

Imagine you’re stuck on Powershell version 3.0 and that you want to get the current user processes.
You can do this with WMI (and mimic the Get-Process console view) like this:

$View = @(
 @{l='Handles';e={$_.HandleCount}},
 @{l='NPM(K)';e={ (Get-Process -Id $_.ProcessId).NonpagedSystemMemorySize/1KB -as [int]}},
 @{l='PM(K)';e={ $_.PrivatePageCount/1KB -as [int]}},
 @{l='WS(K)';e={ $_.WorkingSetSize/1KB -as [int]}},
 @{l='VM(M)';e={ $_.VirtualSize/1mB -as [int]}},
 @{l='CPU(s)';e={ (Get-Process -Id $_.ProcessId).CPU -as [int]}},
 @{l='Id';e={ $_.ProcessId}},
 'UserName'
 @{l='ProcessName';e={ $_.ProcessName}}
)
Get-WmiObject Win32_Process | % { $_ | 
    Add-Member -MemberType ScriptProperty -Name UserName -Value {
        '{0}\{1}' -f $this.GetOwner().Domain,$this.GetOwner().User
    } -Force -PassThru
} | ? UserName -match $env:USERNAME | ft $View -AutoSize

(Ok, I cheated for the NonpagedSystemMemorySize and the CPU load :-P)

…Or by extending Get-Process with WMI like this:

$PSView = @(
 'Handles',
 @{Label="NPM(K)";Expression={[int]($_.NPM/1024)}},
 @{Label="PM(K)";Expression={[int]($_.PM/1024)}},
 @{Label="WS(K)";Expression={[int]($_.WS/1024)}},
 @{Label="VM(M)";Expression={[int]($_.VM/1MB)}},
 @{Label="CPU(s)";Expression={if ($_.CPU -ne $()) { $_.CPU.ToString("N")}}}
 'Id', 'UserName','ProcessName'
 )
Get-Process | % { $_ | 
    Add-Member -MemberType ScriptProperty -Name UserName -Value {
        $o = (Get-WmiObject -Query "Select * FROM Win32_Process WHERE ProcessId = $($this.Id)").GetOwner()
        '{0}\{1}' -f $o.Domain,$o.User 
    } -Force -PassThru
} | ? UserName -match $env:USERNAME |
ft $PSView -AutoSize

I got the above PSView from the Example 5 of the Get-Process Cmdlet help

The interesting new thing in Powershell version 4.0 when you run the Get-Process cmdlet with the new IncludeUserName switch parameter is that you get back a System.Diagnostics.Process#IncludeUserName object and not a System.Diagnostics.Process

This new “child” object (I don’t know how to name it, I’m not a .Net developper) has its custom view defined in C:\Windows\system32\WindowsPowerShell\v1.0\DotNetTypes.format.ps1xml

It’s may also be very difficult to get this ProcessWithUserName view applied.

Here’s a code that works and has the ProcessWithUserName view applied despite that fact that I omitted the new IncludeUserName switch on purpose

(Get-Process | % { 
    $obj = New-Object -TypeName psobject -ArgumentList $_
    $obj | Add-Member -MemberType ScriptProperty -Name UserName -Value {
        $o = (Get-WmiObject -Query "Select * FROM Win32_Process WHERE ProcessId = $($this.Id)").GetOwner()
        '{0}\{1}' -f $o.Domain,$o.User 
    } -Force -PassThru
    $obj.PSObject.TypeNames.Insert(0,'System.Diagnostics.Process#IncludeUserName')
    $obj
})|  ? UserName -match $env:USERNAME

The parantheses (at the begining and the closing one before piping the whole expression to the where cmdlet) are strictly required, otherwise the process view of the System.Diagnostics applies.

Here’s what is allowed with views and of course, you cannot have an empty UserName column if you’ve omitted the new IncludeUserName switch on purpose

Get-Process | ft -View ProcessWithUserName

Advertisements

One thought on “Find the owner of a process

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s