I don't know of any built-in functionality for this, but it is pretty easy to create a function which should get you where you want to go. Here's an example:
function ConvertTo-NestedPropertyHash
{
PARAM (
[Parameter(ValueFromPipeline=$true)]
[object[]]$InputObject
,
[string[]]$ExpandProperty
)
PROCESS
{
foreach($item in $InputObject)
{
$hash = @{}
$processStack = New-Object System.Collections.Stack
$processStack.Push(@{ Item = $item})
while($processStack.Count -gt 0)
{
$current = $processStack.Pop()
$prefix = $current.Prefix
$object = $current.Item
foreach($property in $object | gm | where membertype -eq "Property")
{
if ($Prefix)
{
$propertyPath = "$Prefix.$($property.Name)"
}
else
{
$propertyPath = $Property.Name
}
$propertyValue = $object."$($property.Name)"
if ($ExpandProperty -contains $propertyPath)
{
$processStack.Push(@{
Prefix = $propertyPath
Item = $propertyValue
})
}
else
{
$hash.Add($propertyPath, $propertyValue)
}
}
}
Write-Output $hash
}
}
}
The above function lets you specify properties (with a dot-notation for subproperties) which you want expanded. So given the following types:
Add-Type -TypeDefinition @"
public class InnerInnerType
{
public string Name{get;set;}
}
public class InnerType
{
public string Name{get;set;}
public string Description{get;set;}
public InnerInnerType MyChild{get;set;}
}
public class OuterType
{
public string Name{get;set;}
public InnerType InnerThingy {get;set;}
}
"@
And the following objects created:
$outer = New-Object OuterType
$inner = New-Object InnerType
$childToInner = New-OBject InnerInnerType
$outer.Name = "outer name"
$inner.Name = "inner name"
$inner.Description = "inner description"
$childToInner.Name = "inner inner thingy"
$outer.innerthingy = $inner
$inner.MyChild = $childToInner
You could use the function without asking it to expand any properties, like so:
$outer | ConvertTo-NestedPropertyHash
Which would yield the following output:
Name Value
---- -----
Name outer name
InnerThingy InnerType
Or you could ask it to expand the InnerThingy property:
$outer | ConvertTo-NestedPropertyHash -ExpandProperty InnerThingy
Which yields:
Name Value
---- -----
InnerThingy.MyChild InnerInnerType
Name outer name
InnerThingy.Description inner description
InnerThingy.Name inner name
Or you could also specify nested properties using dot-notation (current implementation of the function requires that you expand a property to be able to expand sub-properties from that property, so you'd need to do -ExpandProperty InnerThingy, "InnerThingy.MyChild" if you want to expand the MyChild nested property), like the following:
$outer | ConvertTo-NestedPropertyHash -ExpandProperty InnerThingy, "InnerThingy.MyChild"
Which yields:
Name Value
---- -----
Name outer name
InnerThingy.Description inner description
InnerThingy.MyChild.Name inner inner thingy
InnerThingy.Name inner name
ps1xmlfile for your type (start by readingGet-Help about_types.ps1xml). Otherwise, you could use my answer below.