Sonntag, 27. Dezember 2009

Small Get-Process Puzzle

Hello PowerShell folks,

here I have a small puzzle for you. Please start only one instance of PowerShell odr PowerShell_ISE and run the following script.

$p1 = get-process powershell*             
$p2 = get-process powershell*


$p1 -eq $p2

Compare-Object $p1 $p2 -IncludeEqual

This time I'm not confuesed, that Compare-Object tells that both processes are equal. This time I wonder why $p1 is not equal To $p2.

When you invoke $p1 a number of times, you will see that the value CPU(s) increases. My natural expectation here is same PID same process.

Is this a PowerShell or a .NET issue ?
Do I better keep using WMI?

I get the rather strange feeling 'The more I learn, the less I know'.



  1. Hi Bernd,

    Get-Process will produce live objects, Even if they are saved to a variable.

    Consider the following. # start calc.exe
    12 > $calc = get-process calc

    13 > $calc | fl name, HasExited

    Name : calc
    HasExited : False

    # Now stop calc.exe
    14 > $calc | fl name, HasExited

    Name : calc
    HasExited : True

  2. Yes Andy,
    HasExited and CPU are dynamic properties.
    PM and WS seems to be static properies.

    But I think this is independent of the fact, that the returned objects are different. That is because the objects are constructed on the fly and no direct pointers to some internal datastructure.

    The interessting fact is that
    $a = get-wmiobject win32_process
    $b = get-wmiobject win32_process
    Compare-Object $a $b
    seems to compare based on PID,

    $a = Get-process
    $b = Get-Process
    Compare-Object $a $b
    seems to compare based on ProcessName.

    I guess the latter is a bug.

  3. If you do some poking around, you will see that Compare-Object defaults to the value of ToString(). For a System.Diagnostics.Process object, that method returns the object type and the name of the process. For Win32_Process, it returns the object path (and type) and the PID.