Logo
CloudWithSingh
Back to all field notes
Cheatsheet
PowerShell
Beginner

PowerShell Format Output: The Complete Guide

Everything you need to format, filter, and control PowerShell output — Format-Table, Format-List, Format-Wide, Format-Hex, Select-Object, Out-GridView, and more. Practical examples, full parameter coverage, calculated properties, and real-world patterns for daily scripting.

Parveen Singh
March 11, 2026
22 min read
65 commands
Prerequisites:PowerShell 5.1+ or PowerShell 7+ installedBasic comfort with the terminalA few commands you already use (Get-Process, Get-Service, etc.)
TLDR

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.Utility

You'll get back:

CommandTypeName
CmdletFormat-Custom
CmdletFormat-Hex
CmdletFormat-List
CmdletFormat-Table
CmdletFormat-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 PropertiesDefault Format
4 or fewer propertiesTable
5 or more propertiesList

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 output
Pro Tip

Format-* 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-Date

You'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-Table

Suddenly 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, WorkingSet

Without -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 -AutoSize

The 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.

Warning

-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)}}
  -AutoSize

Output:

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')}}
  -AutoSize

Example 3: Conditional values

Get-Service | Format-Table Name,
  @{L='State'; E={
    if ($_.Status -eq 'Running') { '✅ Running' } else { '⛔ Stopped' }
  }} -AutoSize

Example 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}
  -AutoSize

The 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 -AutoSize

Output:

   Status: Running

Name                 DisplayName                           StartType
----                 -----------                           ---------
AarSvc_12345         Agent Activation Runtime              Manual
...

   Status: Stopped

Name                 DisplayName                           StartType
----                 -----------                           ---------
AJRouter             AllJoyn Router Service                Manual
...
Pro Tip

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 dashes

Format-Table Complete Parameter Reference

ParameterWhat It DoesWhen To Use
-PropertyChoose which columns to showWhen default shows too many/few
-AutoSizeShrink columns to fit dataAlmost always
-WrapWrap long values instead of truncatingWhen values get cut off with ...
-GroupByAdd group headers between sectionsStatus, type, or category grouping
-HideTableHeadersRemove column header row and dashesScripting or clean output
-ViewUse a named view from .format.ps1xmlRarely (for special formatting views)
-RepeatHeaderRepeat 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, DependentServices

The 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 hidden

Rule 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 -AutoSize

fl * 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}}
Pro Tip

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 | fw

Format-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 Name

Controlling 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 1

Without -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 4

Format-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-Hex

Output:

           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-Hex

Real-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 mismatch

Scenario 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 BOM

Scenario 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-GridView

The -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-Process

With -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 None

Cross-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
CmdletPurposeOutput TypePipe to other cmdlets?
Select-ObjectFilter properties for dataReal objects✅ Yes
Format-TableDisplay formattingFormat 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, CPU

The | 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 1

Excluding 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
Warning

-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

ParameterWhat It DoesExample
-PropertyPick specific propertiesSelect-Object Name, CPU
-ExcludePropertyRemove specific propertiesSelect-Object * -ExcludeProperty Site
-ExpandPropertyUnpack nested collectionsSelect-Object -ExpandProperty Modules
-First NTake first N objectsSelect-Object -First 10
-Last NTake last N objectsSelect-Object -Last 5
-Skip NSkip first N objectsSelect-Object -Skip 20
-UniqueRemove duplicate rowsSelect-Object Source -Unique
Pro Tip

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-Host

You 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 200
Warning

Out-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 File

Out-GridView

Covered in detail in its own section above. The interactive GUI option.

Out-* Quick Reference

CmdletDestinationKey Use Case
Out-HostTerminal screenDefault (implicit)
Out-FileText file on diskSaving formatted reports
Out-StringString variableCapturing formatted output
Out-NullNowhere (discarded)Suppressing unwanted output
Out-GridViewGUI windowInteractive 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.html

Adding 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.html

Fragment 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 -AutoSize

Pattern 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)}} -AutoSize

Pattern 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 -AutoSize

Pattern 4: Group and Summarize

Get-Service |
  Sort-Object Status |
  Format-Table Name, DisplayName -GroupBy Status -AutoSize

Pattern 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 -NoTypeInformation

Pattern 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 -AutoSize

Pattern 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 -AutoSize

Pattern 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.html

Pattern 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

AliasFull Cmdlet
ftFormat-Table
flFormat-List
fwFormat-Wide
fhxFormat-Hex
ogvOut-GridView
selectSelect-Object
sortSort-Object
whereWhere-Object

🛠️ Troubleshooting

ProblemCauseFix
Output shows ... (truncated)Column too narrowAdd -AutoSize or -Wrap
Export-CSV has weird Format* columnsPiped Format-Table to Export-CSVUse Select-Object instead of Format-Table before export
Table only shows 4 propertiesPowerShell default format definitionSpecify properties explicitly: ft Prop1, Prop2, Prop3, Prop4, Prop5
-AutoSize is slow on large datasetsEntire output buffered firstRemove -AutoSize, or pipe through Out-String -Stream
Out-GridView not foundPowerShell 7 on macOS/LinuxInstall-Module Microsoft.PowerShell.ConsoleGuiTools then use Out-ConsoleGridView
-ExpandProperty shows errorTried expanding multiple properties-ExpandProperty only works with one property at a time
Format-List * shows {} for a propertyProperty contains an empty collectionPipe to Select-Object -ExpandProperty PropertyName to see what's inside
Out-File truncates wide tablesDefault 80-character line widthAdd -Width 200 (or wider) to Out-File
-GroupBy shows duplicate headersData not sorted by group propertySort-Object by the same property before -GroupBy

What's Next

Bookmark this page

Save it for your next project sprint

Start a project

Apply what you just learned hands-on

Follow on Instagram

Daily cloud tips & behind-the-scenes

Try hands-on labs

Practice in a real cloud environment

Parveen Singh

Parveen Singh

Microsoft Certified Trainer & Cloud Solutions Consultant

Related Field Notes

Found this useful?

Stay in the loop

Weekly cloud insights, no spam

Subscribe

Explore CloudLearn

Hands-on labs & projects

Start Learning

Book Training

Custom cloud training for your team

Get in Touch

On this page