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

[Edit: Monad has now been renamed to Windows PowerShell. This script or discussion may require slight adjustments before it applies directly to newer builds.]