BeginnerLesson 2 of 16

Cmdlets, Syntax, and the Pipeline

Master the building blocks of PowerShell: how cmdlets are structured, how parameters work, why the object pipeline is powerful, and which pipeline utility cmdlets you will use every day.

🧒 Simple Explanation (ELI5)

A cmdlet is like a power tool with a specific job: a drill drills, a saw cuts, a hammer pounds. The pipeline is like a conveyor belt connecting tools: one tool finishes its job and passes the result directly to the next. In PowerShell, instead of making a separate trip back to the workbench between every tool, you connect them with a pipe (|) and the work flows straight through.

🔧 Why Do We Need It?

🌍 Real-world Analogy

An assembly line in a factory: each station takes the car from the previous station, does its specific job, and passes it to the next. No station needs to know the full process. PowerShell's pipeline works the same way. Each cmdlet receives objects, applies its operation, and sends results downstream.

⚙️ Technical Explanation

A cmdlet is a compiled .NET class. Every cmdlet follows Verb-Noun: the verb describes the action (Get, Set, New, Remove, Start, Stop, Invoke, Export, Import, Test, Wait) and the noun describes the target (Service, Process, Item, Content, AzResourceGroup).

Parameters are named arguments prefixed with a hyphen: -Path, -Name, -Recurse, -Force, -ErrorAction. Positional parameters allow omitting the name for common arguments. Switch parameters are boolean on/off flags: -Recurse, -Force, -Verbose, -Debug, -WhatIf, -Confirm.

The pipeline | passes the complete object output from the left cmdlet as input to the right cmdlet. The automatic variable $_ (or $PSItem) refers to the current object being processed in pipeline expressions.

⚠️
Always Use -WhatIf Before Destructive Commands

Before running any command that deletes, stops, or modifies things, add -WhatIf first. It prints exactly what would happen without actually doing it. Remove-Item -Path C:\Logs\* -Recurse -WhatIf shows every file that would be deleted. Once you are confident, remove -WhatIf to execute. This habit prevents catastrophic mistakes in production.

🔍
Explore Object Properties with Get-Member

After any pipeline cmdlet, add | Get-Member to see every property and method available. Get-Process | Get-Member -MemberType Property shows all properties you can filter and sort on. This is how you discover that process objects have WorkingSet64, CPU, StartTime, and more—without reading documentation every time.

📊 Visual Representation

Pipeline: Object Flow Through Cmdlets
Get-Process
→ [Process[]]
Where-Object
→ [filtered]
Sort-Object
→ [sorted]
Select-Object
→ [slim objects]
Export-Csv

⌨️ Commands / Syntax

powershell
# Cmdlet with named parameters
Get-Service -Name "wuauserv" -ComputerName localhost

# Pipeline: filter, sort, select
Get-Process |
  Where-Object { $_.CPU -gt 5 } |
  Sort-Object CPU -Descending |
  Select-Object Name, Id, CPU

# Explore object properties
Get-Process | Get-Member -MemberType Property

# Count results
Get-Service | Where-Object Status -eq Running | Measure-Object

# Export to CSV file
Get-Service |
  Select-Object Name, Status, StartType |
  Export-Csv -Path services.csv -NoTypeInformation

# Preview destructive operations with -WhatIf
Remove-Item -Path C:\Temp\*.log -Recurse -WhatIf

# ForEach-Object to run code per object
Get-Service | Where-Object Status -eq Stopped | ForEach-Object {
    Write-Host "Stopped service: $($_.Name)"
}

# Aliases (avoid in scripts, useful at command line)
# gps    = Get-Process
# gsv    = Get-Service
# ls/dir = Get-ChildItem

💼 Example (Real-world Use Case)

A security engineer needs a list of all Windows services running as LocalSystem on a server: Get-CimInstance Win32_Service | Where-Object StartName -eq 'LocalSystem' | Select-Object Name, StartMode, State | Sort-Object Name | Export-Csv -Path local-system-services.csv -NoTypeInformation. This one pipeline generates an audit-ready report without any custom tooling or text parsing.

🧪 Hands-on

  1. Count stopped services: Get-Service | Where-Object Status -eq Stopped | Measure-Object.
  2. Group processes by company: Get-Process | Group-Object Company | Sort-Object Count -Descending | Select-Object -First 5.
  3. See the last 10 System events: Get-EventLog -LogName System -Newest 10 | Select-Object TimeGenerated, EntryType, Source.
  4. Explore process properties: Get-Process | Get-Member -MemberType Property | Select-Object Name.
  5. Preview deleting temp files: Get-ChildItem -Path $env:TEMP -Filter *.tmp | Remove-Item -WhatIf.
🎮
Try It Yourself

Build a one-liner that finds all services that are stopped AND set to Automatic start (services that should be running but are not): Get-Service | Where-Object { $_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic' } | Select-Object Name, DisplayName | Sort-Object Name. This is a real health-check pattern that sysadmins run after reboots.

🐛 Debugging Scenario

Problem: you run a pipeline and it silently skips some objects without error—output count is lower than expected.

🎯 Interview Questions

Beginner

What is a cmdlet?

A cmdlet is a compiled .NET class that performs a single, specific operation. It follows the Verb-Noun naming convention (Get-Process, Stop-Service) and can be composed with other cmdlets via the pipeline.

What does the PowerShell pipeline (|) do?

It passes the .NET object output from one cmdlet as input to the next cmdlet. This is different from Bash where the pipe passes text; PowerShell preserves the full object structure, so the receiving cmdlet can access typed properties.

What does $_ represent in a pipeline?

$_ (or $PSItem) is the current object being processed in a pipeline expression. In Where-Object { $_.CPU -gt 5 }, $_ refers to each Process object as it flows through the filter.

What is the -WhatIf parameter?

-WhatIf is a safety parameter supported by most commands that modify state. It previews what the command would do without executing it. Always use -WhatIf before running Remove-Item, Stop-Service, or any state-changing operation in production.

How do you export pipeline results to a CSV?

Pipe to Export-Csv -Path output.csv -NoTypeInformation. The -NoTypeInformation parameter omits the .NET type header row that would otherwise appear at the top of the file.

Intermediate

How is PowerShell's pipeline different from Unix/Bash pipes?

Bash passes text streams between processes. PowerShell passes .NET objects with typed properties between cmdlets. This means no text parsing—you access properties directly like $_.CPU or $_.Status instead of using cut, awk, or grep.

When would you use ForEach-Object instead of a foreach loop?

ForEach-Object works inline in a pipeline and processes objects one at a time as they arrive (streaming). A foreach loop requires the entire collection in memory first. For large datasets piped from cmdlets, ForEach-Object is more memory-efficient.

What is the difference between Select-Object and Format-Table?

Select-Object outputs slimmed-down objects you can continue piping. Format-Table outputs formatted display strings for human reading—you cannot pipe Format-Table output to Export-Csv. Always use Select-Object when you need to process results further; use Format-Table only for final display at the console.

What cmdlets do you use to count, sum, and average pipeline results?

Measure-Object with -Count, -Sum, -Average, -Minimum, and -Maximum parameters. Example: Get-Process | Measure-Object CPU -Sum -Average returns total and average CPU across all processes.

What is pipeline binding and how does PowerShell decide which parameter accepts it?

Pipeline binding is the automatic passing of pipeline output to a receiving cmdlet's parameter. Parameters accept pipeline input if they are marked ValueFromPipeline or ValueFromPipelineByPropertyName in their definition. You can see this with Get-Help cmdlet -Full, looking at the parameter Accept pipeline input? field.

Scenario-based

Write a one-liner to find all services stopped and set to Automatic start.

Get-Service | Where-Object { $_.Status -eq 'Stopped' -and $_.StartType -eq 'Automatic' } | Select-Object Name, DisplayName | Sort-Object Name. This is a standard health-check script that runs after Windows server reboots to surface services that should have started but did not.

A pipeline processes 10,000 files but fails silently partway through. How do you diagnose it?

Set $ErrorActionPreference = 'Stop' to make all errors terminating, or add -ErrorAction Stop to each cmdlet. Check $Error[0] after the pipeline. Add -Verbose to see per-item progress. Use a try/catch wrapper around the pipeline to capture and log failures with full context.

Your manager wants a CSV of all Windows services within 30 minutes. How do you build it?

Get-Service | Select-Object Name, DisplayName, Status, StartType | Sort-Object Name | Export-Csv -Path services-$(Get-Date -Format yyyyMMdd).csv -NoTypeInformation. Running this on multiple machines adds -ComputerName or uses Invoke-Command for remoting.

🌐 Real-world Usage

Operations engineers build pipeline one-liners for daily health checks: running services, disk space, failed events, stopped critical services. Security teams build audit pipelines for user access, service accounts, and open firewall rules. These pipelines feed Executive dashboards and compliance reports via Export-Csv or ConvertTo-Json.

📝 Summary

Cmdlets follow Verb-Noun, accept named parameters, and support -WhatIf for safe previewing. The pipeline passes typed .NET objects, not text. Core pipeline tools are Where-Object (filter), Sort-Object (sort), Select-Object (project), Measure-Object (aggregate), ForEach-Object (iterate), and Export-Csv (persist). Use Get-Member to discover object properties. Never use Format-* cmdlets inside a pipeline where you need the data downstream.