When learning PowerShell, one of the first things you learn is that the command
Write-Host is super useful. It lets you write messages to the console and
allows you to specify optional foreground and background colors.
However, the very next thing you learn is:
Write-Host- it can’t be suppressed or redirected.
So how do you write messages to the user?
In PowerShell 5, a new stream was introduced. PowerShell already had Verbose, Debug, Warning, Error, and Output streams, but it was now time to add an Information stream. Ed Wilson has a great write-up on its introduction here.
One of the key problems with
Write-Host is that it goes directly to the host
implementation. There it is consumed and effectively ‘lost’ to the user.
Write-Information and the new stream, users
can now redirect the stream and modify its impact using
and the common parameter
-InformationAction for cmdlets.
With the new stream available, the implementation of
Write-Host was then changed
to redirect to
Write-Information. To make the changes non-breaking the
-InformationAction is always treated as
Continue to ensure that
existing uses of
Write-Host continue to display as they did in previous
versions of PowerShell.
If a cmdlet calls
Write-Hostthe user can never hide that message from the console.
For example, all of these messages are still displayed even when attempting to
But what about colours?
Write-Information does not. People continue to use
Write-Host and in doing so they continue to prevent the user from using
-InformationAction as intended.
So how can we use the information stream and also have colours? Let’s take a
look at the source code to see how
Write-Host is now implemented.
NOTE: This isn’t the actual Windows PowerShell version of the code, but by checking the PowerShell Core implementation we should get a handle on how things currently work as well as how things work in the future.
What we can see is the construction of a
containing the parameters from the cmdlet. This is then passed on to
along with a tag of
Taking a look at the implementation for
Write-Information we can see that the tags are checked to see if the the
PSHOST tag is provided and a tag of
FORWARDED is missing or the current information preference is
In the event that this check is passed, the
MessageData of the current record
is tested as a
HostInformationMessage and if found, the message is then
decomposed and its values used to communicate to the host.
Before all of these checks, there is a call to
where (I assume…) the normal writing of the record occurs.
From this information we now understand:
- When calling
Write-Hostthe parameters are packed up and passed to
Write-Informationwill process the parameters as a special type if
- A tag of
PSHOSTexists and a tag of
- or The current preference variable is
- A tag of
We can therefore conclude:
PSHOSTtag will ensure only the preference variable impacts visibility.
Taking everything we’ve learnt so far, we can now build a function that will support user-specified colours when viewed in a console, but also honour the visibility of the information stream:
By using the new function, we get all the benefits of the information stream
and its associated preference variable as well as the simple coloured output
Write-Host also supports.
You can grab all the examples from this post here