Hello all. I am trying to understand the below behavior. The below code is very simple and made just to present the behavior, not to be useful code.
First I have a function that generated a collection of Custom PSObjects and then uses that collection as a property for another Custom PSObject that is sent out to the pipeline along with 1 string property and 1 DateTime Object property.
function Test1 { $collection = @() foreach ($i in 0..10) { $collection += New-Object -TypeName PSObject -Property @{value1 = "1:$i"; value2 = "2:$i"; value3 = "3:$i"} }#foreach New-Object -TypeName PSObject -Property @{name = "Collection"; value = $collection; date = (Get-Date)} }#function
The result of this function to standard output is exactly what I would expect. A date property with the date, a name property with a string of “Collection”, and a value property with a collection of values
PS C:\> test1
date name value
8/31/2015 10:02:45 PM Collection {@{value1=1:0; value2=2:0; v…
I then have a second function that I want to accept the object that has been output by the first function as input for the second function.
function Test2 { [CmdletBinding()] Param ( [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)] [String]$Name, [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)] $Value, [Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)] $Date ) Begin{} Process { Write-Host "----------------------------------------------------" Write-Host $Name Write-Host "----------------------------------------------------" Write-Host $Value Write-Host "----------------------------------------------------" Write-Host $Date Write-Host "----------------------------------------------------" Write-Host $Value.Value Write-Host "----------------------------------------------------" Write-Host $Date.Date Write-Host "----------------------------------------------------" }#process End{} }#function
Below are the results of piping test1 to test2 and where I become confused.
PS C:\> test1 | test2
----------------------------------------------------
Collection
----------------------------------------------------
@{date=8/31/2015 10:07:32 PM; name=Collection; value=System.Object[]}
----------------------------------------------------
@{date=8/31/2015 10:07:32 PM; name=Collection; value=System.Object[]}
----------------------------------------------------
@{value1=1:0; value2=2:0; value3=3:0} @{value1=1:1; value2=2:1; value3=3:1} @{value1=1:2; value2=2:2; value3=3:2} @{value1=1:3; value2=2:3; value3=3:3} @{value1=1:4; value2=2:4; value3=3:4} @{value1=1:5; value2=2:5; value3=3:5} @{value1=1:6; value2=2:6; value3=3:6} @{value1=1:7; value2=2:7; value3=3:7} @{value1=1:8; value2=2:8; value3=3:8} @{value1=1:9; value2=2:9; value3=3:9} @{value1=1:10; value2=2:10; value3=3:10}
----------------------------------------------------
8/31/2015 10:07:32 PM
----------------------------------------------------
You can see by the results that $data and $value seem to contain the complete object from the pipeline rather than just the value that they were set to by the new-object in test1. This is confirmed by the fact that I can get the property I want from the variable that should contain the property value by using …
Lastly while I am very interested to know why this behaves in this manner, the ultimate goal is to do things correctly. Since this is the behavior, it is obviously not the way to handle this scenario. So what is the correct methodology for passing a collection of values as a property that can be passed through the pipeline to another function?
Thanks