1

I have a script that returns data through the stdout stream (simply by doing Write-Output at the end of the script).

Sadly, I have many Write-Verbose and Write-Warning along the code, and I want them to write data to the stderr stream, in order to not get tangled with my output.

I found that Write-Warning, for example, actually calling $host.UI.WriteWarningLine under the hood, but it's writing directly to stdout without a way to change it.

Any ideas?

iTayb
  • 12,373
  • 24
  • 81
  • 135
  • How do you call/invoke the script in the first place? As long as you're calling it from within PowerShell, the verbose and warning streams will be separate from stdout – Mathias R. Jessen Feb 02 '16 at 14:29
  • @MathiasR.Jessen `powershell.exe -FilePath c:\script.ps1 2> NUL` – iTayb Feb 02 '16 at 14:30
  • @MathiasR.Jessen That's the thing, I'm using the `stdout` stream outside of the powershell scope. – iTayb Feb 02 '16 at 14:32
  • Perhaps, you could try to make proxy functions for `Write-Verbose` and `Write-Warning` using this approach: [How do I write to standard error in PowerShell?](http://stackoverflow.com/a/15669365/4424236). – beatcracker Feb 02 '16 at 14:59

2 Answers2

2

If you can modify the original script a little, and then run a wrapper script you should be able to do something like this (if you can't then this answer is entirely pointless ;) )

[CmdletBinding()]
Param()
Write-Error "error"
Write-Warning "warning"
Write-Output "output" 
Write-Verbose "verbose" 

and then call the script with a wrapper like this (modifed with @beatcracker's comment link)

.\test1.ps1 -ErrorAction Continue -WarningVariable warn1 `
            -WarningAction SilentlyContinue  `
            -InformationVariable inf `
            -InformationAction SilentlyContinue 

$warn1 | foreach { $host.ui.WriteErrorLine($_)  } 

By adding [CmdletBinding()] to the top of the original script you can call it with the Powershell CommonParameters, including WarningVariable and WarningAction

In this particular script ErrorAction was required to make sure it didn't halt on the write-error message. It obviously wouldn't be required to achieve what you seek.

By putting SilentlyContinue on WarningAction you will take the warning messages out of the stdout stream, by saving them in WarningVariable you can then do whatever you like with them at the end. In this case just looping through them and passing them to stderr

The same goes for the InformationAction and InformationVariable with regards to the verbose stream.

Community
  • 1
  • 1
Michael B
  • 11,887
  • 6
  • 38
  • 74
1

Outside PowerShell you have only STDOUT and STDERR. The error stream goes to STDERR, all other streams go to STDOUT. At that point you can't separate verbose or warning output from regular output anymore.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328