MshObject and Methods that take object

Every once in a while people ( including me) run into trouble calling methods that take object. Why? Well, as I told you earlier objects in MSH are wrapped by an invisible MshObject. As it turns out that this invisible object is not always so invisible. Take a look at the following:

MSH>$key = get-item .

MSH>$hash = @{}

MSH>$hash[$key] = 'foo'

MSH>$hash[$key]

foo

MSH>$hash.ContainsKey($key)

False

MSH>

Weird huh? On the one hand you can use the key to access the object. On the other hand it tells you that the hashtable doesn’t really have that key. What’s going on? Well, if you take a look at the method ContainsKey (Here’s a neat trick on how to do it):

MSH>$hash.ContainsKey

MemberType : Method

OverloadDefinitions : {System.Boolean ContainsKey(Object key)}

TypeOfValue : System.Management.Automation.MshMethod

Value : System.Boolean ContainsKey(Object key)

Name : ContainsKey

IsInstance : True

You can see that the method takes object. Because it takes object MSH doesn’t know whether you actually meant to pass the method the MshObject or the object contained by the MshObject. So it goes ahead and makes the decision of passing the MshObject. However, that wasn’t the key used earlier. The key that was used was the actual BaseObject. What to do? What to do? Well, if you ever run into this situation here are two things you can do. The first is to use the MshObject property I showed you earlier and access the BaseObject property:

MSH>$hash.ContainsKey($key.MshObject.BaseObject)

True

The second is to cast the object to the actual type that you want.

MSH>$hash.ContainsKey([IO.DirectoryInfo]$key)

True

Try to keep this in mind when working with methods that take object.

- Marcel

Comments

  • Anonymous
    September 03, 2005
    The comment has been removed
  • Anonymous
    September 04, 2005
    The comment has been removed
  • Anonymous
    September 25, 2005
    Calling Methods on WMI Object

    this script keeps saying there is no Uninstall Method in win32_Product (there is!)

    -------------

    $computer="LocalHost"

    $Progs=$(get-wmiobject win32_Product -computer $computer)

    foreach ($p in $Progs) {

    If ($P.Caption -eq "MowTool Setup")
    {
    "Prog $($p.Caption) Found"

    $R = $p.baseobject.Uninstall()
    " Return $($R) "
    }
    Else
    {
    "Progs $($p.Caption) Skipped"
    }
    } #end foreach
    --------

    This Vbscript Version Does Work

    --------
    Computer = "."

    Set objWMIService = GetObject("winmgmts:" & Computer & "rootcimv2")
    Set colItem = objWMIService.ExecQuery("Select * from Win32_Product")


    For each objItem in colItem
    if objItem.Caption = "MowTool Setup" then
    wscript.echo "Found " & objItem.Caption
    objItem.Uninstall()
    else
    wscript.echo "skipped " & objItem.Caption
    end if
    Next

    ---------

    Where is the method gone in the MSH version ?

    someone got a clue ?

    greetings //o//
  • Anonymous
    September 26, 2005
    The comment has been removed
  • Anonymous
    November 16, 2005
    The comment has been removed