diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index 10c4dda1e5c..b511054a051 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -1594,15 +1594,19 @@ private void CalculateIORedirection(bool isWindowsApplication, out bool redirect // $powershell.AddScript('ipconfig.exe') // $powershell.AddCommand('Out-Default') // $powershell.Invoke()) - // we should not count it as a redirection. - if (IsDownstreamOutDefault(this.commandRuntime.OutputPipe)) + // we should not count it as a redirection. Unless the native command has its stdout redirected + // for example: + // cmd.exe /c "echo test" > somefile.log + // in that case we want to keep output redirection even though Out-Default is the only + // downstream command. + if (IsDownstreamOutDefault(this.commandRuntime.OutputPipe) && StdOutDestination is null) { redirectOutput = false; } } // See if the error output stream has been redirected, either through an explicit 2> foo.txt or - // my merging error into output through 2>&1. + // by merging error into output through 2>&1. if (CommandRuntime.ErrorMergeTo != MshCommandRuntime.MergeDataStream.Output) { // If the error output pipe is the default outputter, for example, calling the native command from command-line host, @@ -1612,7 +1616,9 @@ private void CalculateIORedirection(bool isWindowsApplication, out bool redirect // $powershell.AddScript('ipconfig.exe') // $powershell.AddCommand('Out-Default') // $powershell.Invoke()) - // we should not count that as a redirection. + // we should not count that as a redirection. We do not need to worry + // about StdOutDestination here as if error is redirected then it's assumed + // to be text based and Out-File will be added to the pipeline instead. if (IsDownstreamOutDefault(this.commandRuntime.ErrorOutputPipe)) { redirectError = false; diff --git a/test/powershell/engine/Basic/NativeCommandBytePiping.Tests.ps1 b/test/powershell/engine/Basic/NativeCommandBytePiping.Tests.ps1 index 8126c08473f..1e645df9030 100644 --- a/test/powershell/engine/Basic/NativeCommandBytePiping.Tests.ps1 +++ b/test/powershell/engine/Basic/NativeCommandBytePiping.Tests.ps1 @@ -63,4 +63,18 @@ Describe 'Native command byte piping tests' -Tags 'CI' { ($pipe)?.Dispose() } } + + It 'Bytes are retained when redirecting to a file' { + testexe -writebytes FF > $TestDrive/content.bin | Should -BeNullOrEmpty + Get-Content -LiteralPath $TestDrive/content.bin -AsByteStream | Should -Be 0xFFuy + } + + It 'Bytes are retained when redirecting to a file and Out-Default is downstream' { + testexe -writebytes FF > $TestDrive/content2.bin | Out-Default + Get-Content -LiteralPath $TestDrive/content2.bin -AsByteStream | Should -Be 0xFFuy + } + + It 'Redirecting to $null should emit no output' { + testexe -writebytes FF > $null | Should -BeNullOrEmpty + } }