Reputation: 51
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.
Upvotes: 4
Views: 2870
Reputation: 4838
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
Upvotes: 3