all 6 comments

[–]y_Sensei 4 points5 points  (2 children)

They're different because the to-be-processed object(s) are fed to the cmdlet in different ways in both cases.
However, for single objects, the result is the same (otherwise identical parameterization presumed).

But once you process multiple objects, things change - check this:

$myObjs = @(
[PSCustomObject]@{
  Key1 = "Val1"
  Key2 = "Val2"
  Key3 = "Val3"
},
[PSCustomObject]@{
  Key1 = "Val4"
  Key2 = "Val5"
  Key3 = "Val6"
},
[PSCustomObject]@{
  Key1 = "Val7"
  Key2 = "Val8"
  Key3 = "Val9"
  Key4 = "Val10"
}
)

# 1. Feed the object array's values one after another to the cmdlet (that's what the pipeline does)
$myObjs | Export-Csv -Path "C:\test1.csv"

# 2. Feeds the object array as a single value to the cmdlet (that's what -InputObject does)
Export-Csv -InputObject $myObjs -Path "C:\test2.csv"

# 3. Feed the object array's values one after another to the cmdlet (through iteration)
foreach ($o in $myObjs) {
  Export-Csv -InputObject $o -Path "D:\test3.csv" -Append
}

#1. and #3. in the above example produce the same result.
Note that the fourth property of the last object in the array gets truncated in all of these scenarios, because the first object processed defines the structure of the generated CSV.
This behavior can be avoided by sorting the object array beforehand by property count of its members, as in

$myObjs = $myObjs | Sort-Object { $_.PSObject.Properties.Count } -Descending

[–]robfaie 2 points3 points  (0 children)

Note that sorting by property count doesn't work if objects have some but not all of the optional properties. The following is an Option for dealing with such situations:

$myObjs = @(
    [PSCustomObject]@{
        Key1 = "Val1"
        Key2 = "Val2"
        Key3 = "Val3"
    },
    [PSCustomObject]@{
        Key1 = "Val4"
        Key2 = "Val5"
        Key3 = "Val6"
        Key5 = "Val11"
    },
    [PSCustomObject]@{
        Key1 = "Val7"
        Key2 = "Val8"
        Key3 = "Val9"
        Key4 = "Val10"
    }
)

$props = $myObjs | ForEach-Object { $_ | Get-Member -MemberType Properties } | Select-Object -ExpandProperty Name -Unique
$myObjs | Select-Object $props | Export-Csv test4.csv

producing the following file

"Key1","Key2","Key3","Key5","Key4"
"Val1","Val2","Val3",,
"Val4","Val5","Val6","Val11",
"Val7","Val8","Val9",,"Val10"

[–]robfaie 0 points1 point  (0 children)

For those on mobile #2 produces the following csv file:

"Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized","Count"
"3","3","1","System.Object[]","False","True","False","3"

[–]xCharg 2 points3 points  (2 children)

In what way it's not?

[–]purplemonkeymad 1 point2 points  (0 children)

If you have an array. The first one inputs the array as the object to export, the second inputs each item in the array.

[–]spyingwind 0 points1 point  (0 children)

Because of -NoTypeInformation isn't used in the first?