I am adding a .NET type to PowerShell session using Add-Type and then creating object of that type using New-Object. This is done as follows:
Add-Type -AssemblyName OuterObj
$a = New-Object OuterObj
Object of type OuterObj is successfully created. Now .NET type $a has a field named innerObj which is object of another .NET type innerObject. So I add innerObject .NET type and create an instance using New-Object:
Add-Type -AssemblyName innerObject
$b = New-Object innerObject
Object of type innerObject is also successfully created. Now I do as follows:
$a.innerObj = $b
Now when I print $a, it shows something like this:
innerObj : innerObject
Thus it does not display the contents of innerObject by default. When I go and explore, innerObj has the fields. I know PowerShell does not show the nested objects by default but instead just shows their types, but is there a way I can specify that what level of nesting of objects PowerShell should show by default? Is there something to specify to show 1 or 2 levels of nested objects?
Any help would be highly appreciated.
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
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With