You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Start-Process should support redirecting to variable names or stream objects #5184
Because there are many executables (mostly of linux origin) which use stderr to write status messages (in addition to errors), and rely purely on exit code to indicate whether there actually is an error or not ....
As a PowerShell scripter, I need to be able to run an executable and both stream the output for sake of status updates and capture the (stderr) output so I can report on it properly if there is an actual error.
Start-Process doesn't support this -- it only captures to file, and if it does, it doesn't output. Additionally, since output stream redirection is limited to redirecting to stdout or file, I cannot redirect error to verbose on CLI apps that consistently behave this way...
My current company has contrived more than one complicated wrapper around ProcessStartInfo and Diagnostics.Process to handle the output events and so on. In fact, it seems that every company I work with above a certain level of PowerShell maturity has their own custom Invoke-Process or other replacement for Start-Process to try and handle this.
Start-Process should allow capturing and also outputting
Start-Process should allow capturing (and reading input from) variables instead of just files
Personally, I think we should not enhance start-process and instead provide ways to solve interacting with processes natively. It seems that if we make the Variable: provider work like a file, this should solve some of your problems?
somecommand 2> variable:stderr 1> variable:stdout
Tee-Object doesn't work with redirection, so need to think how to redirect while still outputting...
We should also allow redirecting one stream to another stream beyond stdout like:
Steve Lee (@SteveL-MSFT) For long running commands, this would make it look like powershell has hung.
I think we need a layered approach where the lowest level converts output and errors to a tagged union of output * string and error * string. On top of that it is quite easy to layer redirection to different streams, or to capture in variables.
It also opens a path to handling more complex commands where there is mixed progress and verbose output in the different streams, and makes it quite easy to make a parser that interprets the output and direct it do the appropriate powershell stream.
Something similar would make it easy to use from the PowerShell side.
foreach($poin ProcessEx.Run(...)){
if ($po.IsOutput){
# parse output and split into Output and Progress
}
else {
# parse error and split into for example Verbose, Warning and Error
}
}
Start-Process is of limited usefulness particularly on Unix, so I think Steve Lee (@SteveL-MSFT)'s suggestion of using direct invocation with enhanced redirections is the more promising idea to pursue, especially if you're interested in showing ongoing output as well as capturing, which only makes sense with synchronous execution (at least on Unix, where running in a new terminal window is not an option).
If we had the ability to capture in a variable while optionally also passing output through, then I think no lower-level approach is needed.
It's too bad this relatively simple request got set aside for a more elegant but unachievable better idea ...
Given it's been 6 years, do you think we could just do the original request?
@PowerShell/wg-powershell-cmdlets discussed this, since stderr gets wrapped as an ErrorRecord, we propose a small change in Tee-Object to have a new -ErrorRecordVariable that stores streamed input that is of type [System.Management.Automation.ErrorRecord] and store it to that variable. Existing behavior to write to the host would continue. So an example usage would look like:
ls *foo* README.txt 2>&1|Tee-Object-Variable stdout_variable -ErrorRecordVariable stderr_variable -ErrorVariable teeObjectErrors
We would enhance Tee-Object docs to show how to use this.
Activity
SteveL-MSFT commentedon Oct 21, 2017
Personally, I think we should not enhance
start-processand instead provide ways to solve interacting with processes natively. It seems that if we make the Variable: provider work like a file, this should solve some of your problems?Tee-Objectdoesn't work with redirection, so need to think how to redirect while still outputting...We should also allow redirecting one stream to another stream beyond stdout like:
powercode commentedon Oct 24, 2017
Steve Lee (@SteveL-MSFT) For long running commands, this would make it look like powershell has hung.
I think we need a layered approach where the lowest level converts output and errors to a tagged union of
output * stringanderror * string. On top of that it is quite easy to layer redirection to different streams, or to capture in variables.It also opens a path to handling more complex commands where there is mixed progress and verbose output in the different streams, and makes it quite easy to make a parser that interprets the output and direct it do the appropriate powershell stream.
powercode commentedon Oct 24, 2017
Something similar would make it easy to use from the PowerShell side.
mklement0 commentedon Nov 12, 2017
Start-Processis of limited usefulness particularly on Unix, so I think Steve Lee (@SteveL-MSFT)'s suggestion of using direct invocation with enhanced redirections is the more promising idea to pursue, especially if you're interested in showing ongoing output as well as capturing, which only makes sense with synchronous execution (at least on Unix, where running in a new terminal window is not an option).If we had the ability to capture in a variable while optionally also passing output through, then I think no lower-level approach is needed.
I had previously suggested syntax
>&targetVarName, but I like the idea of using namespace notation (> variable:targetVarName)However, additional syntax is needed for:
optional pass-through-as-well behavior, as suggested by Steve Lee (@SteveL-MSFT) (
>|?)optional append-to-preexisting-variable-contents behavior (a
+prefix might do, as with-OutVariablefor instance).These two behaviors would bring the redirection operators on par with the
-OutVariableand-ErrorVariablecommon parameters.mklement0 commentedon Nov 12, 2017
P.S: Asking for the ability to capture stderr lines in a variable is the subject of #4332
Jaykul commentedon Nov 17, 2023
It's too bad this relatively simple request got set aside for a more elegant but unachievable better idea ...
Given it's been 6 years, do you think we could just do the original request?
SteveL-MSFT commentedon Apr 29, 2024
I've queued this up for WG to discuss
SteveL-MSFT commentedon May 1, 2024
@PowerShell/wg-powershell-cmdlets discussed this, since stderr gets wrapped as an
ErrorRecord, we propose a small change inTee-Objectto have a new-ErrorRecordVariablethat stores streamed input that is of type[System.Management.Automation.ErrorRecord]and store it to that variable. Existing behavior to write to the host would continue. So an example usage would look like:We would enhance
Tee-Objectdocs to show how to use this.Address an aspect of issue PowerShell#5184.