Difference between using and not using pipe in Export-Csv in Powershell

大城市里の小女人 提交于 2021-02-18 13:52:11

问题


This is probably more of a 'how does PowerShell handle variables and piping' rather than a specific programmatical question, but since it seems like strange behaviour (to me) I thought I'd post it here.

I just had some difficulties exporting a variable to a CSV using PowerShell and found this Stack question that helped me a lot. However, when fiddling around with the output I got two different results depending on how I called the Export-CSV function.

I have a custom PS object that looks roughly like this:

Account      Partner     ProjectName     ProjectPhase
1            A           Test            Start
2            B           Test2           Start
3            A           Test4           End
4            C           Test3           Middle
....

When I use the following line it correctly outputs the CSV file:

$csvBody | Export-Csv -Path "$targetPath\$fileName" -Encoding Unicode -NoTypeInformation

However, when I use the following line it doesn't:

Export-Csv -InputObject $csvBody -Path "$targetPath\$fileName" -Encoding Unicode -NoTypeInformation

In this case, the output looks like this: Count,"Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized" 263,"263","263","1","System.Object[]","False","True","False"

I understand from this other Stack post that the output becomes the property of the $csvBody, which is an array. My question is why does this happen when I'm not piping the object to Export-CSV, but it doesn't happen when I am using the pipe?


回答1:


Here everything works as design and not badly written :

In the second way, the inputobject is a #TYPE System.Object[] as you can see if you keep TypeInformation.

When you call Export-Csv using the pipe, each object of the collection is sent to the process part of the Cmdlet.


Take a collection of integers :

$a = 1..4

then try :

$a | Get-Member

It gives : System.Int32

Then try :

Get-Member -InputObject $a

It gives : System.Object[]

So in your case the object exported is the array wich can be useful too.




回答2:


I think this is because Export-CSV has been written with the intention that it should (and would) generally handle input via the pipeline.

I think the behavior you are seeing occurs because the -InputObject parameter does not accept array input. You can see that from the help page:

   Export-Csv [[-Path] <String>] [[-Delimiter] <Char>] [-Append] [-Confirm] [-Encoding <String> {Unicode | UTF7 |
   UTF8 | ASCII | UTF32 | BigEndianUnicode | Default | OEM}] [-Force] -InputObject <PSObject> [-LiteralPath <String>]
   [-NoClobber] [-NoTypeInformation] [-WhatIf] [<CommonParameters>]

It is <psobject> rather than <psobject[]> and as such it expects a single <psobject> as it's input. It seemingly doesn't unroll that object when it's provided via the parameter line, instead it gives you a CSV that contains the default properties of that object itself (length etc.).

When you send the object via the pipeline, it uses the cmdlet PROCESS functionality of accepting pipeline input to unroll the object and handle each item in the collection individually.

Someone can probably explain this better than I have above, or perhaps can explain why Export-CSV doesn't work the way you expect (other than --as I assume-- by design).



来源:https://stackoverflow.com/questions/43737470/difference-between-using-and-not-using-pipe-in-export-csv-in-powershell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!