Get-Process Piped to Dir

Get-Process Piped to Dir

  • Comments 10

Did you know that you can pipe the output of Get-Process into dir?  Don't believe it?  Let me prove it:


PS> Get-Process wi*
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     95       4     1080       2892    32     0.30    536 wininit
    126       3     1848       4612    41     1.11    640 winlogon
    676      22    28656      20332   187    40.09   2344 WinMail


PS> Get-Process wi* |dir
    Directory: Microsoft.PowerShell.Core\FileSystem::E:\Windows\system32


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/30/2006   2:21 AM      95232 wininit.exe
-a---         8/30/2006   2:21 AM     306688 winlogon.exe


    Directory: Microsoft.PowerShell.Core\FileSystem::E:\Program Files\Windows Mail


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/29/2006   5:04 PM     120320 WinMail.exe

So you might ask the question: how is the possible?
The answer is easy: code!  :-)

 

 

DIR will operate on anything that has a property called path.  You can validate this with a CSV file:

PS> cat data.csv
Path
c:\autoexec.bat
c:\win*
PS> Import-Csv data.csv |Dir

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/10/2004  11:04 AM          0 autoexec.bat
d----          9/8/2006   7:13 PM            WINDOWS
d----         5/11/2006   8:50 AM            winhec
d----        10/26/2005   8:48 PM            WINNT
d----          5/9/2006   2:25 PM            winrm


 

 

So all we had to do was to ensure that Process Objects had a PATH property which mapped to the filename of the executable. 

Alas, our friends in the .NET team failed us here - they provided no such Path.  But instead of whining, we just rolled up our sleeves and fixed the problem.  You see this is one of the key scenarios for the Extended Type System.  The people who produce types are just one source of data about the object.  To paraphrase Brandon Sullivan - the community is not a potted plant - it has a role to play here.  You can extend any type with the data you need.  We've done that for you for a few objects to show you the way.  Let's look at the PATH property of the Process object:

PS> Get-Process |Get-Member path
   TypeName: System.Diagnostics.Process

Name MemberType     Definition
---- ----------     ----------
Path ScriptProperty System.Object Path {get=$this.Mainmodule.FileName;}

 

This is a SCRIPTPROPERTY which means "run these scripts to get/set a value" (here we only provide a GETTER).  The variable $THIS is set to the Process object that this property is attached to. 

Thus when a Process object is piped to DIR, the parameter binder sees that DIR can pipeline objects that have a PATH property so it tries to retrieve this from the Process object which runs the script and returns the value.  Its a beatiful thing.

Now you may see some interesting results if the process object does not report a PATH (which is the case for SYSTEM and IDLE).  This binds a NULL to DIR which causes a dir of your current directory.  As such, you might want to always add a where clause

Get-Process |Where {$_.Path} | Dir

So the question is - why would you ever want to do this?  Imagine the case that your system started to act flaky, you might want to know which of the processes was most recently updated.  You can do that this way (Note that this uses MSINCE - a utility that I blogged about earlier today):

PS> Get-Process |Where {$_.Path} |Dir |Sort LastWriteTime |
>> F
ormat-Table fullname,
>> 
@{Label="Updated (Weeks)";Expr={MSince$_.LastWriteTime Weeks}} -auto

FullName                                                  Updated (Weeks)
--------                                                  ---------------
E:\Windows\system32\CCM\CcmExec.exe                                    32
E:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe               4
E:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe               4
E:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe               4
E:\Program Files\Microsoft Office\OFFICE12\OUTLOOK.EXE                  3
E:\Program Files\Windows Defender\MSASCui.exe                           3
E:\Program Files\Windows Mail\WinMail.exe                               3
E:\Windows\system32\SearchIndexer.exe                                   3
E:\Windows\System32\mobsync.exe                                         3
E:\Program Files\Windows Sidebar\sidebar.exe                            3
E:\Windows\System32\snmp.exe                                            3
E:\Program Files\Windows Media Player\wmplayer.exe                      3
E:\Windows\system32\psxss.exe                                           3
E:\Windows\system32\csrss.exe                                           3
E:\Windows\system32\csrss.exe                                           3
E:\Windows\system32\DllHost.exe                                         3
E:\Windows\system32\Dwm.exe                                             3
E:\Windows\Explorer.EXE                                                 3
E:\Program Files\Internet Explorer\ieuser.exe                           3
E:\Program Files\Internet Explorer\iexplore.exe                         3
E:\Program Files\Internet Explorer\IEXPLORE.EXE                         3
E:\Program Files\Internet Explorer\iexplore.exe                         3
E:\Windows\system32\lsass.exe                                           3
E:\Windows\system32\lsm.exe                                             3
E:\Windows\system32\notepad.exe                                         3
E:\Windows\system32\services.exe                                        3
E:\Windows\system32\SLsvc.exe                                           3
E:\Windows\system32\smss.exe                                            3
E:\Windows\System32\spoolsv.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\System32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\System32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\system32\svchost.exe                                         3
E:\Windows\System32\svchost.exe                                         3
E:\Windows\System32\svchost.exe                                         3
E:\Windows\system32\taskeng.exe                                         3
E:\Windows\system32\taskeng.exe                                         3
E:\Windows\system32\taskeng.exe                                         3
E:\Windows\System32\tcpsvcs.exe                                         3
E:\Windows\system32\wininit.exe                                         3
E:\Windows\system32\winlogon.exe                                        3
E:\Windows\system32\wbem\wmiprvse.exe                                   3
E:\Windows\system32\wuauclt.exe                                         3
C:\systemInternals\autoruns.exe                                         0

 

 

This was pretty interesting because if you look at the dates, it is clear that there are 4 waves of change here.  The latest is the a SystemInternals utility that I installed today.  Then there are a bunch of system processes because I just installed Vista RC1 (3 weeks ago).  Then there is the version of PowerShell (4 weeks ago).  Then there is CcmExec updated 32 weeks ago.  That was curious - I couldn't image what that could be so I did the following to solve the mystery:

PS> Get-Process CCMEXEC |fl Name,Description,FileVersion,Product
Name        : CcmExec
Description : CCM Executive
FileVersion : 2.50.4160.2000 built by: SMS
Product     : Systems Management Server

Investigate your system - you'll discover all sorts of cool things.

 

Enjoy!

Jeffrey Snover [MSFT]
Windows PowerShell/Aspen Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

 

PSMDTAG:TYPEEXTENSION: ScriptProperty Process Path

Leave a Comment
  • Please add 7 and 2 and type the answer here:
  • Post
  • I am having a trouble with "gps wi* | ls" example.

    For some reason, "path" for "winlogon" is returned as "\??\c:\winnt\system32\winlogon.exe" and therefore, "ls" is generating the following error.

    [^_^]PS[73]>gps wi* | ls
    Get-ChildItem : Cannot find drive. A drive with name '\??\c' does not exist.
    At line:1 char:12
    + gps wi* | ls <<<<

    I am not sure whether it's a problem with culture setting or not.

    My culture is set to "en-US" while UI culture is set to "ko-KR".

    I have checked other processes , but also, "csrss" had a same problem with the path where it started with "\??\c".
  • If you search the internet, you'll see that other system management tools display the same path for WinLogon.exe so this is the data that the parent process is setting for this process.  I'm not sure what or why that is (e.g. feature or bug) but it does not work that way on Vista.

    If you were looking for a reason to update - now you have it.  :-)

    Jeffrey Snover [MSFT]
    Windows PowerShell/Aspen Architect
    Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
    Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx


  • wicked!!
  • "I'm not sure what or why that is (e.g. feature or bug) but it does not work that way on Vista. " Could it be because winlogon.exe is executed by NT and not Windows API code, and in NT \\?\ is normally used? (Just a shot in the dark!)
  • I'm using RC2 and don't seem to get the following bit working:

    @{Label="Updated (Weeks)";Expr={MSince$_.LastWriteTime Weeks}} -auto

    I have to take out the "MSince" and "Weeks" bit.

    Any ideas?

    Regards,

    Ray

  • Msince is a function that Jeffrey introduced in a previous blog entry:

    http://blogs.msdn.com/powershell/archive/2006/09/17/Useful-DateTime-functions-LibraryTimeps1-.aspx

    -bruce

    Bruce Payette [msft]

    ============================

    Windows PowerShell in Action

  • Slightly off-topic, but why doesn't get-process take a -computerName parameter?  The .Net Process.GetProcesses() method even has an overload for remote machines.  If I want to do anything w/ remote machines, I'm forced to use the WMI Win32_Process class instead.

  • What is searchindexer.exe and why is it using 50% of my PCU?

  • A number of PowerShell MVPs and PowerShell team members are helping me to compile a table of contents

Page 1 of 1 (10 items)