I have a small script, C:\so\test.ps1
, whose contents is:
Invoke-Expression 'using module .\notarealmodule.psm1'
This script intentionally references a non-existent module in order to throw an error.
When I run this script without redirection, I receive the expected output in $out
:
PS C:\so> $out = & "C:\Program Files\PowerShell\7\pwsh.exe" -File ".\test.ps1"
PS C:\so> $out
Invoke-Expression: C:\so\test.ps1:1
Line |
1 | Invoke-Expression 'using module .\notarealmodule.psm1'
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The specified module 'C:\so\notarealmodule.psm1' was not loaded because no valid module file was found in any
| module directory.
However, once I add redirection, the output is empty:
PS C:\so> $out = & "C:\Program Files\PowerShell\7\pwsh.exe" -File ".\test.ps1" 2>&1
PS C:\so> $out
PS C:\so> $out = & "C:\Program Files\PowerShell\7\pwsh.exe" -File ".\test.ps1" 1>$null
PS C:\so> $out
PS C:\so> $out = & "C:\Program Files\PowerShell\7\pwsh.exe" -File ".\test.ps1" 2>$null
PS C:\so> $out
What is going on here??
I was able to reproduce this issue with System.Diagnostics.Process
. Here is the contents of C:\so\testprocess.ps1
:
$proc = [System.Diagnostics.Process]::new()
$proc.StartInfo.FileName = "C:\Program Files\PowerShell\7\pwsh.exe"
$proc.StartInfo.Arguments = "-File $PSScriptRoot\test.ps1"
$proc.StartInfo.UseShellExecute = $false
$proc.StartInfo.RedirectStandardOutput = $true
$proc.StartInfo.RedirectStandardError = $true
$proc.StartInfo.CreateNoWindow = $true
[void]($proc.Start())
Write-Host ($proc.StandardOutput.ReadToEnd())
Write-Host ($proc.StandardError.ReadToEnd())
[void]($proc.WaitForExit())
Nothing is output when running this script.
PS C:\so> .\testprocess.ps1
PS C:\so>
This issue is not reproducible on PS 7.1.0:
PS C:\so> $out = & "C:\Program Files\PowerShell\7\pwsh.exe" -File ".\test.ps1" 2>&1
PS C:\so> $out
Invoke-Expression: C:\so\test.ps1:1
Line |
1 | Invoke-Expression 'using module .\notarealmodule.psm1'
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The specified module 'C:\so\notarealmodule.psm1' was not loaded because no valid module file was found in any
| module directory.
PS C:\so>.\testprocess.ps1
Invoke-Expression: C:\so\test.ps1:1
Line |
1 | Invoke-Expression 'using module .\notarealmodule.psm1'
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The specified module 'C:\so\notarealmodule.psm1' was not loaded because no valid module file was found in any
| module directory.
PS C:\so>
What kind of evil witchcraft is happening with PS 7.0.0 whereby the error message from Invoke-Expression
ends up in $out
when using &
with no redirection, but doesn't end up in the output from System.Diagnostics.Process
??? Is there a third stream (other than stdout/stderr) that only &
(with no redirection) knows about?