PowerShell: avoid Write-Output, use Return only for ending execution, use $Output variable for returning additional output
Posted by jpluimers on 2021/02/18
Recently, I bumped into [WayBack] Write-Output
confusion for the upteenth time.
Luckily I had the below links archived, basically invalidating the use of Write-Output
, and invalidating the answer at [WayBack] powershell – What’s the difference between “Write-Host”, “Write-Output”, or “[console]::WriteLine”? – Stack Overflow.
- [WayBack] Write-Output vs. Return vs. $Output · Issue #46 · PoshCode/PowerShellPracticeAndStyle · GitHub
@maekee to sum up this long thread: In other programming languages with a
return
statement, thereturn
statement is contractual: nothing returns output from a function except thereturn
statement. Thus, for people with experience in other languages, the presence of code likereturn $output
in PowerShell is misleading. They think: “oh, ok, PowerShell has a return statement” and don’t realize that any un-captured result values get output also — and don’t even realize they can output multiple times.The reasoning for, and objection to, Write-Output is similar. People like it because:
… always explicitly sending an object to a stream… makes it easier to understand [the code] at a glance in the future.
The problem is that this can lead to a false sense of security. If you see
Write-Output
you assume that output can only come from lines withWrite-Output
, when in reality it can come from any command or method call. Or at least, any that doesn’t start with an assignment (or[void]
cast), or end with out-null …So while some people like it because it highlights the spots where you intentionally output something — other people argue it’s presence distracts you from the fact that other lines could output.
Therefore
Since
return
cannot always be used (sometimes you need to write output more than once), you should preferWrite-Output
and usereturn
only for ending execution. But sinceWrite-Output
can lead to false expectations and in addition is slightly slower, (and worse, can be overwritten by functions or aliases) …We recommend:
Use
return
only for ending execution.Avoid Write-Output (although you may want to use for it’s -NoEnumerate switch). Instead, when you want to make output clearer, just assign output to a relevantly named variable. and put that a variable on a line by itself to signal explicit output.
-
and
Jaykulcommented 12 hours ago
TIL Write-Output -NoEnumerate
is broken on PowerShell 6 and has been for 16 months or longer — there’s no plan to fix it. In summary:DO NOT USE Write-Output — EVER.
- [WayBack] Write-Output -NoEnumerate outputs PSObject[] rather than Object[] and generally doesn’t respect the input collection type · Issue #5955 · PowerShell/PowerShell · GitHub
Via:
[WayBack] Joel Bennett on Twitter: “
Write-Output considered EVEN MORE harmful! Most #PowerShell experts recommend against Write-Output
Now, I find there is a long standing bug in PowerShell 6’s -NoEnumerate switch.
--
jeroen
Jaykulcommented on Aug 2, 2016