PatricF
PatricF

Reputation: 419

List process for current user

As an administrator I can get a users processes by running this

Get-Process -IncludeUserName | Where UserName -match test

But as a non-administrator I can't use -IncludeUserName becuase "The 'IncludeUserName' parameter requires elevated user rights".

So if I'm logged on as the user test, how do I list only his processes and not everything that's running?

Upvotes: 20

Views: 41419

Answers (6)

js2010
js2010

Reputation: 27423

Here's a variation that always has a username property in the get-process output, but running getowner() really slows it down. You can add commandline in a similar way, but it's faster because it's only a property.

# add username property to get-process
$updateTypeData = @{
    TypeName   = 'System.Diagnostics.Process'
    MemberName = 'UserName'
    MemberType = [Management.Automation.PSMemberTypes]::ScriptProperty
    Force      = $true
    Value      = { (Get-WmiObject Win32_Process -Filter "ProcessId =
                   $($this.Id)").getowner().user }
}
Update-TypeData @updateTypeData


ps | ? username -eq $env:username

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
    204      12     7784      15072      66.48  11880   2 conhost
    129       9     1640       8428       0.03  18440   2 conhost
    227      22     5228      14328       2.53    228   2 dllhost
    248      14    35224      29168       9.02  21708   2 emacs
   2260     154  1321228     213316     557.70  11780   2 powershell

Upvotes: 0

mmseng
mmseng

Reputation: 850

To add to Marc's answer, here is a version that works in PowerShell 7 (where Get-WMIObject is not available):

$procs = Get-CimInstance Win32_Process | Where { ($_.ProcessName -eq "pwsh.exe") -or ($_.ProcessName -eq "powershell.exe") }
$procsWithOwner = $procs | ForEach-Object {
    $owner = Invoke-CimMethod -InputObject $_ -MethodName "GetOwner" | Select -ExpandProperty "User"
    $_ | Add-Member -NotePropertyName "Owner" -NotePropertyValue $owner -PassThru
}
$procsWithOwner | Select Name,ProcessId,Owner

Source for the technique: https://devblogs.microsoft.com/scripting/get-process-owner-and-other-info-with-wmi-and-powershell/

Upvotes: 0

Alex Kwitny
Alex Kwitny

Reputation: 11544

This is faster, one line, doesn't require admin.

Get-Process | ? {$_.SI -eq (Get-Process -PID $PID).SessionId}

Upvotes: 15

user3735573
user3735573

Reputation: 51

Thanks for your code. Based on this, I created a modified version to allow users to kill (a subset of) their own processes:

#Script to allow users to kill (a subset of) their own processes 
#Based on : https://stackoverflow.com/questions/35195221/list-process-for-current-user
#Previously we used Task Nanny created by Michel Stevelmans which is a lot faster, but it did not show a process that was causing issues for our users.
$UserProcesses = @()
$Owners = @{}
Get-WmiObject win32_process | Foreach{$owners[$_.handle] = $_.getowner().user}
$Processes = Get-Process | select processname,Description,Id,@{l="Owner";e={$owners[$_.id.tostring()]}}
Foreach($Process in $Processes)
{
    IF($process.Owner -eq $env:USERNAME)
    {
        $UserProcesses += $Process
    }
}
$UserProcessesToExclude = @(
    'concentr', #Citrix Connection Center
    'conhost', #Console Window Host
    'dwm', #Desktop Windows Manager
    'explorer', #Explorer
    'Receiver', #Citrix Receiver Application
    'rundll32', #Windows host process (Rundll32)
    'ssonsvr', #Citrix  Receiver 
    'taskhost' #Host Process for Windows Tasks
    'wfcrun32' #Citrix Connection Manager
    'wfshell' #Citrix wfshell shell
)

$UserProcesses | Where{$_.ProcessName -notin $UserProcessesToExclude} | Out-GridView -Title 'Task killer - Select the process(es) you want to kill. Hold CTRL to select multiple processes.' -PassThru | Foreach{Stop-Process -id $_.Id}

Upvotes: 5

Marc
Marc

Reputation: 492

Get-Process alone will not give you this information, you'll need WMI:

$owners = @{}
gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user}
$ps = get-process | select processname,Id,@{l="Owner";e={$owners[$_.id.tostring()]}}
foreach($p in $ps) {
    if($p.Owner -eq $env:USERNAME) {
        $p
    }
}

Upvotes: 10

David Brabant
David Brabant

Reputation: 43489

You can do that through WMI. Here is an excerpt of an article you can find here.

$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

Upvotes: 12

Related Questions