Search code examples
powershellreturn-valuestdout

How do I avoid getting data printed to stdout in my return value?


In doing some Powershell automation, I'm having trouble with the way that data written to stdout by a .cmd file is automatically captured. I have two functions that do something like the following:

function a {
    & external.cmd # prints "foo"
    return "bar"
}

function b {
    $val = a
    echo $val # prints "foobar", rather than just "bar"
}

Basically, data that external.cmd sends to stdout is added to the return value of a, even though all I really want to return from a is the string that I specified. How can I prevent this?


Solution

  • Here are a few different approaches for handling this:

    • capture the output of the .cmd script:

        $output = & external.cmd # saves foo to $output so it isn't returned from the function
      
    • redirect the output to null (throw it away)

        & external.cmd | Out-Null # throws stdout away
      
    • redirect it to a file

        & external.cmd | Out-File filename.txt
      
    • ignore it in the caller by skipping it in the array of objects that's returned from the function

        $val = a
        echo $val[1] #prints second object returned from function a (foo is object 1... $val[0])
      

    In PowerShell, any output value your code does not capture, is returning the "caller" object (including stdout, stderr, etc). So you have to capture or pipe it to something that doesn't return a value, or you'll end up with the object[] itself as your return value from the function.

    The return keyword is really just for clarity, with the exact same effect as just writing the variable alone (as shown), but with an immediate exit of a script block in PowerShell. Something like this would even work (not verbatim but just to give you the idea):

    function foo()
    {
        "a"
        "b"
        "c"
    }
    
    PS> $bar = foo
    PS> $bar.gettype()
    System.Object[]
    PS> $bar
    a
    b
    c
    
    function foobar()
    {
        "a"
        return "b"
        "c"
    }
    
    PS> $myVar = foobar
    PS> $myVar
    a
    b