powershell 2.0 redirection file handle exception powershell 2.0 redirection file handle exception powershell powershell

powershell 2.0 redirection file handle exception


If you do this in foo.ps1 it solves the problem:

# <fix>$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"$objectRef = $host.GetType().GetField( "externalHostRef", $bindingFlags ).GetValue( $host )$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetProperty"$consoleHost = $objectRef.GetType().GetProperty( "Value", $bindingFlags ).GetValue(     $objectRef, @() )[void] $consoleHost.GetType().GetProperty( "IsStandardOutputRedirected", $bindingFlags).GetValue( $consoleHost, @() )$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"$field = $consoleHost.GetType().GetField( "standardOutputWriter", $bindingFlags )$field.SetValue( $consoleHost, [Console]::Out )$field2 = $consoleHost.GetType().GetField( "standardErrorWriter", $bindingFlags )$field2.SetValue( $consoleHost, [Console]::Out )# </fix>write-host "normal"write-error "error"write-host "yay"powershell .\bar.ps1 2>&1 | more

Piping the output through more hides the fact that it is ultimately going to a file from the child instance of Powershell, bypassing the bug.

In fact, if you create a grandparent script foobar.ps1 which just runs foo.ps1:

powershell .\foo.ps1 2>&1 | more

Then you don't need "the fix" at all, and foo.ps1 can just be

write-host "normal"write-error "error"write-host "yay".\bar.ps1

because the piping solves the problem for all descendent scripts.