⚡ PowerShell Pipeline Cheatsheet

Pipeline & Object Manipulationv7.x
Harness the power of object-oriented pipelines

Pipeline Fundamentals

Get-Process | Sort-Object -Property CPU
Pass objects through the pipeline (not just text)
Get-Service | Where-Object Status -eq 'Running'
Filter objects based on properties
Get-ChildItem | Measure-Object -Property Length -Sum
Calculate aggregate statistics on properties
💡 PIPELINE CONCEPT PowerShell passes full objects (not text) between cmdlets. Each object retains all its properties and methods throughout the pipeline.

Filtering Objects

Where-Object { $_.Size -gt 1MB }
Filter using script block ($_ = current object)
Where-Object Name -like '*log*'
Simplified syntax for single property comparisons
... | ? { $_.Status -eq 'Running' -and $_.CPU -gt 50 }
Alias (?) with complex conditions
Operator Description
-eq Equals
-ne Not equals
-gt / -lt Greater/Less than
-like Wildcard match
-match Regex match
-contains Collection contains

Selecting Properties

Select-Object -Property Name, Status, CPU
Select specific properties from objects
Select-Object -First 10
Get first N objects
Select-Object -Skip 5 -First 10
Skip first 5, then take 10
Select-Object -Unique
Remove duplicate objects
Select-Object -ExpandProperty ProcessName
Extract single property as array of values
Select-Object Name, @{n='SizeMB'; e={$_.Length/1MB}}
Create calculated properties

Iteration & Transformation

ForEach-Object { $_.Name.ToUpper() }
Transform each object through script block
ForEach-Object { Stop-Process -Id $_.Id }
Execute cmdlet for each object
% { $_.Length * 2 }
Alias (%) for quick transformations
ForEach-Object -Begin {$total=0} -Process {$total+=$_.Size} -End {$total}
Begin/Process/End blocks for complex operations
ForEach-Object -Parallel { Test-Connection $_ } -ThrottleLimit 10
Parallel execution (PowerShell 7+)

Sorting & Grouping

Sort-Object -Property Name
Sort by property (ascending default)
Sort-Object CPU -Descending
Sort descending
Sort-Object Status, Name
Multi-level sort
Group-Object -Property Status
Group objects by property value
Returns: Count, Name, Group properties
Group-Object Extension -NoElement
Group without storing objects (faster)
Group-Object {$_.Length -gt 1MB}
Group by calculated expression

Property Access

$object.PropertyName
Dot notation for property access
$object | Get-Member
Discover all properties and methods
$object | Get-Member -MemberType Property
Show only properties
$object.PSObject.Properties | Select-Object Name, Value
Iterate through all properties
$object | Add-Member -NotePropertyName 'NewProp' -NotePropertyValue 'Value'
Add custom property to object

Comparing Objects

Compare-Object -ReferenceObject $arr1 -DifferenceObject $arr2
Find differences between two collections
<= in reference only, => in difference only
Compare-Object $old $new -Property Name, Status
Compare specific properties
Compare-Object $a $b -IncludeEqual -ExcludeDifferent
Find only matching objects

Advanced Selection

Select-Object *
Select all properties (useful after filtering)
Select-Object -ExcludeProperty Id, Hash
Select all except specified properties
Select-Object *, @{n='Age'; e={(Get-Date) - $_.BirthDate}}
Combine existing + calculated properties
Select-Object @{Label='Computer'; Expression={$_.PSComputerName}}
Full syntax for calculated properties

Aggregation & Measurement

Measure-Object
Count objects in pipeline
Measure-Object -Property Size -Sum -Average -Maximum -Minimum
Calculate statistics on numeric properties
Measure-Object -Line -Word -Character
Text statistics (works with Get-Content)
($data | Measure-Object -Property Price -Sum).Sum
Extract specific statistic value

Formatting Output

Format-Table -AutoSize
Table format with auto-sized columns
Format-Table Name, Status, @{l='CPU%'; e={$_.CPU}; a='right'}
Custom columns with labels and alignment
Format-List *
List format showing all properties
Format-Wide -Property Name -Column 4
Multi-column compact display
⚠️ CRITICAL Format-* cmdlets should be LAST in pipeline. They output format objects, not original objects!

$Pipeline Variables

$_
Current object in pipeline (most common)
$PSItem
Same as $_ (explicit alternative)
ForEach-Object { $_.Name; $_.Status }
Access multiple properties of current object
... | % { Write-Host "Processing: $($_.Name)" }
Embed pipeline variable in strings

Pipeline Branching

Get-Process | Tee-Object -Variable procs | Where-Object ...
Save objects to variable while passing through
Get-Service | Tee-Object -FilePath services.txt | Select-Object ...
Export to file while continuing pipeline
💡 USE CASE Tee-Object lets you inspect or save data mid-pipeline without breaking the flow

Object Conversion

ConvertTo-Json
Convert objects to JSON format
ConvertTo-Json -Depth 5
Control nesting depth (default is 2)
ConvertFrom-Json
Parse JSON to PowerShell objects
ConvertTo-Csv -NoTypeInformation
Convert to CSV (without type header)
ConvertTo-Html -Title 'Report' -PreContent '<h1>System Report</h1>'
Generate HTML tables from objects
ConvertTo-Xml -As String
Export as XML string

Export & Import

Export-Csv -Path data.csv -NoTypeInformation
Export objects to CSV file
Import-Csv -Path data.csv
Import CSV as objects
Export-Clixml -Path objects.xml
Serialize objects preserving types
Import-Clixml -Path objects.xml
Deserialize with full type fidelity
Out-File -FilePath output.txt -Encoding utf8
Write formatted output to file

Advanced Where-Object

? { $_.Name -match '^[A-Z]{3}\d+' }
Filter using regex patterns
? { $_.Tags -contains 'Production' }
Filter where array property contains value
? { $_.LastModified -gt (Get-Date).AddDays(-7) }
Filter by date calculations
? { $_.GetType().Name -eq 'FileInfo' }
Filter by object type
? { -not $_.IsReadOnly }
Negate boolean properties

Pipeline Techniques

$services = Get-Service | ? { $_.Status -eq 'Running' }
Store pipeline results in variable
... | Out-Null
Suppress all output (performance tip)
... | Out-GridView -PassThru
Interactive GUI selection that passes through
(Get-Process)[0]
Index into pipeline results
Get-Service | Select-Object -First 1 | Restart-Service -WhatIf
Test pipeline actions safely

Creating Custom Objects

[PSCustomObject]@{Name='John'; Age=30}
Create custom object (fastest method)
New-Object -TypeName PSObject -Property @{X=1; Y=2}
Legacy object creation
$obj = "" | Select-Object Name, Value
Create empty object with properties
1..10 | % { [PSCustomObject]@{ID=$_; Square=$_*$_} }
Generate array of custom objects

Advanced Patterns

Get-ChildItem | ? Extension -in '.txt', '.log'
Test if value in array
... | Select-Object -Skip 1 -First ([int]::MaxValue)
Skip headers/first items in pipeline
... | ForEach-Object { $_ } { } { 'Done' }
Begin, Process, End blocks syntax
Get-Process | Group-Object Company | Sort-Object Count -Descending
Chain grouping with sorting
🚀 PERFORMANCE TIP Filter early in the pipeline to reduce objects processed downstream

Common Patterns

Get-ChildItem -Recurse | ? { -not $_.PSIsContainer } | Sort-Object Length -Descending | Select-Object -First 10
Find 10 largest files recursively
Get-Process | Sort-Object WS -Descending | Select-Object -First 5 Name, @{n='MemMB'; e={[math]::Round($_.WS/1MB, 2)}}
Top 5 memory-consuming processes with formatting
Get-Service | Group-Object Status | Select-Object Name, Count
Count services by status
Import-Csv data.csv | % { [PSCustomObject]@{Name=$_.Name; Value=[int]$_.Value * 2}} | Export-Csv output.csv
Transform and re-export data

Pipeline Operators

Command1 | Command2
Standard pipeline (pass objects)
Command1 2>&1 | Command2
Merge error stream into success stream
Command1 && Command2
Chain commands (C2 runs only if C1 succeeds) [PS7+]
Command1 || Command2
Chain commands (C2 runs only if C1 fails) [PS7+]
$result = Get-Content file.txt | Out-String
Convert pipeline output to single string

Inspecting Objects

$obj | Get-Member -MemberType Method
Show available methods
$obj.GetType().FullName
Get full type name of object
$obj | ConvertTo-Json -Depth 3
Examine object structure as JSON
$obj.PSObject.Properties.Name
List all property names
$obj -is [System.IO.FileInfo]
Test if object is specific type

Real-World Examples

Get-EventLog -LogName System -Newest 100 |
? { $_.EntryType -eq 'Error' } |
Group-Object Source |
Sort-Object Count -Descending
Analyze error sources in event log
Get-ChildItem -Recurse *.log |
% { [PSCustomObject]@{
  File=$_.Name
  SizeMB=[math]::Round($_.Length/1MB, 2)
  Age=((Get-Date) - $_.LastWriteTime).Days
}} | Export-Csv log-report.csv
Create custom report from files
Get-Process |
? { $_.CPU -gt 10 } |
Sort-Object CPU -Descending |
Select-Object -First 20 Name, CPU, WS |
ConvertTo-Html | Out-File report.html
Complete pipeline: filter → sort → select → export