PowerShell: the terminal on Windows
Lesson 11 of 11
11PowerShell: the terminal on Windows
The big pictureMost company machines run Windows, and many developers start there. PowerShell gives you the terminal's power there and adds something bash lacks: data flows as objects.
What the picture shows: Each stage of the pipeline receives whole objects (name, size, date), not lines of text, so you filter and sort by property directly.
Map of this part
The concepts in order, click any one to jump to it:
Two ways into the same idea
In bash commands hand each other written sheets, and you cut out the word you need. In PowerShell they hand over tidy cards with fields: name, size, date. You say "give me the cards over 1 MB" without cutting any text.
PowerShell 7 (pwsh) is built on .NET and is cross-platform. Commands are cmdlets in an approved Verb-Noun form (Get-Verb), and the pipeline carries .NET objects you inspect with Get-Member. Filter with Where-Object { $_.Length -gt 1MB }, project with Select-Object, group with Group-Object. Compare with -eq -ne -gt -lt -like -match. The execution policy governs running .ps1 scripts, and modules install from the PowerShell Gallery with Install-Module.
Before You Start
🐚The shell and pipes
You know the pipe | idea from Linux.
🪟PowerShell 7
Install it from the Microsoft Store or with winget install Microsoft.PowerShell.
The Core Idea
1Verb-Noun: names that explain themselves
Every command is a verb-noun: Get-ChildItem (list contents), Set-Location (move), New-Item, Remove-Item. No need to memorise: Get-Command *Item* lists everything with Item in it, and Get-Help Get-ChildItem -Examples gives examples.
Get-Location # where am I (pwd) Set-Location C:\Projects # cd Get-ChildItem # ls / dir New-Item notes.txt -ItemType File # touch Get-Help Get-ChildItem -Examples
2The pipeline carries objects
Get-ChildItem does not print text; it returns file objects with Name, Length and LastWriteTime. Get-Member shows every property. So you filter and sort by name directly.
# the five biggest files over 1 MB in this folder and below
Get-ChildItem -Recurse -File |
Where-Object { $_.Length -gt 1MB } |
Sort-Object Length -Descending |
Select-Object -First 5 Name, @{n='MB'; e={[math]::Round($_.Length / 1MB, 1)}}3Linux equivalents
PowerShell defines familiar aliases (ls, cd, cat) pointing at its own commands, but the options differ. This table gets you there quickly:
Linux PowerShell ls -la Get-ChildItem -Force cat file.txt Get-Content file.txt grep "ERROR" app.log Select-String "ERROR" app.log find . -name "*.log" Get-ChildItem -Recurse -Filter *.log ps aux Get-Process kill 1234 Stop-Process -Id 1234 curl -I https://a.com Invoke-WebRequest https://a.com -Method Head export NAME=value $env:NAME = "value"
ls -la or rm -rf. The alias exists but the flags do not, so you get an error or different behaviour. Use the full PowerShell names in scripts.4.ps1 scripts and the execution policy
Save commands in a .ps1 file and run it with ./clean.ps1. Windows blocks scripts by default on some machines; Set-ExecutionPolicy -Scope CurrentUser RemoteSigned allows your local scripts only.
param([string]$Path = ".", [int]$Days = 30)
$old = Get-ChildItem $Path -Recurse -File -Filter *.log |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$Days) }
$old | Remove-Item -WhatIf # shows what would be deleted; drop -WhatIf to do it
"{0} old log files" -f $old.CountWorked example
Problem: a Windows app writes logs, and you want the number of error lines in each file from the last week. Solution: an object pipeline grouped by file:
Get-ChildItem C:\App\logs -Filter *.log | Where-Object LastWriteTime -gt (Get-Date).AddDays(-7) | Select-String -Pattern "ERROR" | Group-Object Filename | Sort-Object Count -Descending | Select-Object Name, Count
Myth vs Reality
| Myth | Reality |
|---|---|
| PowerShell is the old cmd prompt. | cmd is old and limited. PowerShell is a full language with objects and modules, and runs on Linux and macOS too. |
| If you learn Linux you do not need PowerShell. | Windows servers, Azure and company machines are often run with it. Knowing both makes you flexible. |
Test your understanding
What is the PowerShell equivalent of grep "ERROR" app.log?
Select-String searches for a pattern in text, like grep.
What makes the PowerShell pipeline different from bash?
That is why you write Where-Object Length -gt 1MB instead of cutting text columns.
How do you see what Remove-Item would delete before it does?
-WhatIf prints what would happen without doing it.
Quick review cards
Check Your Understanding
How do you discover a command whose name you do not know?
Get-Command *word* to search by name, then Get-Help the-command -Examples.
Why might ls -la fail in PowerShell?
ls is an alias for Get-ChildItem, which has no -la option. The equivalent is Get-ChildItem -Force.
What does Set-ExecutionPolicy -Scope CurrentUser RemoteSigned do?
It lets your local scripts run and requires a signature for scripts downloaded from the internet, for your user only.
Resources for this lesson
Grouped by type. Start with the official docs for precision, or an article or video for the explanation.
Done with this lesson?
Sign in to save your progress.