PowerShell returns objects, not text — and how you format those objects determines whether your output is useful or a wall of noise. This guide covers every formatting cmdlet (Format-Table, Format-List, Format-Wide, Format-Hex), deep-dives into Select-Object for data filtering, and shows you the Out-* cmdlets that control where your output actually goes. Full parameter breakdowns, calculated properties, real-world patterns, and the mistakes that trip up everyone.
⚙️ How PowerShell Output Actually Works
Before touching any Format-* cmdlet, you need to understand one thing:
PowerShell doesn't output text. It outputs objects.
When you run Get-Process, you don't get lines of text — you get a collection of System.Diagnostics.Process objects. PowerShell's formatting system decides how to render those objects for your screen.
Discovering Available Format Commands
Run this to see every formatting cmdlet available in your session:
Get-Command -Verb Format -Module Microsoft.PowerShell.UtilityYou'll get back:
| CommandType | Name |
|---|---|
| Cmdlet | Format-Custom |
| Cmdlet | Format-Hex |
| Cmdlet | Format-List |
| Cmdlet | Format-Table |
| Cmdlet | Format-Wide |
These are your five built-in formatting tools. Format-Table and Format-List handle 95% of daily work. The others are situational.
Default Formatting Rules
PowerShell uses internal formatting rules (stored in .format.ps1xml files) to decide how to display objects. When no formatting file exists for an object type, it falls back to these defaults:
| Object Properties | Default Format |
|---|---|
| 4 or fewer properties | Table |
| 5 or more properties | List |
That's why Get-Process shows a table but Get-Service | Select-Object * dumps a list. It's not random — it's property count.
The Golden Rule of Formatting
# ✅ Format-* is ALWAYS the last command in a pipeline
Get-Service | Where-Object Status -eq 'Running' | Format-Table -AutoSize
# ❌ Never pipe Format-* output to data cmdlets
Get-Service | Format-Table | Export-CSV services.csv # Garbage outputFormat-* cmdlets destroy the object structure — they produce formatting instructions, not data. They're for human display only. For data pipelines, use Select-Object instead.
📊 Format-Table (ft)
The most-used formatting cmdlet. Renders objects as columns and rows — the classic spreadsheet-style output.
Getting Started
Let's start simple. Run Get-Date in your PowerShell terminal:
Get-DateYou'll see output like: Wednesday, March 11, 2026 10:30:00 AM — a single line with minimal information.
Now pipe it through Format-Table:
Get-Date | Format-TableSuddenly you see columns: DisplayHint, Date, Day, DayOfWeek, DayOfYear, Hour, Kind... The table format reveals all the structured data hiding behind the default display.
The -Property Parameter
Use -Property to choose exactly which columns appear and in what order:
# Pick specific date properties
Get-Date | Format-Table -Property Month, Day, Hour, Minute, Millisecond
# Rearrange process columns
Get-Process | Format-Table -Property Id, Name, CPU, WorkingSet
# Use the shorthand (just list properties after Format-Table)
Get-Process | Format-Table Id, Name, CPU, WorkingSetWithout -Property, PowerShell uses the predefined column set from the object's formatting definition. With it, you're in full control.
The -AutoSize Flag
This is the single most useful parameter in PowerShell formatting:
# Without -AutoSize (columns use fixed widths, data gets truncated)
Get-Service | Format-Table
# With -AutoSize (columns shrink to fit, nothing gets cut off)
Get-Service | Format-Table -AutoSizeThe difference is dramatic. Without -AutoSize, you get columns padded with whitespace and values truncated with .... With it, every column is exactly as wide as it needs to be.
-AutoSize buffers the entire output before displaying. For very large datasets (10,000+ objects), this can be slow. For normal day-to-day use, always include it.
Calculated Properties — The Power Move
Calculated properties let you rename columns, transform values, format numbers, and compute new fields — all inline. The syntax uses a hashtable with Label (or L) and Expression (or E) keys:
@{Label='Column Name'; Expression={ <scriptblock> }}
# Short form:
@{L='Column Name'; E={ <scriptblock> }}Inside the Expression scriptblock, $_ refers to the current object.
Example 1: Format numbers for readability
Get-Process | Format-Table Name, Id,
@{L='CPU (s)'; E={[math]::Round($_.CPU, 2)}},
@{L='Memory (MB)'; E={[math]::Round($_.WorkingSet / 1MB, 2)}}
-AutoSizeOutput:
Name Id CPU (s) Memory (MB)
---- -- ------- -----------
chrome 1234 45.23 312.56
code 5678 12.89 487.12
Without calculated properties, WorkingSet shows as raw bytes (511705088) — useless for quick scanning.
Example 2: Format dates
Get-ChildItem | Format-Table Name, Length,
@{L='Modified'; E={$_.LastWriteTime.ToString('yyyy-MM-dd HH:mm')}}
-AutoSizeExample 3: Conditional values
Get-Service | Format-Table Name,
@{L='State'; E={
if ($_.Status -eq 'Running') { '✅ Running' } else { '⛔ Stopped' }
}} -AutoSizeExample 4: Column alignment and width
Get-Process | Format-Table Name,
@{L='CPU (s)'; E={[math]::Round($_.CPU, 2)}; Alignment='Right'; Width=12},
@{L='Memory (MB)'; E={[math]::Round($_.WorkingSet / 1MB, 1)}; Alignment='Right'; Width=14}
-AutoSizeThe Alignment key accepts Left, Right, or Center. The Width key sets a fixed column width in characters.
Grouping Output
-GroupBy splits the output into sections, each with a header identifying the group:
# Group services by status
Get-Service | Sort-Object Status | Format-Table -GroupBy Status -AutoSizeOutput:
Status: Running
Name DisplayName StartType
---- ----------- ---------
AarSvc_12345 Agent Activation Runtime Manual
...
Status: Stopped
Name DisplayName StartType
---- ----------- ---------
AJRouter AllJoyn Router Service Manual
...
Always Sort-Object by the same property you're grouping by. Otherwise, you'll get repeated group headers scattered throughout the output — PowerShell creates a new group header every time the value changes, not by collecting all matching items.
Wrap vs. Truncate
# Default: truncate long values with ...
Get-Service | Format-Table Name, DisplayName, Status
# Wrap long values to the next line
Get-Service | Format-Table Name, DisplayName, Status -Wrap-Wrap prevents data loss. If a DisplayName is 80 characters, it wraps to the next line instead of showing Microsoft Defender Antivir....
Hiding Table Headers
For clean output in scripts or when piping to files:
Get-Process | Format-Table Name -HideTableHeaders
# Just a list of names, no header row or dashesFormat-Table Complete Parameter Reference
| Parameter | What It Does | When To Use |
|---|---|---|
-Property | Choose which columns to show | When default shows too many/few |
-AutoSize | Shrink columns to fit data | Almost always |
-Wrap | Wrap long values instead of truncating | When values get cut off with ... |
-GroupBy | Add group headers between sections | Status, type, or category grouping |
-HideTableHeaders | Remove column header row and dashes | Scripting or clean output |
-View | Use a named view from .format.ps1xml | Rarely (for special formatting views) |
-RepeatHeader | Repeat headers after every screenful (PS 7+) | Long outputs on scrolling terminals |
📋 Format-List (fl)
Shows each object as a vertical list of Name : Value pairs. This is the format you reach for when you need to see everything about an object.
Getting Started
Compare these two outputs:
# Default display — minimal info
Get-Date
# Wednesday, March 11, 2026 10:30:00 AM# Format-List reveals the full object
Get-Date | Format-List
# DisplayHint : DateTime
# Date : 3/11/2026 12:00:00 AM
# Day : 11
# DayOfWeek : Wednesday
# DayOfYear : 70
# Hour : 10
# Kind : Local
# ...Format-List shows every default property on its own line. Immediately you see data that was completely hidden in the default display.
Selecting Specific Properties
Use -Property to filter down to just what you need:
# Only show specific date components
Get-Date | Format-List -Property Month, Day, Hour, Minute, Millisecond
# Month : 3
# Day : 11
# Hour : 10
# Minute : 30
# Millisecond : 456# Show service details that matter
Get-Service -Name WinRM | Format-List Name, Status, StartType, DependentServicesThe Wildcard: Showing ALL Properties
The * wildcard is your discovery tool:
# "What properties does this object even have?"
Get-Process -Name code | Format-List *This dumps every single property on the object — often 60+ properties for complex objects like processes. You'll discover properties you never knew existed: StartTime, Threads, PriorityClass, HandleCount, TotalProcessorTime...
# Works on anything
Get-Service -Name WinRM | Format-List *
Get-ChildItem myfile.txt | Format-List *
Get-AzVM | Select-Object -First 1 | Format-List *When to Use Format-List Over Format-Table
# This is unreadable as a table (too many columns)
Get-Process -Name code | Select-Object * | Format-Table
# → scrolls off screen, truncated everywhere
# This is perfect as a list
Get-Process -Name code | Format-List *
# → every property on its own line, nothing hiddenRule of thumb: Use Format-Table when comparing multiple objects across a few properties. Use Format-List when inspecting one object in detail.
The Two-Step Discovery Pattern
This is the pattern I use constantly:
# Step 1: "What properties does this object even have?" (discovery)
Get-AzVM | Select-Object -First 1 | Format-List *
# Step 2: Pick the ones you need and build a clean table (production)
Get-AzVM | Format-Table Name, ResourceGroupName, Location, VmSize -AutoSizefl * is your discovery tool. Use it first to find what's available, then switch to ft for clean output.
Format-List with Calculated Properties
Calculated properties work here too — same syntax as Format-Table:
Get-Process | Format-List Name, Id,
@{L='CPU (seconds)'; E={[math]::Round($_.CPU, 2)}},
@{L='Memory (MB)'; E={[math]::Round($_.WorkingSet / 1MB, 2)}},
@{L='Uptime'; E={(Get-Date) - $_.StartTime}}Format-List * is the fastest way to answer "what data is available on this object?" Use it before you start building reports or piping to Export-CSV. You'll save time by knowing exactly what properties exist before you try to use them.
📐 Format-Wide (fw)
Renders a single property in a multi-column layout. Think of it as a compact directory listing — great when you only need to scan names.
Getting Started
# Default: shows process names in columns
Get-Process | Format-Wide
# Same output, using the alias
Get-Process | fwFormat-Wide only shows one property per object (by default, the Name property). You can specify a different property:
# Show service display names
Get-Service | Format-Wide DisplayName
# Show file names in a directory
Get-ChildItem C:\Users | Format-Wide NameControlling the Column Count
The -Column parameter sets how many columns to render:
# Compact: 5 columns
Get-Process | Format-Wide -Column 5
# Wider: 2 columns with more room
Get-Service | Format-Wide DisplayName -Column 2
# Single column (basically a name list)
Get-Process | Format-Wide -Column 1Without -Column, PowerShell auto-calculates based on your terminal width.
When It's Actually Useful
# Quick scan: "what services exist on this machine?"
Get-Service | Format-Wide DisplayName -Column 2
# Quick scan: "what modules are loaded?"
Get-Module | Format-Wide -Column 3
# Quick scan: "what's in this directory?"
Get-ChildItem C:\Users | Format-Wide -Column 4Format-Wide is niche but perfect for quick overviews when you only care about names and don't need details.
🔍 Format-Hex (fhx)
Displays file or data content in hexadecimal. Not something you use daily, but indispensable for debugging encoding issues, inspecting binary files, or checking for hidden characters.
Core Usage
# Display a string as hex
"PowerShell Hex Format" | Format-HexOutput:
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 50 6F 77 65 72 53 68 65 6C 6C 20 48 65 78 20 46 PowerShell Hex F
00000010 6F 72 6D 61 74 ormat
The left column shows the byte offset, the middle shows hex values, and the right shows the ASCII representation.
Working with Files
# Inspect a file's raw bytes
Format-Hex -Path config.json
# Read file content and inspect it
Get-Content file.txt -Raw | Format-Hex
# Inspect a byte array directly
[byte[]](0x48, 0x65, 0x6C, 0x6C, 0x6F) | Format-HexReal-World Debugging Scenarios
Scenario 1: "Why does this CSV have weird characters?"
Get-Content broken.csv -Raw | Format-Hex | Select-Object -First 5
# Look for unexpected byte sequences — often a BOM or encoding mismatchScenario 2: "Does this file have a Byte Order Mark (BOM)?"
Format-Hex -Path script.ps1 | Select-Object -First 1
# EF BB BF = UTF-8 BOM
# FF FE = UTF-16 LE BOM
# FE FF = UTF-16 BE BOMScenario 3: "Are there hidden characters in this string?"
$suspiciousString = "Hello`0World" # null character in the middle
$suspiciousString | Format-Hex
# You'll see the 00 byte between "Hello" and "World"🖥️ Out-GridView (ogv)
Opens a sortable, filterable GUI window. It's like getting an interactive spreadsheet for free. Only works on Windows with PowerShell 5.1 (or install Microsoft.PowerShell.ConsoleGuiTools on PowerShell 7 for a cross-platform terminal version).
Getting Started
# Open an interactive process viewer — click columns to sort, use the filter bar to search
Get-Process | Out-GridView
# Custom window title
Get-Service | Out-GridView -Title "All Services"
# Browse event logs visually
Get-EventLog -LogName System -Newest 100 | Out-GridViewThe -PassThru Pattern
This is what makes Out-GridView truly powerful — it turns into an interactive object picker:
# Pick services from a GUI, then restart the ones you selected
Get-Service | Out-GridView -PassThru -Title "Select services to restart" | Restart-Service
# Pick files to delete interactively
Get-ChildItem -Recurse *.log | Out-GridView -PassThru | Remove-Item
# Select processes to stop
Get-Process | Out-GridView -PassThru | Stop-ProcessWith -PassThru, you select rows in the grid, click OK, and the selected objects continue down the pipeline. Cancel returns nothing.
Output Mode
Control selection behavior with -OutputMode:
# Allow selecting only one item
Get-Service | Out-GridView -OutputMode Single
# Allow selecting multiple items (default with -PassThru)
Get-Service | Out-GridView -OutputMode Multiple
# No selection allowed, just viewing
Get-Service | Out-GridView -OutputMode NoneCross-Platform Alternative
On macOS/Linux with PowerShell 7:
Install-Module Microsoft.PowerShell.ConsoleGuiTools
Get-Process | Out-ConsoleGridView🧩 Select-Object — Filtering Data (Not Just Display)
Select-Object is often confused with Format-Table, but they serve completely different purposes. Format-Table formats for display. Select-Object filters properties and objects while keeping the data intact for further pipeline processing.
The Fundamental Difference
# Select-Object: filters properties, returns REAL objects you can pipe anywhere
Get-Process | Select-Object Name, CPU | Export-CSV procs.csv # ✅ Works perfectly
# Format-Table: formats for display, DESTROYS object structure
Get-Process | Format-Table Name, CPU | Export-CSV procs.csv # ❌ Garbage output| Cmdlet | Purpose | Output Type | Pipe to other cmdlets? |
|---|---|---|---|
Select-Object | Filter properties for data | Real objects | ✅ Yes |
Format-Table | Display formatting | Format instructions | ❌ No (display only) |
The rule: Select-Object for pipelines and data. Format-Table as the last command for human display.
Basic Syntax
Select-Object
[-InputObject <PSObject>]
[[-Property] <Object[]>]
[-ExcludeProperty <String[]>]
[-ExpandProperty <String>]
[-Unique]
[-First <Int32>]
[-Last <Int32>]
[-Skip <Int32>]
[-Wait]Selecting Specific Properties with -Property
The most common use — narrow down an object to just the fields you need:
# Show only Name, Id, and CPU for processes
Get-Process | Select-Object -Property Name, Id, CPUThe | character (the "pipe") passes output from Get-Process as input for Select-Object. The result is a new object with only Name, Id, and CPU — everything else is stripped.
# Select specific service properties
Get-Service | Select-Object Name, Status, StartType, DisplayName
# Use wildcards for property names
Get-Process | Select-Object -Property Name, *Memory*, *Time* -First 1Excluding Properties with -ExcludeProperty
Sometimes it's easier to say what you don't want:
# Show all Peak metrics except the Paged ones
Get-Process | Select-Object -Property Name, Peak* -ExcludeProperty *Paged* -First 1
# Show everything about a service except the verbose metadata
Get-Service -Name WinRM | Select-Object * -ExcludeProperty Site, Container-ExcludeProperty only works with -Property set to a wildcard pattern. It filters down from the included set.
Expanding Nested Properties with -ExpandProperty
Some properties contain nested objects (arrays, collections). -ExpandProperty unpacks them:
# DependentServices is a nested collection — normal select shows the type name
Get-Service -Name EventLog | Select-Object DependentServices
# Output: {Windows Event Collector, ...} (not very helpful)
# ExpandProperty unpacks the collection into individual objects
Get-Service -Name EventLog | Select-Object -ExpandProperty DependentServices
# Output: individual service objects you can work with# Expand the Modules property of a process
Get-Process -Name code | Select-Object -ExpandProperty Modules | Select-Object FileName -First 10-ExpandProperty only works with one property at a time. You can't expand multiple nested properties in a single Select-Object call.
First, Last, and Skip — Limiting Results
Control how many objects come through the pipeline:
# First 5 processes
Get-Process | Select-Object -First 5 Name, CPU
# Last 3 event log entries
Get-EventLog -LogName System | Select-Object -Last 3
# Skip the first 10, show the rest
Get-Process | Select-Object -Skip 10 Name, CPU
# Combine: skip the first 5, then take the next 3
Get-Process | Select-Object -Skip 5 -First 3 Name, CPU-First and -Last are how you do "top N" queries in PowerShell. They're essential for working with large datasets without overwhelming your terminal.
Removing Duplicates with -Unique
# Get unique event sources from the System event log
Get-EventLog -LogName System | Select-Object Source -Unique
# Get unique file extensions in a directory tree
Get-ChildItem -Recurse | Select-Object Extension -Unique-Unique compares the selected properties and removes duplicate rows.
Calculated Properties in Select-Object
The same @{Label; Expression} syntax from Format-Table works here — but crucially, the results are real properties you can export, filter, and pipe:
# Add a calculated Memory column, then export to CSV
Get-Process | Select-Object Name, Id,
@{L='Memory_MB'; E={[math]::Round($_.WorkingSet / 1MB, 2)}},
@{L='CPU_Seconds'; E={[math]::Round($_.CPU, 2)}} |
Export-CSV processes.csv -NoTypeInformation
# Add a computed "Age" property to files
Get-ChildItem | Select-Object Name, Length,
@{L='Age (days)'; E={((Get-Date) - $_.LastWriteTime).Days}}Select-Object Quick Reference
| Parameter | What It Does | Example |
|---|---|---|
-Property | Pick specific properties | Select-Object Name, CPU |
-ExcludeProperty | Remove specific properties | Select-Object * -ExcludeProperty Site |
-ExpandProperty | Unpack nested collections | Select-Object -ExpandProperty Modules |
-First N | Take first N objects | Select-Object -First 10 |
-Last N | Take last N objects | Select-Object -Last 5 |
-Skip N | Skip first N objects | Select-Object -Skip 20 |
-Unique | Remove duplicate rows | Select-Object Source -Unique |
Combine Sort-Object with Select-Object -First for "top N" queries: Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name, CPU gives you the top 5 CPU-consuming processes.
📤 Out-* Cmdlets — Controlling Where Output Goes
The Format-* cmdlets control how output looks. The Out-* cmdlets control where it goes.
Out-Host (Default)
Every pipeline implicitly ends with Out-Host — it sends output to your terminal screen:
# These two are identical
Get-Process | Format-Table -AutoSize
Get-Process | Format-Table -AutoSize | Out-HostYou rarely need to call Out-Host explicitly, but it's useful to understand that it's always there.
Out-File — Saving to Disk
Write formatted output to a text file:
# Save a formatted table to a text file
Get-Service | Format-Table -AutoSize | Out-File services.txt
# Append instead of overwrite
Get-Process | Format-Table Name, CPU -AutoSize | Out-File processes.txt -Append
# Control encoding
Get-Service | Format-Table -AutoSize | Out-File services.txt -Encoding UTF8
# Set a custom line width (default is 80 characters — often truncates)
Get-Service | Format-Table -AutoSize | Out-File services.txt -Width 200Out-File preserves the formatted output (what you see on screen). For structured data exports, use Export-CSV or ConvertTo-Json with Select-Object instead.
Out-String — Converting to Text
Converts formatted output to a string object. Useful when you need the text representation of formatted output:
# Capture formatted output as a string variable
$tableText = Get-Service | Format-Table -AutoSize | Out-String
$tableText # Now it's a single string, not formatting objects
# Stream line-by-line instead of one big string
Get-Service | Format-Table -AutoSize | Out-String -Stream | Select-String "Running"Out-Null — Suppressing Output
Discard output you don't need:
# Run a command but don't show output
New-Item -Path temp.txt -ItemType File | Out-Null
# Same effect, shorter syntax:
$null = New-Item -Path temp.txt -ItemType FileOut-GridView
Covered in detail in its own section above. The interactive GUI option.
Out-* Quick Reference
| Cmdlet | Destination | Key Use Case |
|---|---|---|
Out-Host | Terminal screen | Default (implicit) |
Out-File | Text file on disk | Saving formatted reports |
Out-String | String variable | Capturing formatted output |
Out-Null | Nowhere (discarded) | Suppressing unwanted output |
Out-GridView | GUI window | Interactive browsing/selection |
📊 ConvertTo-Html — Building HTML Reports
When you need to share output beyond the terminal, ConvertTo-Html generates HTML files:
# Basic HTML report
Get-Service | Select-Object Name, Status, StartType |
ConvertTo-Html -Title "Service Report" |
Out-File services.html
# Open it in your browser
Invoke-Item services.htmlAdding CSS for Readable Reports
$css = @"
<style>
body { font-family: Segoe UI, sans-serif; margin: 20px; }
table { border-collapse: collapse; width: 100%; }
th { background-color: #0078D4; color: white; padding: 8px; text-align: left; }
td { border: 1px solid #ddd; padding: 8px; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
"@
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 20 Name, Id,
@{L='CPU (s)'; E={[math]::Round($_.CPU, 2)}},
@{L='Memory (MB)'; E={[math]::Round($_.WorkingSet / 1MB, 1)}} |
ConvertTo-Html -Title "Top 20 Processes" -Head $css -Body "<h1>Process Report</h1>" |
Out-File process-report.htmlFragment Mode for Multiple Tables
$header = ConvertTo-Html -Title "Server Health" -Head $css -Body "<h1>Server Health Report</h1>" |
Out-String
$services = Get-Service | Where-Object Status -eq 'Running' |
Select-Object -First 10 Name, DisplayName |
ConvertTo-Html -Fragment -PreContent "<h2>Running Services</h2>" |
Out-String
$processes = Get-Process |
Sort-Object CPU -Descending |
Select-Object -First 10 Name, CPU |
ConvertTo-Html -Fragment -PreContent "<h2>Top CPU Processes</h2>" |
Out-String
"$header $services $processes" | Out-File server-health.html🎯 Real-World Patterns — Copy These
Pattern 1: Clean Service Report
Get-Service |
Where-Object Status -eq 'Running' |
Sort-Object DisplayName |
Format-Table DisplayName, Status, StartType -AutoSizePattern 2: Top 10 Process Memory Usage
Get-Process |
Sort-Object WorkingSet -Descending |
Select-Object -First 10 |
Format-Table Name, Id,
@{L='CPU (s)'; E={[math]::Round($_.CPU, 2)}},
@{L='Memory (MB)'; E={[math]::Round($_.WorkingSet / 1MB, 1)}} -AutoSizePattern 3: Discover Then Display
# Step 1: Discover — what properties exist?
Get-AzResource | Select-Object -First 1 | Format-List *
# Step 2: Build your clean table from what you found
Get-AzResource | Format-Table Name, ResourceGroupName, ResourceType, Location -AutoSizePattern 4: Group and Summarize
Get-Service |
Sort-Object Status |
Format-Table Name, DisplayName -GroupBy Status -AutoSizePattern 5: Export vs. Display
# For humans (display) — Format-Table as last command
Get-Process | Format-Table Name, CPU, WorkingSet -AutoSize
# For machines (data) — Select-Object + Export, no Format-*
Get-Process | Select-Object Name, CPU, WorkingSet | Export-CSV processes.csv -NoTypeInformationPattern 6: Top-N Query
# Top 5 CPU-consuming processes
Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 Name, CPU
# Top 10 largest files
Get-ChildItem -Recurse -File |
Sort-Object Length -Descending |
Select-Object -First 10 Name, Directory,
@{L='Size (MB)'; E={[math]::Round($_.Length / 1MB, 2)}} |
Format-Table -AutoSizePattern 7: Event Log Inspection
# Recent errors from the Application event log
Get-EventLog -LogName Application -EntryType Error -Newest 20 |
Select-Object TimeGenerated, Source, Message |
Format-List
# Unique sources causing errors
Get-EventLog -LogName Application -EntryType Error |
Select-Object Source -Unique |
Sort-Object Source |
Format-Table -AutoSizePattern 8: Save as HTML Report
Get-Service |
Where-Object Status -eq 'Stopped' |
Select-Object Name, DisplayName, StartType |
ConvertTo-Html -Title "Stopped Services" |
Out-File stopped-services.htmlPattern 9: Interactive Selection then Action
# Select processes from a GUI, then stop them
Get-Process | Out-GridView -PassThru -Title "Select processes to stop" | Stop-Process
# Select files from a GUI, then move them
Get-ChildItem -Recurse *.log | Out-GridView -PassThru | Move-Item -Destination C:\Archive📎 Quick Alias Reference
| Alias | Full Cmdlet |
|---|---|
ft | Format-Table |
fl | Format-List |
fw | Format-Wide |
fhx | Format-Hex |
ogv | Out-GridView |
select | Select-Object |
sort | Sort-Object |
where | Where-Object |
🛠️ Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
Output shows ... (truncated) | Column too narrow | Add -AutoSize or -Wrap |
Export-CSV has weird Format* columns | Piped Format-Table to Export-CSV | Use Select-Object instead of Format-Table before export |
| Table only shows 4 properties | PowerShell default format definition | Specify properties explicitly: ft Prop1, Prop2, Prop3, Prop4, Prop5 |
-AutoSize is slow on large datasets | Entire output buffered first | Remove -AutoSize, or pipe through Out-String -Stream |
Out-GridView not found | PowerShell 7 on macOS/Linux | Install-Module Microsoft.PowerShell.ConsoleGuiTools then use Out-ConsoleGridView |
-ExpandProperty shows error | Tried expanding multiple properties | -ExpandProperty only works with one property at a time |
Format-List * shows {} for a property | Property contains an empty collection | Pipe to Select-Object -ExpandProperty PropertyName to see what's inside |
Out-File truncates wide tables | Default 80-character line width | Add -Width 200 (or wider) to Out-File |
-GroupBy shows duplicate headers | Data not sorted by group property | Sort-Object by the same property before -GroupBy |