166

What is the difference between Write-Host and Write-Output in PowerShell?

Like...

Write-Host "Hello World";

Write-Output "Hello World";
kame
  • 20,848
  • 33
  • 104
  • 159
daniyalahmad
  • 3,513
  • 8
  • 29
  • 52

6 Answers6

143

In a nutshell, Write-Host writes to the console itself. Think of it as a MsgBox in VBScript. Write-Output, on the other hand, writes to the pipeline, so the next command can accept it as its input. You are not required to use Write-Output in order to write objects, as Write-Output is implicitly called for you.

PS> Get-Service

would be the same as:

PS> Get-Service | Write-Output
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • 13
    If you are calling a function that has a return value, do NOT use Write-Output in that function or that string will be returned instead of your return value. Which can cause all kinds of havoc. – Brain2000 Sep 11 '19 at 02:03
  • Be aware, that Write-Output does NOT support colorizing Text like ``-BackgroundColor DarkGreen -ForegroundColor White`` – Gill-Bates Dec 06 '22 at 09:09
53

Write-Output sends the output to the pipeline. From there it can be piped to another cmdlet or assigned to a variable. Write-Host sends it directly to the console.

$a = 'Testing Write-OutPut'  | Write-Output
$b = 'Testing Write-Host' | Write-Host

Get-Variable a,b

Outputs:

Testing Write-Host

Name                           Value                                                                 
----                           -----                                                                 
a                              Testing Write-OutPut                                                  
b                                                  

If you don't tell Powershell what to do with the output to the pipeline by assigning it to a variable or piping it to anoher command, then it gets sent to out-default, which is normally the console so the end result appears the same.

mjolinor
  • 66,130
  • 7
  • 114
  • 135
17

Write-Output sends the data as an object through the pipeline. In the Questions example it will just pass a string.

Write-Host is host dependent. In the console Write-Host is essentially doing [console]::WriteLine. See this for more info.

kame
  • 20,848
  • 33
  • 104
  • 159
Chad Carisch
  • 2,422
  • 3
  • 22
  • 30
  • 6
    Just to clarify for future readers. `Write-Ouput` sends objects. This time it was a string, but in general it will send objects, and is normally unnecessary to use as it is the default way to output results/data :) – Frode F. Nov 03 '13 at 17:20
  • Since PowerShell 5.0, `Write-Host` no longer writes directly to the console. Instead, it writes to the new [information stream](https://learn.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/whats-new/informationstream-overview?view=powershell-7.3), which _may_ end up in the console, if not redirected (e.g. `Write-Host 'foo' 6>&1 | Set-Content file.txt`). – zett42 Jun 13 '23 at 18:40
9

Another difference between Write-Host and Write-Output:

  • Write-Host displays the message on the screen, but it does not write it to the log

  • Write-Output writes a message to the log, but it does not display it on the screen.

And Write-Host is considered as harmful. You can see a detailed explanation in Write-Host Considered Harmful.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Summer
  • 259
  • 3
  • 3
  • 3
    I find Write-Output much more harmful. How are you making sure a function actually returns your expected result and not some unexpected garbage output from a command? – MKesper Nov 30 '16 at 10:44
  • 10
    I think `Write-Output` displays the message on the screen, if you're running the script by yourself. So i'm not sure what you're meaning with "Write-Output writes a message to the log, but it does not display it on the screen." ? – Jim Aho Aug 30 '18 at 12:14
  • You cannot have Write-Output return information to the screen if it is used inside a function from which you capture output to a variable. It may even ruin the output. Write-Host is better suited for this. – galmok Jul 08 '19 at 14:35
  • @Summer Write-Output is harmful, Write-Information is fantastic. Write-Output is the enemy of Powershell functions that have return values. – Brain2000 Sep 11 '19 at 02:20
  • 3
    [According to the docs](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-information?view=powershell-5.1#description), "Starting in Windows PowerShell 5.0, Write-Host is a wrapper for Write-Information This allows you to use Write-Host to emit output to the information stream." – Phistrom Oct 10 '19 at 18:39
  • All versions of "I just want to output something to the screen thanks, in a sequential order with my script code" are broken in PowerShell. It's a case of "the designers trying to be too fancy/philosophical instead of catering to the needs of users". Users want to output to screen sometimes. PowerShell does not allow, in a rational way, the goal of "I just want to output some text to the screen in my code, sequentially, and maybe colour some of the output to highlight information". This functionality exists in *every* programming language except for PowerShell, where it is a broken mess. – YorSubs Dec 22 '19 at 11:44
5

One more thing about Write-Host vs Write-Output: inline String concatenation may not work as expected.

$sampleText = "World"    
Write-Host "Hello" $sampleText

returns

Hello World

but

$sampleText = "World"    
Write-Output "Hello" $sampleText

returns

Hello
World

This would encourage Write-Output with a variable (and use of concatenation) holding the entire string at once.

$hw = "Hello " + $sampleText
Write-Output $hw
SrJoven
  • 196
  • 1
  • 4
  • 1
    Neither of the first two snippets are (explicitly) concatenating strings, though. In both cases the cmdlet is being passed two separate parameters, but the difference is in what they do with them: `Write-Host` without `-NoNewLine` must write one line of output and so ends up appending its inputs, whereas `Write-Output` just outputs its two input objects, which are naturally rendered on separate lines. You don't need a separate variable to combine the two strings, though, you just need to pass them as one parameter: `Write-Output ("Hello " + $sampleText)` or `Write-Output "Hello $sampleText"`. – Lance U. Matthews Oct 13 '22 at 04:23
1

You can understand the difference between the two cmds with below example:

Write-host "msgtxt" | Get-Service

On running above, you will get output as "msgtxt"

Write-output "msgtxt" | Get-Service 

On running above, you will receive an error since msgtxt is not the name of any service.( In ideal condition) (Since you are writing it to a pipeline and it is being passed as input to Get-Service)

Greg
  • 3,861
  • 3
  • 23
  • 58
LAKSHAY ARORA
  • 127
  • 1
  • 6