3

Is it posible to capture both output and verbose information into two different variables?

I am creating a GUI with powershell and WPF where it has a richtextbox which display only verbose and errors.

For example if I execute the following:

get-dscconfiguration -verbose

Then the verbose stream should go to richtextbox and output of that cmdlet should be asigned to a variable for further manuplation.

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Vinay R S
  • 33
  • 1
  • 4

3 Answers3

3

You can capture one stream to a variable or multiple streams to a variable but beyond that you will need to send to file and read back in or filter the variable that captured multiple streams. For example to capture only verbose output you can run the command as a subexpression.

$VerboseOnly = $($OutputOnly= .{
    New-Item -ItemType Directory -Path c:\Test -Verbose
    Remove-Item -Path c:\Test -Verbose
    Remove-Item -Path c:\Test -Verbose
    Write-Warning "warning"
}) 4>&1

When run this outputs the error and warning objects to console but the verbose objects are saved into $VerboseOnly and the output objects are saved into $OutputOnly.

You can redirect multiple streams as well as the following example shows:

$VerboseAndWarning = $(
$OutputOnly = .{
    New-Item -ItemType Directory -Path c:\Test -Verbose
    Remove-Item -Path c:\Test -Verbose
    Remove-Item -Path c:\Test -Verbose
    Write-Warning "warning"
}) 4>&13>&1

At this point only the error object was written to console, the output System.IO.DirectoryInfo object is in $outputOnly, and the warning and verbose messages are in $VerboseAndWarning. You can then pull them out by filtering with a where-object clause.

$VerboseAndWarning | Where-Object {$_ -is [System.Management.Automation.WarningRecord]}
WARNING: warning
$VerboseAndWarning | Where-Object {$_ -is [System.Management.Automation.VerboseRecord]}
VERBOSE: Performing operation "Create directory" on Target "Destination: C:\Test".
VERBOSE: Performing operation "Remove Directory" on Target "C:\Test".
StephenP
  • 3,895
  • 18
  • 18
0

Using Where-Object(The alias is symbol ?) is an obvious method, but it's a bit too cumbersome. It needs a lot of code.

In this way, it will not only take longer time, but also increase the probability of error.

In fact, there is a more concise method that separate different streams to different variable in PowerShell(it came to me by accident).

# First, declare a method that outputs both streams at the same time.
function thisFunc {
    [cmdletbinding()]
    param()
    Write-Output 'Output'
    Write-Verbose 'Verbose'
}
# The separation is done in a single statement.Our goal has been achieved.
$VerboseStream = (thisFunc -Verbose | Tee-Object -Variable 'String' | Out-Null) 4>&1

Then we verify the contents of these two variables

$VerboseStream.getType().FullName
$String.getType().FullName

The following information should appear on the console:

PS> System.Management.Automation.VerboseRecord
System.String

'4>&1' means to redirect the verboseStream to the success stream, which can then be saved to a variable, of course you can change this number to any number between 2 and 5.

If you feel and my method is not bad, please click the mouse to vote for me, thank you very much.

Andy
  • 1,077
  • 1
  • 8
  • 20
-1

https://stackoverflow.com/a/33002914

The above URL is an answer to another similar question that will most likely help you.

He feeds both the stdout and stderr and then splits them once complete. It's not done on the fly however.

You could simply have each one saved into its own variable.

Community
  • 1
  • 1
Random206
  • 757
  • 6
  • 19