PowerShell’s formatting and output cmdlets transform raw data into readable, actionable information. Whether you’re displaying process information, exporting logs, or creating reports, understanding these cmdlets is essential for effective PowerShell scripting and administration.

Understanding PowerShell’s Formatting System

PowerShell uses a sophisticated formatting system that automatically determines how to display objects. When you run a command, PowerShell checks for custom formatting rules and applies them before displaying output. The formatting cmdlets give you explicit control over this process.

Formatting and Output in PowerShell: Complete Guide to Format-Table, Format-List, Out-File & More

The Four Core Formatting Cmdlets

PowerShell provides four primary formatting cmdlets, each serving different visualization needs:

  • Format-Table: Displays output in tabular format with columns
  • Format-List: Shows each property on a separate line
  • Format-Wide: Displays objects in multiple columns with limited properties
  • Format-Custom: Uses custom view definitions for specialized formatting

Format-Table: Tabular Data Display

Format-Table (alias: ft) is the most commonly used formatting cmdlet. It organizes data into columns, making it ideal for comparing multiple objects with similar properties.

Basic Format-Table Usage

# Display processes in table format
Get-Process | Format-Table

# Select specific properties
Get-Process | Format-Table Name, CPU, WorkingSet

# Alternative syntax
Get-Process | ft Name, CPU, WorkingSet

Output:

Name                           CPU        WorkingSet
----                           ---        ----------
chrome                      45.23      234567890
powershell                   2.15       89012345
explorer                    12.89      156789012

AutoSize Parameter

The AutoSize parameter adjusts column widths to fit content, eliminating wasted space:

Get-Service | Format-Table Name, Status, DisplayName -AutoSize
Name    Status  DisplayName
----    ------  -----------
BITS    Running Background Intelligent Transfer Service
Spooler Running Print Spooler
wuauserv Running Windows Update

Property Expressions and Calculated Properties

Create custom columns with calculated values using hashtable syntax:

Get-Process | Format-Table Name, 
    @{Label="Memory(MB)"; Expression={$_.WorkingSet / 1MB}; FormatString="N2"},
    @{Label="CPU(s)"; Expression={$_.CPU}; FormatString="N2"} -AutoSize
Name       Memory(MB) CPU(s)
----       ---------- ------
chrome        223.74  45.23
powershell     84.88   2.15
explorer      149.51  12.89

GroupBy Parameter

Group related items together based on a property:

Get-Service | Format-Table Name, DisplayName -GroupBy Status
   Status: Running

Name    DisplayName
----    -----------
BITS    Background Intelligent Transfer Service
Spooler Print Spooler

   Status: Stopped

Name       DisplayName
----       -----------
AppIDSvc   Application Identity

Format-List: Detailed Property View

Format-List (alias: fl) displays each property on its own line, making it perfect for viewing detailed information about individual objects.

Basic Format-List Usage

# Display all properties of a process
Get-Process powershell | Format-List

# Display specific properties
Get-Process powershell | Format-List Name, Id, CPU, StartTime

# Show all properties including hidden ones
Get-Process powershell | Format-List *

Output:

Name      : powershell
Id        : 12345
CPU       : 2.15625
StartTime : 10/22/2025 9:30:45 AM

When to Use Format-List

Format-List excels when you need to:

  • Examine detailed properties of a single object
  • View properties with long text values
  • Troubleshoot by seeing all available properties
  • Display nested or complex object structures
# Perfect for viewing service details
Get-Service BITS | Format-List *

# Excellent for examining file properties
Get-Item C:\Windows\notepad.exe | Format-List *

Out-File: Redirecting Output to Files

Out-File sends command output to a text file, essential for logging, reporting, and data export.

Formatting and Output in PowerShell: Complete Guide to Format-Table, Format-List, Out-File & More

Basic Out-File Syntax

# Save process list to file
Get-Process | Out-File C:\Logs\processes.txt

# Append to existing file
Get-Service | Out-File C:\Logs\services.txt -Append

# Specify encoding
Get-Process | Out-File C:\Logs\processes.txt -Encoding UTF8

Out-File Parameters

# Control width to prevent line wrapping
Get-Process | Format-Table | Out-File C:\Logs\processes.txt -Width 200

# Overwrite without confirmation
Get-Service | Out-File C:\Logs\services.txt -Force

# No line wrapping
Get-Process | Out-File C:\Logs\processes.txt -NoNewline

Out-File vs Redirection Operator

PowerShell offers the redirection operator (>) as a shorthand:

# These are equivalent
Get-Process | Out-File C:\Logs\processes.txt
Get-Process > C:\Logs\processes.txt

# Append with >>
Get-Service >> C:\Logs\services.txt

Export-Csv: Structured Data Export

Export-Csv creates comma-separated value files, ideal for data analysis in Excel or other tools.

Basic CSV Export

# Export processes to CSV
Get-Process | Export-Csv C:\Reports\processes.csv

# Without type information header
Get-Process | Export-Csv C:\Reports\processes.csv -NoTypeInformation

# Select specific properties
Get-Process | Select-Object Name, CPU, WorkingSet | 
    Export-Csv C:\Reports\processes.csv -NoTypeInformation

Custom Delimiters and Encoding

# Use semicolon delimiter
Get-Service | Export-Csv C:\Reports\services.csv -Delimiter ";" -NoTypeInformation

# Specify encoding
Get-Process | Export-Csv C:\Reports\processes.csv -Encoding UTF8 -NoTypeInformation

# Append to existing CSV
Get-Service | Export-Csv C:\Reports\services.csv -Append -NoTypeInformation

Importing CSV Data

# Import and work with CSV data
$processes = Import-Csv C:\Reports\processes.csv
$processes | Where-Object {$_.CPU -gt 10}

# Convert CSV to objects for processing
Import-Csv C:\Reports\services.csv | 
    Where-Object Status -eq "Running" | 
    Format-Table Name, DisplayName

Out-GridView: Interactive Data Explorer

Out-GridView (alias: ogv) displays output in a searchable, filterable GUI window, perfect for interactive data exploration.

Basic GridView Usage

# Display processes in grid view
Get-Process | Out-GridView

# Add a custom title
Get-Service | Out-GridView -Title "Windows Services"

# Wait for user selection
$selected = Get-Process | Out-GridView -PassThru
$selected | Stop-Process

Selection Modes

# Single selection
$process = Get-Process | Out-GridView -OutputMode Single
Write-Host "Selected: $($process.Name)"

# Multiple selection
$services = Get-Service | Out-GridView -OutputMode Multiple
$services | Start-Service

# No selection (view only)
Get-EventLog -LogName System -Newest 100 | Out-GridView

ConvertTo-Html: Creating HTML Reports

ConvertTo-Html generates HTML-formatted output for web-based reports and documentation.

Basic HTML Conversion

# Create simple HTML report
Get-Process | ConvertTo-Html | Out-File C:\Reports\processes.html

# Add custom title and styling
Get-Service | ConvertTo-Html -Title "Service Report" -PreContent "

Windows Services

" | Out-File C:\Reports\services.html

Advanced HTML Reports with CSS

$css = @"

"@

Get-Process | Select-Object Name, CPU, WorkingSet -First 10 |
    ConvertTo-Html -Head $css -Title "Top 10 Processes" |
    Out-File C:\Reports\styled_processes.html

Output Cmdlets Comparison

Formatting and Output in PowerShell: Complete Guide to Format-Table, Format-List, Out-File & More

Choosing the Right Output Cmdlet

# Console viewing: Format-Table
Get-Process | Format-Table Name, CPU

# Detailed inspection: Format-List
Get-Service BITS | Format-List *

# Simple logging: Out-File
Get-EventLog -LogName System -Newest 50 | Out-File C:\Logs\events.txt

# Data export: Export-Csv
Get-ADUser -Filter * | Export-Csv C:\Reports\users.csv -NoTypeInformation

# Interactive filtering: Out-GridView
Get-Process | Out-GridView -PassThru | Stop-Process

# Web reports: ConvertTo-Html
Get-Service | ConvertTo-Html | Out-File C:\Reports\services.html

Format-Wide: Compact Multi-Column Display

Format-Wide (alias: fw) displays objects in multiple columns, showing only one property per object.

Basic Format-Wide Usage

# Display process names in columns
Get-Process | Format-Wide Name

# Specify number of columns
Get-Service | Format-Wide Name -Column 4

# Display with property selection
Get-ChildItem | Format-Wide Name -Column 3

Output:

chrome      powershell  explorer    notepad
winword     excel       outlook     teams

Out-String: Converting to String Format

Out-String converts objects to strings, useful for text manipulation or storing formatted output as variables.

# Convert to string
$output = Get-Process | Format-Table | Out-String

# Store formatted data
$serviceList = Get-Service | Format-List * | Out-String
$serviceList | Out-File C:\Reports\services.txt

# Width control
$wide = Get-Process | Format-Table | Out-String -Width 200

Advanced Formatting Techniques

Custom Format Files

PowerShell allows creating custom .ps1xml format files for consistent object display:

# View current format data
Get-FormatData -TypeName System.Diagnostics.Process

# Load custom format file
Update-FormatData -PrependPath C:\CustomFormats\MyFormat.ps1xml

Combining Format and Output Cmdlets

# Format then export
Get-Process | 
    Format-Table Name, CPU, WorkingSet | 
    Out-File C:\Reports\processes.txt -Width 150

# Multiple outputs from same data
$services = Get-Service
$services | Export-Csv C:\Reports\services.csv -NoTypeInformation
$services | ConvertTo-Html | Out-File C:\Reports\services.html
$services | Format-Table | Out-File C:\Reports\services.txt

Pipeline Performance Considerations

Formatting and Output in PowerShell: Complete Guide to Format-Table, Format-List, Out-File & More

# Efficient: Filter before formatting
Get-Process | 
    Where-Object CPU -gt 10 | 
    Select-Object Name, CPU, WorkingSet | 
    Format-Table -AutoSize

# Less efficient: Format before filtering (avoid this)
Get-Process | 
    Format-Table | 
    Where-Object CPU -gt 10  # Won't work as expected

Real-World Formatting Examples

System Monitoring Report

# Create comprehensive system report
$date = Get-Date -Format "yyyy-MM-dd"
$reportPath = "C:\Reports\SystemReport_$date.html"

$css = @"

"@

$html = @"

System Report - $(Get-Date -Format 'yyyy-MM-dd HH:mm')

Top 10 CPU Consuming Processes

$(Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU, WorkingSet | ConvertTo-Html -Fragment)

Running Services

$(Get-Service | Where-Object Status -eq "Running" | Select-Object Name, DisplayName, Status | ConvertTo-Html -Fragment)

Disk Space

$(Get-PSDrive -PSProvider FileSystem | Select-Object Name, @{N="Used(GB)";E={[math]::Round($_.Used/1GB,2)}}, @{N="Free(GB)";E={[math]::Round($_.Free/1GB,2)}} | ConvertTo-Html -Fragment) "@ ConvertTo-Html -Head $css -Body $html -Title "System Report" | Out-File $reportPath

Service Status Dashboard

# Interactive service management
$services = Get-Service | 
    Select-Object Name, DisplayName, Status, StartType | 
    Sort-Object Status, Name

$selected = $services | Out-GridView -Title "Service Manager" -OutputMode Multiple

foreach ($service in $selected) {
    $action = Read-Host "Action for $($service.Name) [Start/Stop/Restart]"
    switch ($action.ToLower()) {
        "start" { Start-Service $service.Name }
        "stop" { Stop-Service $service.Name }
        "restart" { Restart-Service $service.Name }
    }
}

Log Analysis and Export

# Analyze event logs and create multiple outputs
$errors = Get-EventLog -LogName System -EntryType Error -Newest 100

# Console summary
$errors | 
    Group-Object Source | 
    Sort-Object Count -Descending | 
    Format-Table Count, Name -AutoSize

# Detailed CSV export
$errors | 
    Select-Object TimeGenerated, Source, EventID, Message | 
    Export-Csv C:\Logs\system_errors.csv -NoTypeInformation

# HTML report
$errors | 
    Select-Object TimeGenerated, Source, EventID, Message | 
    ConvertTo-Html -Title "System Errors" | 
    Out-File C:\Logs\system_errors.html

# Plain text log
$errors | 
    Format-List TimeGenerated, Source, EventID, Message | 
    Out-File C:\Logs\system_errors.txt

Best Practices for Formatting and Output

Performance Optimization

  • Apply filters with Where-Object before formatting cmdlets
  • Use Select-Object to limit properties before exporting
  • Avoid using Format-* cmdlets in the middle of pipelines
  • Use -AutoSize sparingly for large datasets
# Good: Filter first
Get-Process | Where-Object CPU -gt 5 | Format-Table Name, CPU

# Bad: Format first (loses object properties)
Get-Process | Format-Table Name, CPU | Where-Object CPU -gt 5

Output Encoding

# Ensure proper encoding for international characters
Get-Service | Out-File C:\Reports\services.txt -Encoding UTF8

# Specify encoding for CSV
Get-Process | Export-Csv C:\Reports\processes.csv -Encoding UTF8 -NoTypeInformation

Error Handling

# Safe file operations with error handling
try {
    Get-Process | Export-Csv C:\Reports\processes.csv -NoTypeInformation -ErrorAction Stop
    Write-Host "Export successful" -ForegroundColor Green
}
catch {
    Write-Host "Export failed: $_" -ForegroundColor Red
}

# Test path before writing
$outputPath = "C:\Reports\output.txt"
if (Test-Path (Split-Path $outputPath)) {
    Get-Service | Out-File $outputPath
} else {
    Write-Host "Directory does not exist" -ForegroundColor Red
}

Common Formatting Pitfalls and Solutions

Truncated Output

PowerShell truncates columns by default. Solutions:

# Use AutoSize for better column width
Get-Process | Format-Table Name, Path -AutoSize

# Increase width for Out-File
Get-Process | Format-Table | Out-File C:\Logs\processes.txt -Width 300

# Use Format-List for long values
Get-Process | Format-List Name, Path

Lost Object Properties

Format-* cmdlets convert objects to formatted text, losing original properties:

# Wrong: Can't access properties after formatting
Get-Process | Format-Table Name, CPU | Where-Object CPU -gt 5  # Won't work

# Correct: Filter before formatting
Get-Process | Where-Object CPU -gt 5 | Format-Table Name, CPU

Type Information in CSV

# Avoid type information header
Get-Process | Export-Csv C:\Reports\processes.csv -NoTypeInformation

# Or use ConvertTo-Csv for in-memory processing
$csv = Get-Service | ConvertTo-Csv -NoTypeInformation

Conclusion

Mastering PowerShell’s formatting and output cmdlets enables you to present data effectively, create professional reports, and export information in various formats. Format-Table and Format-List provide console visualization, Out-File and Export-Csv handle file operations, while Out-GridView and ConvertTo-Html offer interactive and web-based solutions. By combining these cmdlets appropriately and following best practices, you can build powerful scripts that communicate results clearly and efficiently.

Remember to filter data before formatting, choose the right output format for your needs, and always consider your audience when presenting information. With these tools and techniques, you’re equipped to handle any PowerShell formatting and output challenge.