Search code examples
powershelladminpipelinesysinternals

How to pipe 'Elapsed Time' (or other output) from PsList


This task is incredibly simple yet I can't seem to figure it out (all the more reason it's frustrating) - I would like to query PsList for a particular process and return a specific portion of it's regular output. In example, I would like to return only the 'Elapsed Time' field from the PsList output below

Name                Pid Pri Thd  Hnd   Priv        CPU Time    Elapsed Time 
RDCMan             7384   8  22 1316  60432     0:00:54.101     5:02:31.886

such that psuedocode and behavior would be as follows:

pslist rdcman | select Elapsed Time
 > 5:02:31.886

Note: 'select' doesn't actually work in this way.

The following code snippet dances around the desired output and may be of value although I can't seem to massage it to my needs.

I've tried to find pslist's source code (no luck) to see if reverse engineering could enlighten, and played with pslist rdcman | Get-Member. None of the member information was readily informative.

Any advice?


Solution

  • If for whatever reason you have your heart set on the output from pslist you could also do this to make it into a PowerShell object

    $output = .\pslist.exe 2> $null 
    $output | Select -Skip 3 | ForEach-Object{
        $procInfo = $_ -split "\s+"
        [pscustomobject][ordered]@{
            Name = $procInfo[0..($procInfo.Count -8)] -Join " "                
            Pid = $procInfo[-7] 
            Pri = $procInfo[-6] 
            Thd = $procInfo[-5] 
            Hnd = $procInfo[-4] 
            Priv = $procInfo[-3]     
            "CPU Time" = $procInfo[-2]  
            "Elapsed Time" = $procInfo[-1] 
        }
    } | Format-Table
    

    .\pslist.exe 2> $null was to suppress the error output generated from pslist. We skip the first couple of lines in the output since the should be the same everytime.

    Process information for WYVERN:
    
    Name                Pid Pri Thd  Hnd   Priv        CPU Time    Elapsed Time 
    

    Then we split each line on groups of space to get an array. The next part should not have been as complicated but since EXE names can contain spaces we needed to account for that. The last 7 columns should never contain space so those were explicitly assigned in the [pscustomobject] that was created. Of the few items from that that we not assigned we created a space delimited string. Format-Table is there merely to make it pretty on screen. If you need to manipulate the output do so in front of the | Format-Table.

    Sample Output

    Name                      Pid   Pri Thd Hnd  Priv    CPU Time       Elapsed Time 
    ----                      ---   --- --- ---  ----    --------       ------------ 
    Idle                      0     0   4   0    0       1059:54:59.735 0:00:00.000  
    System                    4     8   146 952  220     2:13:41.415    300:01:13.336
    smss                      312   11  3   32   580     0:00:00.062    300:01:13.320
    csrss                     512   13  10  858  3076    0:00:20.139    300:01:09.763
    wininit                   628   13  3   82   1688    0:00:00.062    300:01:07.985
    csrss                     644   13  12  1514 5540    0:19:56.168    300:01:07.969
    services                  696   9   7   274  7056    0:00:39.296    300:01:07.798
    

    In the case of getting information for rdcman you could just try the following. This code is in place of the last line of the code above

    } | Where-Object{$_.Name -eq "rdcman"} | Select -ExpandProperty "Elapsed Time"
    

    or

    } ?{$_.Name -eq "rdcman"} | Select -Expand "Elapsed Time"