2

It seems that PowerShell adds an additional variable to the return value of a function.

The function subfoo2 itself delivers the correct values, but as soon as PowerShell jumps back to the postion where I called the function (in foo1), value contains the value of an other variable ($msg)

(Have a look at the comments in the code)

writeMessageLog($msg){
   ...
   Add-Content $msg
   ...
}
   subfoo2{
   writeMessageLog($msg)
   return $UserArrayWithValues #During Debug, $Array is fine (1)
}
   foo1{
   $var = subfoo2 $UserArray # $var has now the value of $msg and $UserArrayWithValues (2)
   #do something with var
}

Realcode:

function WriteLog 
{
param ( [string] $severity , $msgNumber, [string] $msg )
...

        $msgOut = $date + ... + $msg 
        Add-Content $msgout ( $msgOut )
...
}

function getFeatures
{
    writelog 'I'  1002  $true $true "Load Features"
    $Features = importCsv -pPath $FeatureDefintionFilePath 
    Writelog 'I'  1000  $true $true "Features Loaded"
    return $Features # $Features has value as expected (1)
}


function GetUserFeatures ($pUserObject)
{

    $SfBFeatures = ""
    $SfBFeatures = getFeatures #SfBFeaures has Value of $msg and $Features (2)
...
}

Do I use the functions/return values wrong? What could lead to such behavior? Is it an issue if i call a function within a function?

If I remove $msgOut = $date + ... + $msg in writeMessageLog, the values are fine.

I'm pretty lost right now, and have no ideas where this comes from. Any ideas welcome.

Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
cwa
  • 69
  • 6

2 Answers2

3

This is how powershell works, basically everything that you print out will be returned as the function output. So don't output extra stuff. To force something to not output stuff you can do:

$null = some-command_that_outputs_unwanted_things

since everybody is obsessed with Out-Null I'll add this link showing several other ways to do that.

4c74356b41
  • 69,186
  • 6
  • 100
  • 141
  • Ah I see... I assume it's the same issue as here: [link](http://stackoverflow.com/questions/39312207/powershell-returns-wrong-result) But i wasn't aware that Powershell will return "all of the return" values... Your solution works perfectly... thank you so much. Solution: $null = writelog 'I' 1002 $true $true "Load Features" Appreciate your quick answer – cwa Mar 02 '17 at 10:53
2

Within a function, everything you don't assign or pipe to a consuming cmdlet will get put to the pipeline and returned from the function - even if you don't explicit return it. In fact the return keyword doesn't do anything in PowerShell so the following is equivalent:

function Test-Func
{
   "Hello World"
}

function Test-Func
{
   return "Hello World"
}

So it looks like your writeMessageLog puts anything on the pipeline thus you have to either assign the value to anything:

$notUsed = writeMessageLog($msg)

or (prefered) pipe it to the Out-Null cmdlet:

writeMessageLog($msg) | Out-Null
Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
  • pipe to out-null isn't a preferred way to do that. http://stackoverflow.com/questions/5260125/whats-the-better-cleaner-way-to-ignore-output-in-powershell – 4c74356b41 Mar 02 '17 at 10:56
  • @4c74356b41 IMHO its the most readable way to do it and it uses a cmdlet which is ment for that. – Martin Brandl Mar 02 '17 at 11:00
  • 1
    @4c74356b41 even though there may be methods that give you better performance, I don't think you can deduce from that that `pipe to out-null isn't a preferred way to do that`. Presumably the cmdlet exists for a reason. – arco444 Mar 02 '17 at 11:01
  • I don't see any reason to use `| Out-null` when `> $null` is strictly faster and equally readable – 4c74356b41 Mar 02 '17 at 11:02
  • Thanks for clarification. I will have a look at both ways. I guess the best way to avoid such issues, is to use a proper "pipeable" function/cmdlet (e.g. for getFeatures) . This should avoid the use of the return Statement... But I have to think about that in detail. – cwa Mar 02 '17 at 11:10