Suppose I have the following function:
function Foo {
Write-Information 'Info'
Write-Warning 'Warning'
Write-Verbose 'Verbose'
Write-Error 'Error'
return 'Return'
}
If I assign its output to a variable $a, all streams but the success stream get implicitly written to the terminal (assuming $[Stream]Preference = 'Continue'), while the success stream gets written to $a:
PS1> $a = Foo
Info
WARNING: Warning
VERBOSE: Verbose
Foo : Error
At line:1 char:6
+ $a = Foo
+ ~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Foo
PS1> $a
Return
Running ($a = Foo) yields the same result, except that Return from the success stream also gets dumped to the terminal because of the expression evaluation caused by the parentheses. $a still gets the value Return.
If I redirect all streams to a file, $a still gets the value Return assigned and all streams are redirected as expected:
PS1> ($a = Foo) *>output.txt
PS1> $a
Return
PS1> gc output.txt
Info
Warning
Verbose
Foo : Error
At line:1 char:7
+ ($a = Foo) *>output.txt
+ ~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Foo
Return
But if I redirect all streams to the success stream instead, suddenly $a gets assigned the content of all streams:
PS1> ($a = Foo) *>&1
Info
WARNING: Warning
VERBOSE: Verbose
Foo : Error
At line:1 char:7
+ ($a = Foo) *>&1
+ ~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Foo
Return
PS1> # So far so good
PS1> $a
Info
WARNING: Warning
VERBOSE: Verbose
Foo : Error
At line:1 char:7
+ ($a = Foo) *>&1
+ ~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Foo
Return
PS1> # ???
How can this behavior be explained? Especially the discrepancy between redirecting to file and redirecting to the success stream. I can understand that $a = Foo *>&1 leads to $a containing everything, but would expect the parentheses to cause the expression to be evaluated before redirecting the streams. Or am I missing something here and the redirection applies before any evaluation? But then $a should be $null when redirecting to file, should it not?