Best way to return values from a function that writes to STDOUT
another approach:
- in your function, do logging via Write-Information.
- in the calling scope, call the function inside a sub-expression and redirect the information stream of the sub-expression to stdout. Be sure to assign the return value of the function to a variable, or it will also go to stdout.
eg
function bar() {
Write-Information "Hello from bar()"
return 4
}
$($x = bar) 6>&1
Write-Output "in main `$x = $x"
If you're on an old version of powershell and can't use Write-Information
the same approach works with Write-Verbose
. In that case you'd redirect as 4>&1
. With verbose you'll get the ugly yellow/black and "VERBOSE" text, unless you're redirecting the stdout of the overall script into a file, in which case the VERBOSE: tag will be omitted.
In PowerShell all non-captured output inside a function is returned, not just the argument of return
. From the documentation:
In PowerShell, the results of each statement are returned as output, even without a statement that contains the
return
keyword.
It doesn't matter if the function looks like this:
function Foo {
'foo'
}
or like this:
function Foo {
'foo'
return
}
or like this:
function Foo {
return 'foo'
}
it will return the string foo
either way.
To prevent output from being returned, you can
write to the host or one of the other ouptput streams (depending on the type of output you want to create):
Function a { Write-Host 'some text' Write-Verbose 'verbose message' Write-Information 'info message' # requires PowerShell v5 or newer $a = 4 return $a }
Side note:
Write-Information
is not available prior to PowerShell v5 when the information stream was introduced, and starting with that versionWrite-Host
also writes to that stream rather than directly to the host console.capture the output in a variable or "assign" it to
$null
:Function a { $var = Write-Output 'some text' $null = Write-Output 'some text' $a = 4 return $a }
or redirect the output to
$null
:Function a { Write-Output 'some text' | Out-Null Write-Output 'some text' >$null $a = 4 return $a }