Verb-Noun: PowerShell’s naming convention
Every PowerShell cmdlet follows the same pattern: Verb-Noun. Get-Process gets processes, Get-Service gets services, Stop-Process stops a process, Set-Location sets your location. Once you know this, you can often guess a cmdlet’s name correctly before ever looking it up, and when you can’t, PowerShell documents itself:
Get-Command -Verb Get -Noun Process*
Get-Help Get-Process -Examples
Get-Command searches for cmdlets by verb or noun pattern; Get-Help prints a cmdlet’s built-in manual, including usage examples, entirely offline. There is no Linux equivalent quite this consistent: man pages exist, but command names themselves (grep, awk, ls) don’t follow a predictable, guessable pattern the way Verb-Noun does.
The pipeline: objects, not text
This is the single biggest conceptual difference from the Linux shell you already know. A Linux pipe (|) passes plain text from one command to the next; the receiving command has to parse that text back apart to do anything useful with it, which is exactly why tools like grep, awk, and cut exist, to slice text apart again. PowerShell’s pipe also uses |, but it passes whole objects, structured data with named properties, not flattened text. The receiving cmdlet can reach directly into those properties by name, no re-parsing required.
See it directly:
Get-Process | Get-Member
Get-Member inspects whatever just came through the pipeline and lists every property and method it has. You’ll see properties like Id, ProcessName, CPU, and WorkingSet (memory usage). Because those are real properties, not just columns in printed text, you can filter and sort on them directly:
Get-Process | Where-Object { $_.WorkingSet -gt 100MB } | Sort-Object WorkingSet -Descending | Select-Object -First 5 ProcessName, WorkingSet
Read this left to right the way you’d read a Linux pipeline: Get-Process gets every running process, Where-Object keeps only the ones using more than 100MB of memory, Sort-Object orders what’s left by memory usage, and Select-Object -First 5 keeps just the top five, showing only the two properties you asked for. $_ refers to “the current object in the pipeline,” the PowerShell equivalent of a loop variable. Every step worked with real memory numbers and real process names as data, not as text that had to be sliced apart first.
A few everyday cmdlets
Get-Process # what's running right now (like Linux's ps)
Get-Service # background services and their status
Get-Content .\practice.txt # read a file's contents (like cat)
Get-ChildItem -Recurse # list files recursively (like find, roughly)
Try piping Get-Service through a filter to find anything not running that should be:
Get-Service | Where-Object { $_.Status -eq 'Stopped' } | Select-Object -First 10 Name, Status
Execution policy, and why PowerShell draws attention from attackers
PowerShell has an execution policy, a setting controlling whether scripts (.ps1 files) are allowed to run at all, separate from running commands interactively. Check yours:
Get-ExecutionPolicy
A typical default is RemoteSigned (local scripts run freely, downloaded scripts must be digitally signed) or more restrictive. This exists for a defensive reason worth understanding properly: PowerShell is extraordinarily powerful, it can touch the file system, the registry, the network, and other processes, all from a single interpreted command, without ever writing a traditional .exe file to disk. That combination, powerful and often invisible to antivirus tools looking for suspicious files, is exactly why attackers favor PowerShell for “fileless” malware: a single obfuscated or base64-encoded one-liner, often launched with a flag like -EncodedCommand or -WindowStyle Hidden, can download and run further malicious code entirely in memory.
This is also why defenders don’t treat “PowerShell ran” as routine: modern Windows logs PowerShell activity in detail (PowerShell’s own Script Block Logging, separate from the Event Viewer work in the next lesson), specifically because so much real attacker activity on a Windows box runs through it. Knowing the shell this well is exactly what lets you recognize when something run through it looks wrong.
What to notice
- PowerShell’s pipeline passes structured objects, not text, which is why
Where-ObjectandSort-Objectcan filter and sort on real properties directly instead of needing a separate text-parsing tool. Get-HelpandGet-Commandmake PowerShell self-documenting offline; lean on them instead of guessing.- A long, encoded, or obfuscated PowerShell command line is one of the most common signatures of fileless malware, and it’s exactly the kind of command line Event Viewer and PowerShell logging exist to capture.