The other day I was involved in a short Twitter debate about the relative merits of using Return vs Write-Object (or its alias Write) in PowerShell functions. Here’s my take.
I treat Return as a legacy keyword. You may have used this often in functions written in other languages. In a PowerShell function however, it will return the specified value to the pipeline and then exit the function. This is not a big deal if your function can only return one value anyway such as a function to convert Fahrenheit to Celsius. However, if the code in your function will return multiple objects, you won’t get them all using the Return keyword. Here’s an example.
Function Test-Return {
Write-Host "This function will use the RETURN keyword" -foregroundcolor CYAN
$data=Get-Service | where {$_.status -eq "stopped"}
#this returns a single item
foreach ($item in $data) { Return $item.displayname}
}
If you run this code you will only get a single object returned. Compared this with a function that uses Write.
Function Test-Write {
Write-Host "This function will use the WRITE keyword" -foregroundcolor CYAN
$data=Get-Service | where {$_.status -eq "stopped"}
foreach ($item in $data) {write $item.displayname}
}
This will send all objects to the pipeline.
I’m certainly aware that there are ways to write a function so that Return will send all objects to the pipeline. You can also use Return to send an array to the pipeline which also gets around the limitation. But why bother? Why not simply use Write-Object all the time and avoid the confusion. Even in a function that can only return a single value, like my temperature conversion example, using Write-Object makes it very clear what PowerShell is going to do. Return can be a little ambiguous. Return what to where?
I occasionally use Return in a function when I specifically want its behavior, but I consider this more an exception rather than the rule.
My recommendation is to relegate Return to the VBScript and text based shells or scripting languages of the past and embrace Write-Object and the PowerShell paradigm.
Oh, and if you want to follow the PowerShell discussions on Twitter, I’m at http://twitter.com/JeffHicks and you’ll find a lot of people to follow, including other PowerShell MVPs at http://wefollow.com/tag/powershell
If you’re so fond of the Powershell paradigm, please use the full name of the cmdlet you’re discussing. I almost mistaked your Write(-Output) for Write-Host, which can only output a single property value (e.g. a string, which is what you are using in the example). Some people use write-host a lot, and thus ignore the rich object-based architecture of powershell. If you remember to keep Return outside any loops, you should be fine. But as I understand from your post, Write-Output is even better!
Hugo
http://www.peetersonline.nl
I’m sold.. I was a fan of return, but I’m going to switch to Write-Object, as it makes more overal sense with the pipeline.
I do disagree as to the ambiguity of the return statement though.. it returns to the value to the place where the function was called from.
Returning an array also has the negative side effect of making your function stop and collect all values sent to the pipeline before continuing processing, which can make your script use up much more memory than you need to.
Another convert to write-object here. Thanks again, Jeff.