I\'ve learned from this Stack Overflow question, that PowerShell return semantics are different, let\'s say, from C#\'s return semantics. Quote from the aforementioned quest
echo
is an alias for Write-Output which sends the object to the next command.
Using Write-Host should help:
PS:> function Calculate
>> {
>> # Every function that returns has to echo something
>> Write-Host "test"
>> return 11
>> }
>>
PS:> $A = Calculate
test
PS:> $A
11
PowerShell does pipes awkwardkly. To work around the return value problem and save the pipeline for real data, pass the function a value by reference, that is, an array. The array can be loaded with the value you wish to return. Here's a simple example:
# tp.ps1
# test passed parameters
# show that arrays are passed by reference, and can be used to provide
# return values outside the pipeline
function doprint
{
process { write-output "value now: $psitem" }
}
function recurse($thing, $rtx)
{
$thing++
if($thing -lt 20) {
if($thing -eq 15) { $rtx[0] = $thing }
write-output $thing | doprint
recurse $thing $rtx
}
}
j=0
$rtv=@(4)
recurse $j $rtv
write-output $rtv[0]
Worth mentioning:
Any unmanaged command output inside your function will end up as a return value.
I use to get this trouble with a function managing XML content:
Function Add-Node(NodeName){
$NewXmlNode = $Xml.createElement("Item")
$Xml.Items.appendChild($NewXmlNode) | out-null
}
If you remove the Out-Null, the return of your function will be the Node basic properties... (You can also manage the exit code of the appendChild command ... it depends on the motivation) :)
@Michael Sorens's answer is useful, but it suggests a design strategy that seems rather onerous. I don't want to have to separate out data processing functions from functions that report progress or diagnostic messages. Reading his blogpost, I found a less hacky work-around to the OP's question. Here's the key sentence from the blog post:
A PowerShell function returns all uncaptured output.
So what if we capture our output?
function Calculate
{
$junkOutput = echo "Calculate"
return 11
}
$result = Calculate
Now $result
just contains 11, as intended.