Lets say I have an array of objects with some properties, one of which is itself an array of objects. I want to ‘flatten’ this structure & report each of the embedded objects alongside selected attributes from its parent object.
ExpandProperty seems ideal, but why is the expanded object updated on the source object? and how to prevent this?
Here’s a simple test setup
$json = '[{"Name":"James","Age":42,"Books":[{"Title":"Consider Phlebas","Author":"Iain M. Banks"},{"Title":"The Player of Games","Author":"Iain M. Banks"}]},{"Name":"Susan","Age":36, "Books":[{"Title":"The Three Body Problem","Author":"Cixin Liu"},{"Title":"The Dark Forest","Author":"Cixin Liu"}]}]
$obj = $json | ConvertFrom-Json
$obj |FT
Name Age Books
---- --- -----
James 42 {@{Title=Consider Phlebas; Author=Iain M. Banks}, @{Title=The Player of Games; Author=Iain M. Banks}}
Susan 36 {@{Title=The Three Body Problem; Author=Cixin Liu}, @{Title=The Dark Forest; Author=Cixin Liu}}
This statement produces exactly the output I am after
$obj | Select-Object -Property Name -ExpandProperty books
Title Author Name
----- ------ ----
Consider Phlebas Iain M. Banks James
The Player of Games Iain M. Banks James
The Three Body Problem Cixin Liu Susan
The Dark Forest Cixin Liu Susan
But the sting in the tail is my original object is modified (the Name property from the parent object has been added to each embedded book object) & if I run the last command again I get the error Select-Object : The property cannot be processed because the property “Name” already exists.
$obj | FT
Name Age Books
---- --- -----
James 42 {@{Title=Consider Phlebas; Author=Iain M. Banks; Name=James}, @{Title=The Player of Games; Author=Iain M. Banks; Name=James}}
Susan 36 {@{Title=The Three Body Problem; Author=Cixin Liu; Name=Susan}, @{Title=The Dark Forest; Author=Cixin Liu; Name=Susan}}
This just seems weird. I thought select-object created a new object as output from each input object, but ExpandProperty appears to update the source object. How can I get the output I want without modifying the input object, and such that I can run the statement again without error