What is the difference in result by write-host and write-output?
Asked Answered
V

4

2

I am new to PowerShell and while doing some code I came through this thing. While I use Write-Host and Write-Output to perform the same query, I get different results:

PS> Write-Output $PSVersionTable                                                                                                                   

Name                           Value                                                                                                                                               
----                           -----                                                                                                                                               
PSVersion                      5.0.10586.117                                                                                                                                          
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                             
BuildVersion                   10.0.10586.117
CLRVersion                     4.0.30319.17929
WSManStackVersion              3.0                                                                                                                                                 
PSRemotingProtocolVersion      2.3                                                                                                                                                 
SerializationVersion           1.1.0.1                                                                                                                                             

vs.

PS> Write-Host $PSVersionTable                                                                                                                   
System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry
Vudimir answered 19/8, 2016 at 8:21 Comment(0)
I
2

Important difference:

Write-output writes an object to the pipeline, so the next command can accept it as it's input. While Write-host just write directly to the console.

In your example

Write-Output will write the object to the pipeline, and Out-Default (Hidden at the end of the pipeline) will display the object values in either a table or a list.

Write-Host writes directly to the console instead of using the default cmdlet Out-default in the end of the pipeline. In other words, Write-Host does not write anything to the pipeline, only displays what he sees to the console.. This is why you can add parameters like -foregroundcolor to the Write-Host cmdlet, but not to the Write-output cmdlet.

Write-Host is useful when debugging and you need to display text in diffrent colors.

You can simply test this with

Write-Output "Hello World" | Get-Member

We can se that this is a System.String Object.

If we run:

Write-Host "Hello World" | Get-Member

We get an error: gm : You must specify an object for the Get-Member cmdlet ...

Inflatable answered 19/8, 2016 at 16:26 Comment(0)
C
1

Here are the two top results when doing a google search:

PowerShell difference between Write-Host and Write-Output?

Which should I use: "Write-Host", "Write-Output", or "[console]::WriteLine"?

*Edit: Write-Host does not support the data type of $PSVersionTable while Write-Output does. To see which one supports which data type you can use

Get-Help Write-Host
Get-Help Write-Output
Cut answered 19/8, 2016 at 8:28 Comment(3)
Eric I have already checked these. Please check the image that I have uploaded along with the question. Thnx anyways😃Vudimir
Ah, I didn't view the picture, I've added a few rows to my answer now.Cut
Quibble: It's not that Write-Host doesn't support [System.Management.Automation.PSVersionHashTable], the data type of $PSVersionTable; it simply stringifies it in a way that isn't helpful to the human observer, mainly because it is typically used for printing strings; both Write-Host and Write-Output support (accept) instances of any type, but (a) their way of stringifying them differs and (b) - more importantly - Write-Output and Write-Host serve very different purposes (as the linked articles explain, but not your answer per se).Helvetii
H
1

It sounds like you already know that Write-Host and Write-Output have different purposes; in short:

  • To produce (data) output, simply use a command or expression as-is, which implicitly outputs it to the success (data) output stream - explicit use of Write-Output is rarely needed:

    • Instead of Write-Output $PSVersionTable, you can simply use $PSVersionTable by itself.
  • Write-Host, in PSv4-, prints directly to the host (e.g., the console), bypassing PowerShell's output streams, which is why it should generally be avoided. While it is integrated into PowerShell's output streams since v5, via new stream #6, it's better to use its successor, Write-Information - unless you need to produce console-only output for creating interactive experiences, such as writing prompt strings, espically if colored display is needed.


To explain the difference in console output:

  • Write-Output, just like implicit output, uses PowerShell's default output formatting, which typically provides a much friendlier representation than just calling .ToString() on the underlying .NET type instances - see Get-Help about_Format.ps1xml

    • $PSVersionTable.GetType().FullName tells us that $PSVersionTable is an instance of [System.Management.Automation.PSVersionHashTable], which derives from [System.Collections.Hashtable], which PowerShell's default formatting renders in a 2-column table layout.
  • Write-Host essentially calls just .ToString() on its arguments, which in many cases simply prints the full type name of an object.

    • Calling .ToString() on a [System.Management.Automation.PSVersionHashTable] instance would yield just 'System.Management.Automation.PSVersionHashTable'.
      However, Write-Host prints the elements of objects that support the [IEnumerable] interface individually.

    • Thus, each entry in $PSVersionTable is printed separately, and since entries are of type [System.Collections.DictionaryEntry], which also stringifies to simply the type's full name - System.Collections.DictionaryEntry - you get a space-separated list of these strings (because Write-Host generally joins distinct outputs with a single space each).

Note that you can explicitly request a string representation of PowerShell's default output formatting via the Out-String cmdlet.

Therefore, aside from the stream-integration aspect, the following Write-Host command produces the same console output as Write-Output $PSVersionTable (or, simply: $PSVersionTable):

Write-Host ($PSVersionTable | Out-String)

Another important difference is that if you pass multiple objects or arrays (enumerables) as arguments (rather than via the pipeline):

  • Write-Output formats each input object individually, as in the pipeline; e.g., Write-Output 1, 2 yields two lines:

    1
    2
    
  • Write-Host prints a single, space-separated list of the stringified input objects; e.g., Write-Host 1, 2 yields a single line:

    1 2
    

The same applies if you pass these value as individual arguments (rather than as an array); that is, Write-Output 1 2 and Write-Host 1 2 yield the same respective output.

Helvetii answered 23/8, 2017 at 2:7 Comment(0)
V
0

And another good article: Which Write Is Right For PowerShell?

In short $PSVersionTable return hash table (collection of objects). Write-host command is trying to convert everything to string and then to show it at the console, but you can not convert the whole hash-table directly to string.

Write-Output directly send this hash table to console without trying to change it.

Vinculum answered 19/8, 2016 at 8:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.