none
Change default formatting of output from PowerShell script RRS feed

  • Question

  • I have a PowerShell script intended for testing a web application. It outputs various types of objects that contain data parsed from HTTP responses. I want the script to display this data by default, so that I can see what it is doing, and I also want to be able to capture the output to a variable so that I can examine the properties of the objects in more detail.

    When I am not capturing the output of the script to a variable or piping it to a cmdlet, PowerShell 5.1 appears to format the output as if I had piped it to Format-Table, which chooses the columns of the table based on the properties of the first object. My problem is that the other objects have entirely different properties and Format-Table generally does not display them at all.

    I can simulate the behavior by using this command:

    @( [System.Tuple]::Create(10); [System.Collections.Generic.KeyValuePair[[Int],[Int]]]::new(20, 21); ) | Format-Table

    The output is:

    Item1 Length
    ----- ------
       10      1

    That is, the Key and Value properties of the KeyValuePair object do not appear at all. The same happens if I omit the Format-Table invocation. In contrast, if I pipe the objects to Format-List, then the output is more useful:

    Item1  : 10
    Length : 1
    
    Key   : 20
    Value : 21
    

    How does PowerShell decide to use Format-Table to format the output?

    Can I put something in the script to make PowerShell default to Format-List instead, while retaining the ability to pipe the original objects to other cmdlets?

    Wednesday, January 9, 2019 4:31 PM

Answers

  • PowerShell outputs objects (not text), so why does the formatting of the output objects matter?

    If you want a specific format, collect the properties of the objects you want, output them as a list of custom objects, and format them afterwards.


    -- Bill Stewart [Bill_Stewart]


    Wednesday, January 9, 2019 5:09 PM
    Moderator

All replies

  • PowerShell outputs objects (not text), so why does the formatting of the output objects matter?

    If you want a specific format, collect the properties of the objects you want, output them as a list of custom objects, and format them afterwards.


    -- Bill Stewart [Bill_Stewart]


    Wednesday, January 9, 2019 5:09 PM
    Moderator
  • If you analyze the code you will see that it is bogus.  You are trying to make a table out of two dissimilar items in an array. The first item returned will be the one that decides the properties.

    PS D:\scripts> @(
    >>     [System.Tuple]::Create(10)
    >>     [System.Collections.Generic.KeyValuePair[[Int], [Int]]]::new(20, 21)
    >> )
    
    Item1 Length
    ----- ------
       10      1
    
    
    
    PS D:\scripts> [System.Tuple]::Create(10)
    
    Item1 Length
    ----- ------
       10      1
    
    
    PS D:\scripts> [System.Collections.Generic.KeyValuePair[[Int], [Int]]]::new(20, 21)
    
    Key Value
    --- -----
     20    21
    
    
    PS D:\scripts>

    Format-List formats each object separately.

    PS D:\scripts> @(
    >>     [System.Tuple]::Create(10)
    >>     [System.Collections.Generic.KeyValuePair[[Int], [Int]]]::new(20, 21)
    >> ) | Format-List
    
    
    Item1  : 10
    Length : 1
    
    Key   : 20
    Value : 21

    Do not create arrays of dissimilar objects if you want consistent output Or. As Bill noted, create a custom code block to format the results as you want.


    \_(ツ)_/

    Wednesday, January 9, 2019 5:17 PM
  • If I pipe the output of the script to Format-List, then I get the format that I want.

    However, it would be more convenient if that happened automatically. PowerShell already implicitly formats the objects and I'd like to know if that can be controlled or tricked somehow.

    It seems that, if the first output object is a dummy Hashtable like @{a=1}, then PowerShell formats that as an IEnumerable<DictionaryEntry> table and formats the subsequent objects as if by Format-List. That would be handy except the dummy object at the start of the output looks ugly. An empty Hashtable unfortunately does not have the same effect.

    Wednesday, January 9, 2019 5:19 PM
  • I refer the honorable gentleman to my first reply posted some minutes ago.

    -- Bill Stewart [Bill_Stewart]

    Wednesday, January 9, 2019 5:22 PM
    Moderator
  • No.  The formatting choice is determined by the first element returned.  If you look in the format file for the objects you are using you will see the formats applied by object type.  The object type of an array will always force the selection of a table if the first object in the array does not have a format specified that is different.

    See: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_format.ps1xml?view=powershell-6


    \_(ツ)_/

    Wednesday, January 9, 2019 5:25 PM
  • The actual types of objects output by the script are:

    1. System.Management.Automation.PSCustomObject
    2. System.Management.Automation.PSCustomObject
    3. System.Management.Automation.PSCustomObject
    4. System.Management.Automation.PSCustomObject
    5. Microsoft.PowerShell.Commands.WebResponseObject
    6. Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject
    7. System.Net.HttpWebResponse

    where each PSCustomObject is the result of Invoke-RestMethod.

    Do you then recommend making the script invoke Format-List on its own? With perhaps a SwitchParameter to suppress this formatting.

    Wednesday, January 9, 2019 5:25 PM
  • I'll go ahead and repeat my first message...

    PowerShell outputs objects (not text), so why does the formatting of the output objects matter?

    If you want a specific format, collect the properties of the objects you want, output them as a list of custom objects, and format them afterwards.


    -- Bill Stewart [Bill_Stewart]

    Wednesday, January 9, 2019 5:57 PM
    Moderator
  • You're correct Bill.

    Except.

    You need to actually comprehend what is being asked. And this is something I've tried to find the answer to, and just like this, time and time again I end up going back and forth with a guy like you - who is correct in his answer about the technical specs of a specific command output, or whatever the case. But who is either unable to speak normal english, or be able to wrap their heads around what the other guy on the other end of the blog comments is asking - instead can only comprehend the technical specifications of the tool or language or whatever.

    Technically, PowerShell outputs objects - yes, you're correct, Bill.

    What is being asked however, is essentially this (rephrased slightly):

    "I write a lot of little scripts to lookup data, because in actuality - in the real world, that's why we all write code - to help us do tasks quicker - like lookup an employee'd profile data by their Employee ID. In doing so, I find that I'm quite often typing " | Format-List" or " | Format-Table" at the end of every command - because I want to be able to easily scan and read the output.

    That said, is there a way to set an environment variable, or set a profile parameter somewhere in something, that would automatically tack on that " | Format-List" for every command I write - or at least for the commands that output data in a way that could be formatted into a Table or List?"

    In bash in Linux, I'd setup an alias in my .bash_profile - can something similar be done with PowerShell?

    Answering that would be helpful. 

    Thursday, July 25, 2019 6:08 AM
  • You're correct Bill.

    Except.

    You need to actually comprehend what is being asked. And this is something I've tried to find the answer to, and just like this, time and time again I end up going back and forth with a guy like you - who is correct in his answer about the technical specs of a specific command output, or whatever the case. But who is either unable to speak normal english, or be able to wrap their heads around what the other guy on the other end of the blog comments is asking - instead can only comprehend the technical specifications of the tool or language or whatever.

    Technically, PowerShell outputs objects - yes, you're correct, Bill.

    What is being asked however, is essentially this (rephrased slightly):

    "I write a lot of little scripts to lookup data, because in actuality - in the real world, that's why we all write code - to help us do tasks quicker - like lookup an employee'd profile data by their Employee ID. In doing so, I find that I'm quite often typing " | Format-List" or " | Format-Table" at the end of every command - because I want to be able to easily scan and read the output.

    That said, is there a way to set an environment variable, or set a profile parameter somewhere in something, that would automatically tack on that " | Format-List" for every command I write - or at least for the commands that output data in a way that could be formatted into a Table or List?"

    In bash in Linux, I'd setup an alias in my .bash_profile - can something similar be done with PowerShell?

    Answering that would be helpful. 

    The answer is no.  There is no way to do that.

    The recommendation, as always, is that you learn the basics of any technology that you want to work with.  You cannot ask others in a technical forum to learn this for you.

    Also be aware that tagging a new question on another users question is not allowed in most technical forums.  It is hijacking and is not helpful to the original poster (OP) and not helpful to others who will use answered questions and discussions.

    If you have a question please open your own topic.  Her eare som links that will help you get started in technical forums:

    Please carefully review the following links to set your expectation for posting in technical forums.

    Learning to script properly with PowerShell


    \_(ツ)_/

    Thursday, July 25, 2019 6:26 AM
  • If I have hijacked this post, then I apologize. The intention wasn't to hijack, but to simply rephrase what I believed the original poster's question to be. Albeit in a sarcastic manner - but you have to expect that when the responses are essentially "you clearly don't know what you're talking about" instead of "that's not actualy correct, because x, y and z". No matter how many different ways I phrase my question, to various search engines, I end up at this post over and over. If every search engine seems to think that this is the same question I'm asking (or close to it), and in reading it, I believe my question to be essentially the same as the original poster's question - should I not rephrase to clarify it? If that's hijacking, then so be it I suppose - my bad. 


    I appreciate your quick, concise answer to my question, so thank you. That is something that is possible in bash and other shells, so it would seem appropriate that PowerShell would have some mechanism of doing the same. Totally great that it doesn't.

    The ony comment I'll make with regard to your recommendation is this. This is bloody TechNet - this is where IT professionals have been going for a very long time, to post questions and have the community attempt to assist in answering them. That's how we all learn. And that's why there are community forums! Had you posted a question to any forum in which I was an expert, I wouldn't have ever told you to go learn the technology. Instead I would have concisely answered the question, given a very brief explanation as to why, and suggested some sites that provide appropriate level documentation. 

    What happens on this forum by the commenter I was replying to, is never helpful to anyone. It brushes off the site visitor, essentially saying "I'm too smart to answer this rediculous question. How can you not know everything there is to know about this subject, if you're going to post here?". When in fact, that's the whole reason people ask questions on forums.

    Again, thank you for your reply and quick answer. 

    Have a great day.

    Thursday, July 25, 2019 12:51 PM
  • Questions about a script that a user has written are acceptable.

    This is not a bash forum.  Bash answers won't work.  You complaints are misleading to others as you do not know PS.

    It is incumbent on users posting here to make some attempt to learn the technology. After all this is a technical forum.

    Your complaints have been registered although I can't see where they are helpful.  They are just complaints.


    \_(ツ)_/

    Thursday, July 25, 2019 1:08 PM
  • To add to the OPs issue. The array will only enumerate the first value because the enumerator for formatting will always take the properties of the first object in the collection. If other objects are structured differently they won't display.

    This will display them:

    PS D:\scripts> $x = @(
    >>      [System.Tuple]::Create(10)
    >>      [System.Collections.Generic.KeyValuePair[[Int], [Int]]]::new(20, 21)
    >> )
    PS D:\scripts> $x[0]
    
    Item1 Length
    ----- ------
       10      1
    
    
    PS D:\scripts> $x[1]
    
    Key Value
    --- -----
     20    21
    

    As Bill has noted, you need to build custom objects or build a custom formatter.

    A simple extraction will show this:

    PS D:\scripts> $x|%{"$_"}
    (10)
    [20, 21]

    Note that the 2 objects are different in topology.


    \_(ツ)_/


    • Edited by jrv Thursday, July 25, 2019 1:15 PM
    Thursday, July 25, 2019 1:12 PM
  • perhaps this will explain it better:

    PS D:\scripts> $x | select key,value,item1,length
    
    Key Value item1 length
    --- ----- ----- ------
     20    21
                       10    1
    
    # we can further illuminate this quandary like this: (notice how asking for explicit properties
    # overrides the default PS behavior.) PS D:\scripts> $x | select key,value Key Value --- ----- 20 21 PS D:\scripts> $x | select item1,length item1 length ----- ------ 10 1 PS D:\scripts>

    Yes.  Programming is a bitch if you are not a trained programmer.  It is not what most think it is.  PowerShell can add a layer of further doubt to the mix.


    \_(ツ)_/






    • Edited by jrv Thursday, July 25, 2019 1:30 PM
    Thursday, July 25, 2019 1:17 PM
  • I'm not going to reply after this - but seriously?

    PowerShell is a shell correct? The first real Shell ms has actually had, correct? I am correct - but that's besides the point. 

    If PowerShell is a shell for Windows. I would just say this - isn't it reasonable for users familiar with shells for other operating systems to make generalize assumptions about this Windows Shell? 

    For the record, you have no idea what I do know and don't - what I was saying is that I am familiar with the bash shell, and that this particular issue can easily be solved using it. If it can't in PowerShell, great - but that's what I was posting to ask. 

    Again, have a great day, and thank you.

    Thursday, July 25, 2019 1:24 PM
  • I apparently lied about the previous being my last post....

    There you go JRV. Was that so hard?

    Thursday, July 25, 2019 1:26 PM
  • I refer you to I'm not going to reply after this - but seriously?

    PowerShell is a shell correct? The first real Shell ms has actually had, correct? I am correct - but that's besides the point. 

    If PowerShell is a shell for Windows. I would just say this - isn't it reasonable for users familiar with shells for other operating systems to make generalize assumptions about this Windows Shell? 

    For the record, you have no idea what I do know and don't - what I was saying is that I am familiar with the bash shell, and that this particular issue can easily be solved using it. If it can't in PowerShell, great - but that's what I was posting to ask. 

    Again, have a great day, and thank you.

    I refer you to the book "Windows PowerShell in Action v3" for a complete explanation of what PS is and what it is not.   PS is way more than a simple shell.  It also does not work like any other shells.

    There is no standard definition for a "shell" other than it is usually interactive and supports a language that allows implementing a program contraflow environment 

    Bash cannot solve this issue because it is an issue requiring the Net framework.  The example code uses net objects that are not available in Bash.  Bash is a specific shell for a much different type of processing.  It cannot do what PowerShell does which is why I objected.  You are making  many assumptions based on a limited understanding of all of the technologies you are criticizing. 

    To learn a sophisticated technology it is necessary to study that technology.

    To the original issue.  The answer to the OP was that custom objects would need to be created to allow the PS formatters to work correctly.  There is no language that can resolve different object topologies directly.  Some form of manipulation must be done to obtain a useful output.  Enummerators usually get their output structure from the fist object.  There are ways to override that as I have shown but the default enumerator will not work with the PS format CmdLets.

     

    \_(ツ)_/

    Thursday, July 25, 2019 2:06 PM
  • You need to actually comprehend what is being asked.
    ...
    ...is there a way to set an environment variable, or set a profile parameter somewhere in something, that would automatically tack on that " | Format-List" for every command I write - or at least for the commands that output data in a way that could be formatted into a Table or List?"

    I really do understand what's being asked. This is why I asked the follow-up question (which, as can be noted, was never answered). My follow-up question reveals the misunderstanding that seems to be inherent in the question.

    If you need list formatting, append "| fl" to your command line. I don't think you'd want that automatically appended to every command you run, though, because then you really would lose data.


    -- Bill Stewart [Bill_Stewart]

    Thursday, July 25, 2019 2:13 PM
    Moderator