There's good information in the existing answers, but let me try to bring it all together:
function DoIt($one, $two)
{
"`$one is $one"
"`$two is $two"
return $one * $two
}
produces three outputs ("return values") to PowerShell's success [output] stream (see about_Redirection), which are the evaluation results of:
- expandable string
"`$one is $one"
- expandable string
"`$two is $two"
- expression
$one * $two
The expandable strings are implicitly output - due to producing a result that is neither captured, sent to another command, nor redirected .
Similarly, the return
in return $one * $two
is just syntactic sugar for:
$one * $two # implicit output
return # control flow: exit the scope
Note:
return
is unnecessary here and never required.
While Write-Output
could be used in lieu of implicit output:
- it is only ever helpful if you want output a collection as a single object, via its
-NoEnumerate
switch.
- it is otherwise not only needlessly verbose, it slows things down.
If you want to print status information from a function without polluting the output stream, you have several choices:
Write-Host
prints to the host's display (the console, if you're running in a console window); in PSv4-, such output could neither be captured nor suppressed; in PSv5+, Write-Host
now writes to the information stream (number 6
), which means that 6>
can be used to redirect/suppress the output.
Write-Verbose
is for opt-in verbose output, which you can activate by setting preference variable $VerbosePreference
to 'Continue'
or by using the -Verbose
switch.
Write-Debug
is for opt-in debugging output via $DebugPreference
or -Debug
, though note that in the latter case a prompt is displayed whenever a Write-Debug
statement is encountered.
Because these outputs are captured in a variable - $sum = DoIt 5 4
- and there is more than 1 output, they are implicitly collected in an array (of type [object[]]
).
Using implicit output to print this variable's value to the display - $sum
- enumerates the array elements, which prints them each on their own line:
$one is 5
$two is 4
20
By contrast, using implicit output with expandable string "`$sum is $sum"
results in a single output string in which the reference to variable $sum
, which contains an array, is expanded as follows:
Thus, if you join array elements $one is 5
, $two is 4
, and 20
with a single space between them, you get:
$one is 5 $two is 4 20
To put it differently: the above is the equivalent of executing '$one is 5', '$two is 4', '20' -join ' '