13

I am learning PowerShell recently, and found a behavior that I cannot understand. Let me explain in code below:

function func1()
{
    Write-Output "output from func1()"
    func2
    return $true
}

function func2()
{
    Write-Output "output from func2()"
    func3
}

function func3()
{
    Write-Output "output from func3()"
}

Write-Output "*** 1. run alone ****"
func1

Write-Output "*** 2. run inside if ****"
if (func1) {
    #do nothing
}

It is strange when func1 is called directly, it can output message as expected, but if put inside "if" statement, it will not. See output as below:

*** 1. run alone ****
output from func1()
output from func2()
output from func3()
True
*** 2. run inside if ****

You can see it's empty. Why is that, and how can I enable the output like the first example? Thanks!

3 Answers 3

14

PowerShell functions are not like their traditional language counterparts: they can output multiple things. When you're using Write-Output, you are sending things down the pipeline, so func1() will return both a String and a Boolean. If you try this:

$return_values = func1;
$return_values | Get-Member

You will see that you get both System.String and System.Boolean objects in $return_values. Indeed the 'return' statement is more like an 'exit' or 'break' in traditional languages: it marks an exit point, but the function will actually return with whatever was already outputted (+ the optional return argument).

The quick fix to the issue is to change Write-Output to Write-Host, though they do slightly different things.

Sign up to request clarification or add additional context in comments.

Comments

7

You can achieve desired results by replacing Write-Output with Write-Host. This is suitable only if your main concern is to produce output in the console as Write-Host does not go to stdout stream.

You can read more about difference between the 2 cmdlets in this SO thread :Which should I use: "Write-Host", "Write-Output", or "[console]::WriteLine"?

Comments

0

using this inline c# code can solve the problem

Add-Type -Language CSharp @"
using System; 
namespace Test 
{
public static class Write 
{ 
    public static void StdOut() 
    {
        Console.WriteLine("hello world");
    }
}
}
"@;

function func1()
{
# Write-Output "output from func1()"
[Test.Write]::StdOut()
return $true
}

Write-Output "*** 1. run alone ****"
func1

Write-Output "*** 2. run inside if ****"
if (func1) {

}

# checking for func1 members - there are Boolean only value returned
$return_values = func1;
$return_values | Get-Member

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.