How to Output value from function to caller but not to console
Asked Answered
A

1

6

Say I have this simple PowerShell function:

function testit() {
    return $true > $null
}

Write-Host "testing"
$thistest = testit 
Write-Host "value = $thistest"

When I use it in my PowerShell script, I want to receive the value in the script but I don't want it to show in the console.

How do I keep the return value in the pipeline but just hide it from console?

If I use the > $null then it suppresses the output completely - I just want it to not show in the console, but I still want the value.

Amey answered 4/1, 2017 at 23:56 Comment(3)
What is wrong with return $true or just $true?Arvie
I don't understand what you're asking; it doesn't show in the console normally. function test { $true }; $x = test has no on-screen output, and it keeps the return value in $xKymric
it does if you call the function. What I don't want is return $true to show True in the console.Amey
D
9

As documented PowerShell functions return all non-captured output to the caller. If the caller doesn't do anything with the returned value PowerShell automatically passes it to Out-Default, which then forwards it to Out-Host (see this article written by Don Jones).

Using redirection operators on the return value inside the function effectively suppresses the return value so that the function wouldn't return anything.

If you have a function like this:

function testit {
    return $true
}

and call it by itself:

testit

PowerShell implicitly does this:

testit | Out-Default

which effectively becomes

testit | Out-Host

If you capture the return value in a variable

$thistest = testit

the value gets stored in the variable without anything being displayed on the console.

If you redirect the output or pipe it into Out-Null

testit >$null
testit | Out-Null

the return value is discarded and nothing is displayed on the console.

If you want to prevent PowerShell's default behavior of passing uncaptured output at the end of a pipeline to Out-Host you can do so by overriding Out-Default like this:

filter Out-Default { $_ | Out-Null }

or (as @PetSerAl pointed out in the comments) like this:

filter Out-Default {}

However, beware that this modification disables Out-Default for everything in the current scope until you remove the filter again. If you do for instance a Get-ChildItem while the filter is active nothing will be displayed unless you explicitly write the output to the host console:

Get-ChildItem | Out-Host

You remove the filter like this:

Remove-Item function:Out-Default
Drees answered 5/1, 2017 at 1:57 Comment(4)
What a wonderful answer! Just what I needed and wanted. Thank you.Amey
Why do you pipe $_ to Out-Null instead of doing nothing (function Out-Default { })?Arvie
@PetSerAl Because I failed to realize that would work too. Thanks for pointing it out, I updated my answer.Drees
So, there's no way to make it return a value to the caller, but not to the console except by calling it from another function?Amey

© 2022 - 2024 — McMap. All rights reserved.