0

I have an array of PSCustomObject created with several properties on them. Some properties are ints, some strings, and others are what I surmise to be dictionary object (the objects are being returned from Invoke-RestMethod) Here's an example:

> $items[0]

id       : 42
name     : Modularize the widget for maximum reuse
priority : {[id, 1], [order, 1], [name, High]}
project  : {[id, 136], [name, Wicked Awesome Project]}

Ultimately, what I want to do is to "flatten" this structure so that I can pipe to to Export-CSV and all the data is retained. Each property would become a column. Example:

id             : 42
name           : Modularize the widget for maximum reuse
priority_id    : 1
priority_order : order
priority_name  : High
project_id     : 135
project_name   : Wicked Awesome Project

So, my thought was to enumerate through the properties and if any one is a Dictionary/HashTable/PSCustomObject to enumerate through it's properties and add them the to parent property to flatten this structure out.

However, I have not been able to successfully infer whether or not a property is a Dictionary/HashTable/PSCustomObject. I loop through all the properties like so.

 foreach($property in $item.PsObject.Properties)
 {
     Write-Host $property
     Write-Host $property.GetType()
     Write-Host "-------------------------------------------------------------"

     # if a PSCustomObject let's flatten this out
     if ($property -eq [PsCustomObject])
     {
        Write-Host "This is a PSCustomObject so we can flatten this out"
     }
     else
     {
        Write-Host "Use the raw value"
     }

 }

For properties that appear to be PSCustomObject this prints out the following.

 System.Management.Automation.PSCustomObject project=@{id=135}
 System.Management.Automation.PSNoteProperty
 -------------------------------------------------------------

However, I am unable to to conditionally check that this ia PSCustomObject. All conditionals that I have tried fall under the else condition. I have tried replacing [PSCustomObject] with [Dictionary] and [HashTable]. Note that checking the type won't help since they all appear to be PSNoteProperty.

How can I check that a property is in fact a PSCustomObject and therefore needs to be flattened?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Ryan Taylor
  • 8,740
  • 15
  • 65
  • 98

2 Answers2

2

The following code will determine whether or not a property of a PSCustomObject is also a PSCustomObject.

foreach($property in $item.PsObject.Properties)
{
    Write-Host $property
    Write-Host $property.GetType()
    Write-Host "-------------------------------------------------------------"

    # if a PSCustomObject let's flatten this out
    if ($property.TypeNameOfValue -eq "System.Management.Automation.PSCustomObject")
    {
       Write-Host "This is a PSCustomObject so we can flatten this out"
    }
    else
    {
       Write-Host "Use the raw value"
    }
}
Ryan Taylor
  • 8,740
  • 15
  • 65
  • 98
0

To check if variable is of given type, you shouldn't use comparison operator -eq, but type operator -is:

$psc = New-Object -TypeName PSCustomObject

if ($psc -is [System.Management.Automation.PSCustomObject]) {
    'is psc'
}
if ($psc -is [Object]) {
    'is object'
}
if ($psc -is [int]) {
    'is int'
} else { 
    "isn't int"
}
AdamL
  • 12,421
  • 5
  • 50
  • 74
  • This does not work for my scenario. Note that I am attempting to loop through all the properties in a given object and I want to determine which of those properties, if any, are also PSCustomObjects. – Ryan Taylor Jul 24 '14 at 22:11