PowerShell Pipeline

The Moment I Understood Objects

I was helping a colleague who needed to find all files larger than 100MB on a file server to free up space. Coming from Linux, his first instinct was to reach for find, grep, and awk. I suggested PowerShell:

Get-ChildItem -Recurse | Where-Object {$_.Length -gt 100MB} | Sort-Object Length -Descending

He was skeptical. "But how do you know there's a Length property?" he asked. I showed him:

Get-ChildItem | Get-Member

His eyes widened as he saw the complete list of properties and methods available on file objects. No parsing strings with regular expressions. No splitting columns with awk. Just structured objects with accessible properties.

That's when he got it. PowerShell doesn't pass text between commands - it passes objects. And that changes everything.

What is the Pipeline?

The pipeline (|) is PowerShell's way of passing output from one cmdlet to another. But unlike Unix/Linux pipes that pass text streams, PowerShell pipes pass .NET objects.

Traditional Text-Based Pipes (Bash/Linux)

# Linux: text streams requiring parsing
ps aux | grep "python" | awk '{print $2, $11}'

You're working with text, so you need tools like grep, awk, sed to extract what you need.

PowerShell Object-Based Pipeline

# PowerShell: objects with properties
Get-Process | Where-Object {$_.Name -like "*python*"} | Select-Object Id, Name

You're working with process objects that have properties you can directly access. No parsing required.

How the Pipeline Works

When you pipe cmdlets together, the output of one becomes the input of the next:

Flow:

  1. Get-Process outputs process objects

  2. Sort-Object receives those objects, sorts by CPU property

  3. Select-Object receives sorted objects, takes first 10

  4. Final 10 objects displayed to screen

Visualizing Object Flow

Both approaches give the same result, but the pipeline is cleaner.

Pipeline Fundamentals

Basic Pipeline Syntax

Each command processes output from the previous command.

The Pipeline Variable: $_

Inside a pipeline, $_ represents the current object:

In PowerShell 7+, you can also use $PSItem instead of $_ (they're identical).

Getting to Know Objects: Get-Member

Before working with objects in the pipeline, discover their properties and methods:

I use Get-Member constantly when exploring new cmdlets or modules.

Essential Pipeline Cmdlets

Where-Object: Filtering

Filter objects based on conditions:

Select-Object: Choosing Properties

Select specific properties or limit results:

Calculated Properties

Create custom properties on the fly:

Sort-Object: Ordering

Sort objects by properties:

Measure-Object: Statistics

Calculate statistics on object properties:

Group-Object: Grouping

Group objects by property values:

Common Pipeline Patterns

Get → Filter → Select

The most common pattern:

Get → Filter → Sort → Select

Add sorting to the mix:

Get → Group → Select

Grouping and counting:

Get → Measure → Format

Statistics and display:

Real-World Pipeline Examples

Finding Large Files

When disk space was running low on a file server:

Found 2.5TB of old backup files nobody knew existed.

Analyzing Process Resource Usage

Troubleshooting performance issues:

Checking Service Status

Monitoring critical services across servers:

If any critical service isn't running, it shows up immediately.

File Organization Report

Understanding directory structure:

Shows file types and space consumption - invaluable for cleanup planning.

Pipeline Performance Considerations

ForEach-Object vs foreach Loop

Pipeline approach (slower but more convenient):

Loop approach (faster for large datasets):

For small datasets (< 1000 items), use pipeline for readability. For large datasets, use loops for performance.

Early Filtering

Filter as early as possible:

Avoid Format-* in Pipeline

Format cmdlets (Format-Table, Format-List) convert objects to formatting instructions. Don't use them mid-pipeline:

Common Pitfalls

1. Using Format-* Too Early

Problem: Get-Process | Format-Table | Export-Csv fails Solution: Format cmdlets should always be last:

2. Forgetting to Use Get-Member

Problem: Guessing property names incorrectly Solution: Always check with Get-Member first:

3. Inefficient Filtering

Problem: Filtering after retrieving all data Solution: Filter during data retrieval when possible

4. Breaking the Pipeline

Problem: Trying to use pipeline output incorrectly Solution: Understand what each cmdlet outputs:

Key Takeaways

  • PowerShell pipes objects, not text - this is fundamental

  • $_ represents the current object in the pipeline

  • Get-Member reveals properties and methods available

  • Common pattern: Get → Filter → Sort → Select

  • Filter early for better performance

  • Format cmdlets should always be last in the pipeline

  • Calculated properties create custom fields on the fly

  • Pipeline is readable - each step is clear and purposeful

What You've Learned

✅ How PowerShell's object-based pipeline differs from text pipes ✅ Using $_ to reference current pipeline objects ✅ Essential pipeline cmdlets: Where, Select, Sort, Measure, Group ✅ Common pipeline patterns for filtering and transforming data ✅ Real-world pipeline examples for practical tasks ✅ Performance considerations for large datasets ✅ Avoiding common pipeline pitfalls

Next Steps

Now that you master the pipeline, you're ready to work with PowerShell objects in depth. In Working with PowerShell Objects, you'll learn:

  • Deep dive into object properties and methods

  • Advanced filtering techniques

  • Object manipulation and transformation

  • Working with complex nested objects

  • Custom object creation

Understanding objects is key to PowerShell mastery - let's go deeper.


Ready to master objects? Continue to Working with PowerShell Objects

Last updated