Streams
When running from bash all 6 streams can get merged to STDOUT
STDERR (apparently can go to STDERR sometimes)
PowerShell Streams Reference
Overview
PowerShell has 7 streams: 1 input stream and 6 output streams. This allows fine-grained control over different types of output.
The Streams
| Stream | Number | Cmdlet | Purpose |
|---|---|---|---|
| stdin | - | Read-Host, pipeline | Input to commands |
| Success | 1 | Write-Output | Normal output (stdout) |
| Error | 2 | Write-Error | Error messages (stderr) |
| Warning | 3 | Write-Warning | Warning messages |
| Verbose | 4 | Write-Verbose | Detailed information |
| Debug | 5 | Write-Debug | Debug information |
| Information | 6 | Write-Host, Write-Information | User messages |
Writing to Streams
# Success (default, goes to pipeline)
Write-Output "Normal output"
"This too" # Implicit Write-Output
# Error
Write-Error "Something failed"
# Warning
Write-Warning "Proceed with caution"
# Verbose (must enable with -Verbose or preference)
Write-Verbose "Detailed info" -Verbose
# Debug (must enable with -Debug or preference)
Write-Debug "Debug info" -Debug
# Information (displayed to user, not piped by default)
Write-Host "Hello user"
Write-Information "Info message" -InformationAction Continue
Redirecting Streams
Basic Redirection
# Redirect to file
command 1> output.txt # Success to file
command 2> errors.txt # Errors to file
command 3> warnings.txt # Warnings to file
# Suppress streams
command 2>$null # Discard errors
command 3>$null # Discard warnings
# Redirect all streams
command *> everything.txt
Merging Streams
# Merge error into success (stderr → stdout)
command 2>&1
# Merge warning into error (warning → stderr)
command 3>&2
# Merge all into success
command *>&1
Multiple Redirections
# Separate outputs
Get-Process 1> output.txt 2> errors.txt 3> warnings.txt
# Clean output: suppress errors and warnings
Get-Process 2>$null 3>$null
# Send warnings to stderr, keep stdout clean
command 3>&2 > output.txt
Controlling Stream Behavior
Preference Variables
$ErrorActionPreference = "Stop" # Treat errors as terminating
$WarningPreference = "SilentlyContinue" # Hide warnings
$VerbosePreference = "Continue" # Show verbose messages
$DebugPreference = "Continue" # Show debug messages
$InformationPreference = "Continue" # Show information messages
Per-Command Parameters
Get-Process -ErrorAction Stop
Get-Process -WarningAction SilentlyContinue
Get-Process -Verbose
Get-Process -Debug
Get-Process -InformationAction Continue
Common Patterns
Suppress Warnings
# Using parameter
ConvertTo-Json -WarningAction SilentlyContinue
# Using redirection
ConvertTo-Json 3>$null
Capture All Output
# Capture success and error
$result = command 2>&1
# Capture everything
$all = command *>&1
Clean Pipeline Output
# Only success goes through pipeline
Get-Process 2>$null 3>$null | Where-Object {$_.CPU -gt 10}
# Errors and warnings to stderr, data to stdout
Get-Process 2>&2 3>&2 | ConvertTo-Json
Separate Good and Bad Output
# Save output and errors separately
Get-ChildItem -Recurse 1> files.txt 2> access_errors.txt
Practical Examples
Example 1: Clean JSON Output
# Problem: Warnings pollute output
Get-Process | ConvertTo-Json -Depth 1 | jq
# Solution: Redirect warnings to stderr
Get-Process | ConvertTo-Json -Depth 1 3>&2 | jq
# Or suppress warnings
Get-Process | ConvertTo-Json -Depth 1 -WarningAction SilentlyContinue | jq
Example 2: Debugging Function
function Process-Data {
param($Data)
Write-Verbose "Starting processing..." -Verbose
Write-Debug "Data: $Data" -Debug
if ($Data -eq $null) {
Write-Error "Data is null"
return
}
Write-Warning "This might take a while"
Write-Output "Result: $Data"
}
# Run with all streams visible
Process-Data "test" -Verbose -Debug
# Run with clean output
Process-Data "test" 3>$null 4>$null 5>$null
Example 3: From Bash
# Redirect PowerShell streams in bash
pwsh -c 'Get-Process | ConvertTo-Json 3>&2' > output.json 2> warnings.txt
# Suppress warnings in bash
pwsh -c 'Get-Process | ConvertTo-Json 3>$null' > output.json
Key Differences from Bash
| Feature | Bash | PowerShell |
|---|---|---|
| Total streams | 3 (stdin, stdout, stderr) | 7 (stdin + 6 output) |
| Stream numbers | 0, 1, 2 | 1-6 (plus stdin) |
| Granularity | Basic | Fine-grained |
| Warning stream | No (uses stderr) | Yes (separate) |
| Verbose/Debug | No (manual) | Yes (built-in) |
Quick Reference
# Redirecting
command 1> file # stdout to file
command 2> file # stderr to file
command 3> file # warnings to file
command *> file # all to file
# Merging
command 2>&1 # stderr → stdout
command 3>&2 # warning → stderr
command *>&1 # all → stdout
# Suppressing
command 2>$null # discard errors
command 3>$null # discard warnings
command *>$null # discard all
# Parameters
-ErrorAction SilentlyContinue
-WarningAction SilentlyContinue
-Verbose
-Debug
Best Practices
- Use
Write-Outputfor data that goes through the pipeline - Use
Write-Hostfor user messages that shouldn't be piped - Use
Write-Errorfor errors, notthrow(unless terminating) - Use
Write-Warningfor non-critical issues - Use
Write-Verbosefor detailed logging (enable with-Verbose) - Use
Write-Debugfor troubleshooting (enable with-Debug) - Redirect streams (3>&2) rather than suppressing when you need logs
- Suppress streams (3>$null) when you want clean output
Backlinks