Powershell: I/O Redirection to variables

Created on 17 Mar 2017  路  8Comments  路  Source: PowerShell/PowerShell

I/O Redirection to variables works differently in different (but similar) cases
sometimes it clone output to variable and console (current host)
call scheme: $o = SomeCode *>&1

Steps to reproduce

 C:\> $sb = {
>>> $DebugPreference = $InformationPreference = $VerbosePreference = 'continue'
>>> Write-Output 'output'
>>> Write-Host 'host'
>>> Write-Verbose 'verbose'
>>> Write-Warning 'warn'
>>> Write-Debug 'debug'
>>> Write-Information 'info'
>>> Write-Error 'error'
>>> }
 C:\> #local
 C:\> $o = Invoke-Command -ScriptBlock $sb *>&1
 C:\> $o
output
host
VERBOSE: verbose
WARNING: warn
DEBUG: debug
info
 C:\> #remote
 C:\> $o = Invoke-Command -ScriptBlock $sb -ComputerName remote-server *>&1
host
VERBOSE: verbose
WARNING: warn
DEBUG: debug
info
 C:\> $o
output
host
info
error
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
    + PSComputerName        : wsus-serv

 C:\> #job
 C:\> Start-Job -ScriptBlock $sb

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
13     Job13           BackgroundJob   Running       True            localhost            ...


 C:\> $o = Receive-Job 13 *>&1
host
VERBOSE: verbose
WARNING: warn
DEBUG: debug
info
 C:\> $o
output
host
info
error
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
    + PSComputerName        : localhost

Expected behavior

C:\># in each cases
C:\> $o = SomeCode *>&1
C:\> $o
output
host
VERBOSE: verbose
WARNING: warn
DEBUG: debug
info
error
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
    + PSComputerName        : localhost

Actual behavior

local redirection doesn't redirect error stream (but redirection to file works ok)
remote - verbose, warning, debug streams not redirected; host, verbose, warning, debug, info leaked to console
job - verbose, warning, debug streams not redirected; host, verbose, warning, debug, info leaked to console

Environment data

 C:\> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.1.14409.1005
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14409.1005
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Name                           Value
----                           -----
PSVersion                      6.0.0-alpha
PSEdition                      Core
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   3.0.0.0
GitCommitId                    v6.0.0-alpha.17
CLRVersion
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
Issue-Question Resolution-By Design

Most helpful comment

Take a look at InvokeCommandCommand.cs, WriteStreamObjectsFromCollection() method (https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/remoting/commands/InvokeCommandCommand.cs#L1842). This shows how stream objects from the remoting layer are written. Verbose, Warning, Progress, Debug, Host data streams are written through remote host method callbacks by default which bypasses redirection directives. I believe these callbacks will have to be updated to support redirection. There is another possible option using information PSStreamObjectType types which were added to support these data streams over remoting when no host is provided.

All 8 comments

@MVKozlov Thanks for your contribution!

@PaulHigin Could you clarify is the behavior by design or we should fix anything?

This is by design, but I am not sure what the reasoning was when the design decisions were made, and I agree it is confusing.

@PaulHigin Thanks for comments!

@PowerShellTeam Can anyone make deeper explanations that we can document it or make improvements?

I understand that some design considerations have place and some streams must be on the screen but at least let it be captured just like informational stream

Take a look at InvokeCommandCommand.cs, WriteStreamObjectsFromCollection() method (https://github.com/PowerShell/PowerShell/blob/master/src/System.Management.Automation/engine/remoting/commands/InvokeCommandCommand.cs#L1842). This shows how stream objects from the remoting layer are written. Verbose, Warning, Progress, Debug, Host data streams are written through remote host method callbacks by default which bypasses redirection directives. I believe these callbacks will have to be updated to support redirection. There is another possible option using information PSStreamObjectType types which were added to support these data streams over remoting when no host is provided.

So, it's closed because Won'tFix or we have a chance ?

I believe it should be RFC to discuss in depth and re-design. https://github.com/PowerShell/PowerShell-RFC

Was this page helpful?
0 / 5 - 0 ratings