PowerShell Input and Output
Input and output (I/O) control how a PowerShell script communicates with the outside world — receiving data from the user or files, and sending results to the screen, files, or other systems. Understanding the different output streams and input methods is essential for writing interactive and professional scripts.
Output Methods
PowerShell provides several cmdlets for sending output. Each one serves a different purpose and behaves differently in the pipeline.
Write-Host
Write-Host displays text directly to the console. It does not send output into the pipeline — it writes directly to the screen. Use it for user-facing messages and status updates.
Write-Host "Script is running..."
Write-Host "Complete!" -ForegroundColor Green
Write-Host "ERROR: File not found!" -ForegroundColor Red -BackgroundColor Black
Write-Host "Processing..." -NoNewline
Write-Host " Done"
Available colors: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White
Write-Output
Write-Output sends data into the pipeline. It is the correct way to return values from scripts and functions when the result needs further processing.
# Write-Output sends data to the pipeline
$result = Write-Output "Hello from pipeline"
Write-Host $result # Hello from pipeline
# In functions, use Write-Output to return values
function Get-Greeting {
param ($Name)
Write-Output "Hello, $Name"
}
$msg = Get-Greeting -Name "Deepa"
Write-Host $msg.ToUpper() # HELLO, DEEPA
Write-Host vs Write-Output
| Feature | Write-Host | Write-Output |
|---|---|---|
| Destination | Screen only | Pipeline / screen |
| Pipeline passthrough | No | Yes |
| Can be captured | No | Yes (assigned to variable) |
| Supports colors | Yes | No |
| Best for | User messages, status | Returning data from functions |
Write-Verbose
Write-Verbose displays detailed diagnostic messages. These are hidden by default and only show when -Verbose is passed or $VerbosePreference = "Continue" is set.
function Start-Backup {
[CmdletBinding()]
param ([string]$Path)
Write-Verbose "Starting backup for: $Path"
Write-Verbose "Checking if path exists..."
if (Test-Path $Path) {
Write-Verbose "Path confirmed."
Write-Host "Backup started."
} else {
Write-Host "Path not found: $Path"
}
}
# Run silently
Start-Backup -Path "C:\Data"
# Run with verbose output
Start-Backup -Path "C:\Data" -Verbose
Write-Warning
Write-Warning "Disk space is below 10%!"
# Output: WARNING: Disk space is below 10%!
Write-Error
Write-Error "Configuration file not found at C:\config.xml"
# Output: Write-Error: Configuration file not found at C:\config.xml
Write-Debug
$DebugPreference = "Continue" # Enable debug messages
function Calculate-Tax {
param ([decimal]$Amount)
Write-Debug "Input amount: $Amount"
$tax = $Amount * 0.18
Write-Debug "Calculated tax: $tax"
return $Amount + $tax
}
$total = Calculate-Tax -Amount 1000
Write-Host "Total with tax: $total"
PowerShell Output Streams
| Stream | Number | Cmdlet | Default Visibility |
|---|---|---|---|
| Success | 1 | Write-Output | Visible |
| Error | 2 | Write-Error | Visible |
| Warning | 3 | Write-Warning | Visible |
| Verbose | 4 | Write-Verbose | Hidden |
| Debug | 5 | Write-Debug | Hidden |
| Information | 6 | Write-Information | Hidden |
Redirecting Output Streams
# Redirect error stream to success stream
Get-ChildItem "C:\NonExistent" 2>&1
# Redirect all streams to a file
.\script.ps1 *> "C:\Logs\all_output.txt"
# Redirect only errors to a file
.\script.ps1 2> "C:\Logs\errors.txt"
# Suppress error output entirely
Get-ChildItem "C:\NonExistent" 2>$null
Reading Input from the User
Read-Host
Read-Host prompts the user to type input and waits for them to press Enter.
$username = Read-Host "Enter your username"
Write-Host "Welcome, $username!"
Output:
Enter your username: Arun
Welcome, Arun!
Read-Host with Secure String (Password Input)
$password = Read-Host "Enter password" -AsSecureString
Write-Host "Password captured (not shown for security)"
Input Validation with Read-Host
do {
$age = Read-Host "Enter your age (1-120)"
} until ($age -match "^\d+$" -and [int]$age -ge 1 -and [int]$age -le 120)
Write-Host "Valid age entered: $age"
Reading from Files
Get-Content – Read a Text File
# Read all lines from a file (returns array of strings)
$lines = Get-Content -Path "C:\Logs\app.log"
# Display each line
foreach ($line in $lines) {
Write-Host $line
}
# Read as one single string
$content = Get-Content -Path "C:\Logs\app.log" -Raw
Write-Host $content
# Read first 10 lines only
Get-Content -Path "C:\Logs\app.log" -TotalCount 10
# Read last 5 lines (tail)
Get-Content -Path "C:\Logs\app.log" -Tail 5
Real-time Log Monitoring with -Wait
# Continuously watch a log file as new lines are written
Get-Content -Path "C:\Logs\live.log" -Wait -Tail 5
Writing to Files
Out-File – Write Output to a File
# Create or overwrite a file
Get-Process | Out-File -FilePath "C:\Reports\processes.txt"
# Append to an existing file
Get-Date | Out-File -FilePath "C:\Logs\run_log.txt" -Append
# Specify encoding
Get-Service | Out-File -FilePath "C:\Reports\services.txt" -Encoding UTF8
Set-Content – Write Text to a File
# Write (overwrite) content to a file
Set-Content -Path "C:\Config\settings.txt" -Value "Environment=Production"
# Write multiple lines
$lines = @(
"ServerName=WebServer01",
"Port=443",
"Environment=Production"
)
Set-Content -Path "C:\Config\settings.txt" -Value $lines
Add-Content – Append to a File
# Append a new log entry
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path "C:\Logs\audit.log" -Value "[$timestamp] Script executed"
Write to CSV and XML
# Export objects to CSV
Get-Process | Select-Object Name, CPU, Id |
Export-Csv -Path "C:\Reports\processes.csv" -NoTypeInformation
# Export to XML (CliXml preserves full object structure)
Get-Process | Export-Clixml -Path "C:\Reports\processes.xml"
# Re-import the XML back into PowerShell objects
$processes = Import-Clixml -Path "C:\Reports\processes.xml"
Console Output Formatting
Format-Table
Get-Process | Select-Object Name, CPU, WorkingSet |
Format-Table -AutoSize
Format-List
Get-Service -Name wuauserv | Format-List *
Format-Wide
Get-Process | Format-Wide -Property Name -Column 4
Suppressing Output
# Suppress all output from a command
New-Item -Path "C:\Temp\file.txt" -ItemType File | Out-Null
# Assign to $null instead
$result = New-Item -Path "C:\Temp\file2.txt" -ItemType File
$null = $result
Summary
PowerShell provides a rich set of I/O tools. Write-Host handles user-facing console messages with color. Write-Output sends data into the pipeline. Write-Verbose, Write-Warning, and Write-Error cover diagnostic and error output streams. Read-Host captures interactive user input. Get-Content reads files, Set-Content and Add-Content write and append to files, and Export-Csv and Export-Clixml handle structured data export. Each tool fits a specific scenario — choosing the right one keeps scripts clean and maintainable.
