According to the MSDN for Strongly Encouraged Development Guidelines:
Cmdlets should not use the Console API.
Why is this?
If I write [Console]::Write("test")
, it works just as well as
Write-Host "test"
EDIT:
It's well known that Write-Host
should be avoided. When MSDN says to not use the Console API, is it safe to assume that they are implying that we should not use Write-Host
either since that uses the Console API behind the scenes?
Many IT professionals use it as a way to connect remotely to other computers and servers. When engaging in this process, PowerShell can leave some loopholes open for security breaches. This is the major drawback of using PowerShell script.
PowerShell is as case-insensitive as possible while preserving case.
Cmdlets differ from commands in other command-shell environments in the following ways: Cmdlets are instances of . NET classes; they are not stand-alone executables. Cmdlets can be created from as few as a dozen lines of code.
PowerShell Formatting Overview PowerShell has a set of commands that gives you control over how you wish to display the output for any particular object. The names of all the cmdlets begin with the verb Format . You can use these cmdlets to decide how you like to see the data.
The main reason you shouldn't use console-related functionality is that not all PowerShell host environments are consoles.
While the typical use case is to run PowerShell in a console, PowerShell does not need a console and can cooperate with different kinds of host environments.
Thus, for your code to remain portable, it shouldn't assume the existence of a console.
It is safe, however, to assume the existence of (the abstraction called) host, which PowerShell exposes via the automatic $HOST
variable.
The capabilities of hosts vary, however, which has historically created problems even when not using the console API directly, but its PowerShell abstraction, Write-Host
- see below.
PowerShell provides a hosting API,
with which the PowerShell runtime can be embedded inside other applications. These applications can then use PowerShell functionality to implement certain operations, including those exposed via the graphical interface.
https://en.wikipedia.org/wiki/PowerShell
The regular PowerShell console using the Console Window Host (conhost.exe
) on Windows is therefore just one implementation of a PowerShell host - the PowerShell ISE is another example, as is the Microsoft Exchange Server management GUI (2007+).
As for Write-Host
:
Up to PSv4, as the name suggests, it used to write to the host - which may or may not be a console - so Write-Host
could actually fail on hosts that don't support user interaction; see this question.
Starting with PSv5, Write-Host
is safe to use, because it now writes to the newly introduced, host-independent information stream (number 6
) - see Get-Help about_Redirection
and the next section.
Note that Write-Host
still does and always has generated output outside of the normal PowerShell output stream - its output is meant to be "commentary" (feedback to the user) rather than data.
While Write-Host
is safe to use in PSv5+, it exist for backward compatibility, so instead consider usingWrite-Information -InformationAction Continue
or using Write-Information
with preference variable $InformationPreference
set to Continue
, because:
"Write-Host" is now a bit of a misnomer, given that it doesn't actually directly write to the host anymore.
Write-Host
, in the interest of backward compatibility, doesn't integrate with the $InformationPreference
preference variable - see below.
Write-Host
still offers console-inspired formatting parameters (-ForegroundColor
, -BackgroundColor
), which not all hosts (ultimately) support.
Write-Host
vs. Write-Information
:
Tip of the hat to PetSerAl for his help with the following.
Write-Information
, introduced in PSv5, is the cmdlet that fully integrates with the new, host-independent information stream (number 6
).
Notably, you can now redirect and thus capture Write-Information
/ Write-Host
output by using 6>
, something that wasn't possible with Write-Host
in PSv4-.
Also note that this redirection works even with $InformationPreference
's default value, SilentlyContinue
, which only governs the display, not the output aspect (only using common parameter -InformationAction Ignore
truly suppresses writing to the stream).
In line with how PowerShell handles errors and warnings, the display behavior of Write-Information
is controllable via the new $InformationPreference
preference variable / the new common -InformationAction
cmdlet parameter.Write-Information
's default behavior is to be silent - $InformationPreference
defaults to SilentlyContinue
.
Note that Write-Information
has no direct formatting parameters[1] and instead offers keyword tagging with the -Tags
parameter[2]
.
By contrast, for backward compatibility, Write-Host
effectively behaves likeWrite-Information -InformationAction Continue
, i.e., it outputs by default, and the only way to silence it is to use Write-Host -InformationAction Ignore
[3]
- it does not respect an $InformationPreference
value of SilentlyContinue
(it does, however, respect the other values, such as Inquire
).
[1] PetSerAl points out that you can pass formatting information to Write-Information
, but only in an obscure fashion that isn't even documented as of PSv5.1; e.g.:Write-Information -MessageData ([System.Management.Automation.HostInformationMessage] @{Message='Message'; ForegroundColor='Red'}) -InformationAction Continue
[2] Note how parameter name "Tags" actually violates one of the strongly encouraged cmdlet development guidelines: it should be "Tag" (singular).
[3] PetSerAl explains that this behavior stems from Write-Host
passing the PSHOST
tag to Cmdlet.WriteInformation
behind the scenes.
[Console]::Write
or Write-Host
are basically the same. They both write a message to the console which can be seen on the screen.
The basic reason why this is discouraged is that it breaks the workflow. The output of a Write-Host
cmdlet can't be piped or used further. Now if the script runs on a machine without graphical output or similar constraints the command is lost.
According to this and this thread, you should therefore rather use Write-Output
, which sends the output message to the pipeline where it can be further used. Further, you can use exceptions if your message is meant to signal an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With