Write-Host has had a bad press over the years culminating in the infamous saying “if you use Write-Host a puppy will die” or words to that effect.
So what’s the fuss about?
Let’s take some code
Write-Host -Object “starting”
function t1 {
Write-Host -Object “In the function”
2+2
}
Write-Host -Object “pre-function”
t1
Write-Host -Object “post-function”
It’s not quite the world’s most fantastic piece of code but it’ll do for now
When you run this code you see output like this:
starting
pre-function
In the function
4
post-function
The problem is that you can’t easily separate the code output from the Write-Host messages as Write-Host does what it says and writes your message direct to the host.
What you should be doing is using one of the more specific Write cmdlets:
Write-Debug
Write-Error
Write-Host
Write-Information
Write-Progress
Write-Verbose
Write-Warning
Maybe in this case Write-Information
Write-Information -MessageData “starting” -InformationAction Continue
function t1 {
Write-Information -MessageData “In the function” -InformationAction Continue
2+2
}
Write-Information -MessageData “pre-function” -InformationAction Continue
t1
Write-Information -MessageData “post-function” -InformationAction Continue
with output of
starting
pre-function
In the function
4
post-function
But this looks just like Write-Host. In PowerShell v5 and later Write-Host is a wrapper for Write-Information
To see the difference remove the –InformationAction parameter and use this horribly contrived code
$inf = @()
Write-Information -MessageData “starting” -InformationVariable a
$inf += $a
function t1 {
Write-Information -MessageData “In the function” -InformationVariable a
$inf += $a
2+2
}
Write-Information -MessageData “pre-function” -InformationVariable a
$inf += $a
t1
Write-Information -MessageData “post-function” -InformationVariable a
$inf += $a
If you look at the contents of $inf you see the messages
starting
pre-function
post-function
Notice you’ve lost the message from within the function – we’ll come back to that another time
You have a record with some interesting data
PS> $inf | gm TypeName: System.Management.Automation.InformationRecord Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() Computer Property string Computer {get;set;} ManagedThreadId Property uint32 ManagedThreadId {get;set;} MessageData Property System.Object MessageData {get;} NativeThreadId Property uint32 NativeThreadId {get;set;} ProcessId Property uint32 ProcessId {get;set;} Source Property string Source {get;set;} Tags Property System.Collections.Generic.List[string] Tags {get;} TimeGenerated Property datetime TimeGenerated {get;set;} User Property string User {get;set;}
For instance
PS> $inf | select TimeGenerated, MessageData TimeGenerated MessageData ------------- ----------- 29/06/2018 20:25:44 starting 29/06/2018 20:25:44 pre-function 29/06/2018 20:25:44 post-function
could be useful for tracing progress
There’s a lot more in the write cmdlets that we’ll come back to another time