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
returnstatement, thereturnstatement is contractual: nothing returns output from a function except thereturnstatement. Thus, for people with experience in other languages, the presence of code likereturn $outputin 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-Outputyou 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
returncannot always be used (sometimes you need to write output more than once), you should preferWrite-Outputand usereturnonly for ending execution. But sinceWrite-Outputcan lead to false expectations and in addition is slightly slower, (and worse, can be overwritten by functions or aliases) …We recommend:
Use
returnonly 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 -NoEnumerateis 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