5

1.ps1 has 2 objects created and printed. But only one show up in the output. Both objects show up in the following cases:
(1) write-output is done with Format-List
(2) object1 has more than 4 properties (and so it gets vertically formatted automatically)
Trying to understand the reasoning behind this behaviour.

PS C:\> cat .\1.ps1
$object1 = New-Object PSObject
$object1 | add-member NoteProperty -name pn1 -value pv1
$object1 | add-member NoteProperty -name pn2 -value pv2
$object1 | add-member NoteProperty -name pn3 -value pv3
write-output $object1

$object2 = New-Object PSObject
$object2 | add-member NoteProperty -name npn1 -value npv1
$object2 | add-member NoteProperty -name npn2 -value npv2
$object2 | add-member NoteProperty -name npn3 -value npv3
$object2 | add-member NoteProperty -name npn4 -value npv4
$object2 | add-member NoteProperty -name npn5 -value npv5
$object2 | add-member NoteProperty -name npn6 -value npv6
write-output $object2
PS C:\>
PS C:\> .\1.ps1

pn1                                     pn2                                     pn3
---                                     ---                                     ---
pv1                                     pv2                                     pv3


PS C:\>
3
  • What do do you want to see? Commented Aug 2, 2013 at 17:06
  • @StanleyDeBoer The second object, obviously. Commented Aug 2, 2013 at 17:08
  • I get that, it's just not obvious to me to expect the columns in Format-Table to change. Commented Aug 2, 2013 at 17:17

3 Answers 3

3

I think it has to do with the way Format-Table works. I think by default PowerShell will either pick Format-Table or Format-List to display objects on the console, I'm not sure how the decision is made but obviously Format-Table was chosen.

Format-Table works by taking the first object and picking the properties from that. For any object that follows the first one it will only populate the columns for the properties from the first object.

You might want to try

 .\1.ps1 | % { $_ | ft }

And see if that get's you what you are looking for.

Sign up to request clarification or add additional context in comments.

5 Comments

<5 properties, it uses Format-Table. For >5 Format-List is used. But I wonder, why would they be so dumb as to not figure out that first and second write-output have different property_names - so they could/are objects of different types.
Because most of the time commands output objects of one type at a time ( I can't think of any built-in commands that output more than one type of object at a time), So you are talking about an edge case. Edge cases are often handled differently then you might expect simply because the right behavior in one situation might be the wrong behavior in another.
ah!! - may be they don't mix formatting when running from a script. so here, object 1 will be Format-Table by default (<5 props), but object2 should be Format-List (>5 props). If the cmdlets are run on the shell, it is Format-Table for 1, and Format-List for 2. I expect the same behaviour while running it from a script too
no this shouldn't be an edge case.. I have two separate write-output statements.. not printing both objects in a single write-output
You are using Write-Output not Write-Host. The first one writes to the pipeline, the second one writes to the console
2

If you are just trying to display the information, you should be using Write-Host rather than Write-Output. You want to use Write-Output when you are sending data on in the pipeline, and shouldn't be used to simply display data.

Here is a post that gives a more in-depth answer: Which should I use: "Write-Host", "Write-Output", or "[console]::WriteLine"?

From the link:

Write-Output should be used when you want to send data on in the pipe line, but not necessarily want to display it on screen. The pipeline will eventually write it to out-default if nothing else uses it first. Write-Host should be used when you want to do the opposite. [console]::WriteLine is essentially what Write-Host is doing behind the scenes.

2 Comments

yes, that explains the behaviour. Well, the real use case in which I encountered this situation - we actually need it pipelined, so that other cmdlets can use prop/values of the object passed down the pipeline. In my opinion, the output formatting in write-host isn't visually pleasing from a customers perspective.
You can still format the Write-Host to make it more visually pleasing :)
2

I can't explain this behavior, but you can mitigate it by using an explicit formatter for the first output, e.g.:

Write-Output $object1 | Format-Table

It looks like without explicit formatting PowerShell remembers an implicitly applied table format and omits output that doesn't match this format. For instance, if you add another Write-Output $object1 at the end of the script:

$object1 = New-Object PSObject
...
write-output $object1

$object2 = New-Object PSObject
...
write-output $object2
write-output $object1

you will get this output:

PS C:\> .\test.ps1

pn1                                 pn2                                 pn3
---                                 ---                                 ---
pv1                                 pv2                                 pv3

pv1                                 pv2                                 pv3

Wat?! O_o

Why anyone would consider this a good idea is beyond me.

4 Comments

yes, as I had mentioned in my original question, format-list works. Just wanted to understand why writing to console is so hard without it. If the same prop names are not found in the next object, then why didn't they print the second object's properties,values too ?
Probably because it has a different set of properties than the first object. If you create another object with the same set of properties as $object1 (i.e. same names, but different values), it will be shown just fine.
Does that justify skipping the object completely? Ideally I would have expected ob1's prop/val printed.. followed by obj2's prop/val.. and not try and club obj2 with obj1's properties. Because they just don't match - so it is a different object.
I'd say that's what most people would expect. And I don't recall providing any kind of justification. Nor would I have intended to.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.