0

I have a binary cmdlet Get-CustomPSObject. When I do something like:

Get-CustomPSObject > a.txt

the result is stored as a plain text, meaning that the Get-CustomPSObject is working fine.

However when I try:

Get-CustomPSObject | Export-csv a.csv

The a.csv file becomes:

"Capacity","Count","IsReadOnly","IsFixedSize","SyncRoot","IsSynchronized"
"4","1","False","False","System.Object","False"

none of these fields are in my PSObject. I've no idea what they stands for. Any thoughts?

Frode F.
  • 52,376
  • 9
  • 98
  • 114
jamesdeath123
  • 4,268
  • 11
  • 52
  • 93

2 Answers2

2

Export-CSV takes the first object it recieves to create the headers. Most likely, your Get-CustomPSOjbect runs a method/cmdlet/script that returns an object you didn't save. E.g. you use something like

get-childitem

and not

$files = get-childitem

inside your Get-CustomPSObject function.

EDIT Okay, so you're cmdlet is a binary cmdlet. Important information. I'm no expert in this, so please correct me if I'm wrong.

When you make a binary cmdlet that can output multiple objects, you need to write them one by one. One of the ideas behind PowerShell is the use of a pipeline that can use objects as they come without waiting for the complete array.

Because of your current "design flaw" in your binary cmdlet, Export-CSV tries to export the array(as one item) to a csv-file and not the elements inside.

You now use this:

WriteObject(list/array of objects)

This is bad. It outputs all objects at the same time.

To fix it, run this at the end of your "object-creation-loop":

WriteObject(mycurrentobject) 

This is good. You enable the use of pipeline and every object is sent out one by one when they're created. Export-CSV can then recieve each object and convert them to csv-format.

Frode F.
  • 52,376
  • 9
  • 98
  • 114
  • the Get-CustomPSObject finally writes to pipeline through WriteObject($list of PSObject); what do you suggest to do with that? – jamesdeath123 Mar 14 '13 at 14:48
  • Well, first. I'd update the question to include that the cmdlet is a binary cmdlet. Second, see updated answer – Frode F. Mar 14 '13 at 14:59
  • You are right that writobject within the loop does the trick! Thanks! – jamesdeath123 Mar 14 '13 at 15:20
  • Great :-) If you consider this the correct answer, please verify it with the checkmark next to the question. It will help future readers figure out the solution. – Frode F. Mar 14 '13 at 15:24
  • done! actually one more question here: if I do writeObject(PSObject) in a loop and pipeline them to next cmdlet, for example Get-CustomPSObject | Export-csv a.csv , does powershell gets all objects and then pass to the next cmdlet and run Export-csv for once, or does it executes Export-csv everytime writeObject writes an object,? – jamesdeath123 Mar 14 '13 at 15:41
  • It executes every object seperately without knowing how many there are going to be. It keeps the instance/session of `export-csv` open until it doesn't recieve any objects. That's why `Export-CSV` will create the csv-header based on the FIRST object you pass through, so the first object needs to have every properties that will appear later. – Frode F. Mar 14 '13 at 15:50
1

In your first example using > the output is run through Powershell formatting system while in the second using export-csv it is not.

If you look at get-custompsobject | gm you should see those extra properties that aren't shown in console or sent to your text file.

For export-csv you can control which properties are sent to the csv file using select-object

get-custompsobjct | select-object column1, column2 | export-csv a.csv
Chad Miller
  • 40,127
  • 3
  • 30
  • 34
  • hmm you are right that Get-Custompsobjct |gm returns all the members and properties of list object, and the properties are exactly the content exported to csv (capacity\counts, etc.) but Select-Object column1, coumn2 listed objects that contains only the key of the parameter but no the values, e.g.: get-custompsobjct | select-object column1, column2 gives: ObjectId: (blank) Name:(blank) . I have no idea what the select-object doesnt grab the values too? Supposingly it should look like: ObjectId: 123 Name: 'Object-Name' – jamesdeath123 Mar 14 '13 at 14:56
  • voted because you provide a good way to debug pipeline stuff, although Graimer's answer did solve my question :) – jamesdeath123 Mar 14 '13 at 15:28