Powershell check if variable is an object

Question:

[Edit after both answers said lack of clarity]
My Goal: Perform different operations depending if what is passed to a function is an “object” type thing (e.g. an array, a hashtable) or just a simple “string” type thing. If it’s just a string, I’ll simply include it in the body of the email. If it’s an array or hashtable, I need to do a bunch of processing on it to convert it into an HTML table.

[Original Question Text]
I’m passing a variable $body to a function Email-Report that can either be a simple string or an object (e.g. a hashtable or array).
I want to check if $body is an object and do different things depending.
My problem is $body could be almost anything, not just a string or a hashtable. So I can’t just check if $body.GetType().Name -eq String

I’ve tried $body.GetType().Name which returns

However if the variable is an array BaseType becomes System.Array so I can’t filter on that property, also as mentioned above the $body variable may not always be a hashtable or an array.
If it’s a hash table, $var.GetType() returns a BaseType of System.Object, however I can’t seem to refer to the BaseType property.
($hash.GetType()).BaseType returns another object itself, which itself has a BaseType property which is blank.

I’ve also tried $body.IsObject and $body.IsObject() but those methods don’t seem to exist. I’ve also tried $body -eq [System.Object] which I expected to be $true, but it returns $false.

Not sure where to go from here – I think I’m missing something obvious or having a logic error.

Answer:

It’s not entirely clear from the question what your goal or motivation is here, but here goes:

Every single object in PowerShell ultimately inherits from System.Object due to the nature of .NET’s type system, so it’s a bit of a silly test to attempt to employ type identity comparison for, since you could simply do:


If you want to test that the the object in question is not a value type (ie. not a struct or an integral type, but a class), inspect the IsValueType property of the type:


If you want a generalized solution to test whether a certain type occurs in the type hierarchy of an object, there are three general approaches:

  1. Rely on PSTypeNames
  2. Use the -is operator
  3. Resolve all base types yourself

PSTypeNames

All objects in PowerShell have a special property called PSTypeNames that contains the type names of all types in the type hierarchy for the underlying object + (optionally) PowerShell-defined type extension names – this is how PowerShell differentiates formatting of instances of different CIM classes for example.

Since PSTypeName can be manipulated by the user directly, this is inherently “unsafe”, but will work in most cases:

Builtin type operator(s)

Since PowerShell 3.0 we have two new type operators: -is and its negated counterpart -isnot. These actually inspect the runtime type of the underlying .NET object, so they’re safer than inspecting the synthetic PSTypeNames property:

-is automatically tests for base types and interfaces as well (all statements below are $true):

These operators, along with the related -as operator, are documented in the about_Type_Operators help topic.

Resolve type hierarchy manually

Finally, if we want to explore a little further we can resolve the type hierarchy manually by simply dereferencing GetType().BaseType until we hit System.Object. Below is a simple helper function that emits all the base types, which we can then compare against:

Note that you could just use -is instead of Test-IsType, except if you specifically wanted to test for base classes only, not also for interfaces.

Source:

Powershell check if variable is an object by licensed under CC BY-SA | With most appropriate answer!

Leave a Reply