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