Share via


Getting User Names for Processes

Sometimes, I am in awe at the PowerShell team.  Other times, I am stunned, but at their inability to grasp common user scenarios.  PSH3, for example, finally allows Get-ChildItem to specify “files only” or “directories only” (but their way of specifying attributes is a whole other syntax, which leads me to think it was specced out by someone utterly unfamiliar with PSH.)

Even in PSH3, the common question of “Okay, who owns CPU_HOG.exe?” isn’t easily available.  Yes it is available, and has been since PSH1, but that means it has the same rough edges as so many of the other PSH1 artifacts.  Specifically, there doesn’t seem to be a way to get there from Get-Process (huh?).  You have to use Get-WMIObject WIN32_Process.

Fun. 

Okay, my complaints about the design aside, here’s the way I do it.

function Get-ProcessByUsername {
     param (
         [string[]]$Name = @('*'),
         [string[]]$UserName = @($env:USERNAME),
         [string[]]$ComputerName = @($env:COMPUTERNAME)
     );

     begin {
         $Name = $Name | % { $_.ToLower(); }
         $UserName = $UserName | % { $_.ToLower(); }
     }

     process {
         Get-WMIObject -ComputerName $ComputerName -Class WIN32_Process | % {
             $process = $_;
             if (($Name -eq @('*')) -or ([array]::IndexOf($Name, $process.Name) -ne -1)) {
                 if ( $user = $process.GetOwner().User) {
                     $user = $user.ToLower();
                     if (($UserName -eq @('*')) -or ([array]::IndexOf($UserName, $user) -ne -1)) {
                         Add-Member -InputObject $process -MemberType NoteProperty -Name UserName -Value $user;
                         $process;
                     }
                 }
             }
         }
     }
}

Get-ProcessByUserName | Select-Object -Property Name, UserName, ProcessId, CSName

 

The last line is both an example on how to use it, AND a warning: WMI objects contain a lot of redundant, extraneous, esoteric, and otherwise irrelevant data for most uses.  (Of course, when you need the QuotaPeakPagedPoolUsage, then it’s good to have, but most of the time, most users won’t care.) 

Additionally, that wonderful invisible formatter at the end of any command or command pipline?  The one that often hides the relevant data and gives you only three or four of the most commonly used fields?  It evidently doesn’t work with WMI objects.  If you just send the raw output to STDOUT without selecting your properties, you’ll get screenfull after screenfull of that irrelevant data.