PowerShell Administration Foundations
Learn what PowerShell is, how to start it, read cmdlet syntax, discover commands, use aliases, get help, and manage files and folders.
Content
Parsing Cmdlet Syntax
Versions:
Watch & Learn
AI-discovered learning video
Parsing Cmdlet Syntax Without Crying (PowerShell Edition)
"The syntax block in Get-Help isn’t a threat. It’s a contract." — someone who finally read it twice
You’ve already met cmdlets (Verb-Noun squad) and you know how to launch and gracefully Irish-exit PowerShell. Now we’re decoding the one thing that looks like it wants to fight you: the cmdlet syntax block. This is the Rosetta Stone of PowerShell. Learn to read it, and suddenly every cmdlet starts speaking human.
Step 1: Meet the Syntax Block (Without Panic)
Pop open a help page: Get-Help Get-Process -Full and scroll to SYNTAX. You’ll see something like:
Get-Process [[-Name] <string[]>] [-Id <int[]>] [-ComputerName <string[]>]
[-Module] [-FileVersionInfo] [-IncludeUserName] [-InputObject <Process[]>]
[<CommonParameters>]
Let’s translate this line by line. First, some grammar rules.
Syntax Symbols, De-coded
| Symbol | Meaning | Example |
|---|---|---|
[] |
Optional | [-Id <int[]>] means you can omit -Id |
<> |
Data type or placeholder | <string[]> means "array of strings" |
... |
Repeatable (less common in cmdlet syntax; array types often cover this) | Think -Name <string[]> = give one or many names |
| ` | ` | Choice/alternatives (you’ll see this in type names sometimes) |
{} |
Script block (actual PowerShell code) | Where-Object { $_.CPU -gt 100 } |
And a vibe check: parameters are case-insensitive and you can abbreviate as long as it’s unambiguous. -ErrorAction → -EA. PowerShell is chill like that.
Powerful rule: In syntax, square brackets mean "optional." In real life, nothing is optional—except pants when you’re remoting from home.
Step 2: Named vs Positional Parameters (a.k.a. Why "It Worked... Somehow")
Some parameters have positions so you can skip the name. In Get-Process, -Name is position 0.
- Positional:
Get-Process notepad, calc - Named:
Get-Process -Name notepad, calc
Both work. Use named parameters when:
- You’re scripting for humans (future-you is a human)
- You’re mixing multiple parameters
- The position isn’t obvious
Pro move: If your argument has spaces, quote it. Single quotes are literal; double quotes expand variables.
Get-ChildItem -Path 'C:\Program Files' -Recurse
$ext = 'log'
Get-ChildItem -Filter "*.${ext}"
Step 3: Switches and Booleans (The On/Off Buttons)
Parameters like -Recurse, -Force, -WhatIf are switches—present = true, absent = false.
- Turn a switch off explicitly:
-Recurse:$false(useful with splatting) - Use safety wheels:
-WhatIfsimulates,-Confirmprompts
Remove-Item -Path 'C:\Temp\*.log' -Recurse -Force -WhatIf
If
-WhatIfdoesn’t show exactly what you expect, your script doesn’t do what you think it does.
Step 4: Parameter Sets (Mutual Exclusivity, But Make It Friendly)
Some cmdlets have multiple valid "shapes" called parameter sets. They’re shown as separate syntax blocks. You can only use parameters from one set at a time.
Classic pattern: -Path vs -LiteralPath.
-Pathunderstands wildcards:Get-Item -Path 'C:\Temp\*.txt'-LiteralPathtreats characters literally:Get-Item -LiteralPath 'C:\Temp\[weird].txt'
Try to mix them and PowerShell gets judgy: "Parameter set cannot be resolved…"
Debug tip: Get-Help <CmdletName> -Full shows which set each parameter belongs to.
Step 5: Pipeline Binding — ByValue vs ByPropertyName
When you pipe objects, PowerShell tries to bind them to the next cmdlet’s parameters either:
- ByValue: the entire object matches the parameter type
- ByPropertyName: a property on the object matches the parameter name
Examples:
- ByValue: Stop services passed from
Get-Servicedirectly toStop-Service(because it acceptsServiceControllerobjects).
Get-Service | Where-Object Status -eq Running | Stop-Service -WhatIf
- ByPropertyName: Build objects with a
Nameproperty and feed them toGet-Process.
'notepad','calc' | ForEach-Object { [pscustomobject]@{ Name = $_ } } | Get-Process
If you piped raw strings ('notepad'), it wouldn’t bind to -Name because that’s ByPropertyName only for Get-Process. The string doesn’t have a Name property—so no go.
Pipeline rule: If it isn’t binding, check the parameter’s "Accept pipeline input?" metadata in help. It’s either ByValue, ByPropertyName, both, or nope.
Step 6: The Metadata Section of Help is Gold
Run: Get-Help Get-Process -Parameter Name and you’ll see fields like:
- Required? true/false
- Position? 0, 1, etc.
- Default value
- Accept pipeline input? ByValue/ByPropertyName
- Accept wildcard characters? true/false
These lines tell you how to shape your input without guesswork. Learn them. Love them.
Step 7: Common Parameters — The Hidden Superpowers
When you see [<CommonParameters>] in syntax, that means you automatically get:
-Verbose,-Debug-ErrorAction,-ErrorVariable-WarningAction,-WarningVariable-OutVariable,-OutBuffer-WhatIf,-Confirm(often available separately too)
Examples:
Get-Process -Name notepad -Verbose
Get-Item 'C:\Nope' -ErrorAction SilentlyContinue
Pro tip:
-EA 0does not exist. Use-EA SilentlyContinueor-EA Stop. They’re from theActionPreferenceenum.
Step 8: Quotes, Arrays, and Escaping
- Single quotes: literal. Double quotes: expand variables and subexpressions
$(...). - Arrays: comma-separate values. Many parameters accept arrays (
<type[]>).
Get-Process -Name 'svchost','spoolsv'
$items = 'A B','C D' # two items with spaces
Get-ChildItem -Path $items
Escape character is the backtick `. Use sparingly; prefer quoting correctly.
# Escaping a quote inside single quotes? Double the quote in double quotes.
Write-Output "He said, \"PowerShell slaps\""
Step 9: Splatting — When Your One-Liner Becomes a Paragraph
If your cmdlet call is getting long, pack parameters into a hashtable and "splat" it with @.
$params = @{
Path = 'C:\Temp\*.log'
Recurse = $true
Force = $true
ErrorAction = 'Stop'
}
Remove-Item @params -WhatIf
Benefits: readability, easy toggles (Recurse = $false), cleaner diffs.
Step 10: Abbreviations, Aliases, and Wildcards
- You can abbreviate parameter names:
-ErrorAction→-EA,-Verbose→-v. - Cmdlet names can have aliases (
gci→Get-ChildItem), but in scripts, prefer the real names. - If the parameter says "Accept wildcard characters? true", you can use
*and?.
Get-Service -Name 'win*'
Get-ChildItem -Filter *.ps1 -Recurse
Mini-Lab: Parse-and-Execute Like a Pro
Goal: Stop any process using > 100 seconds of CPU… but safely.
- Discover capabilities
Get-Help Get-Process -Full # Read syntax & parameters
Get-Help Stop-Process -Full # Check pipeline binding
- Compose pipeline harnessing ByValue and ByPropertyName
# Get top CPU hogs, extract unique names
$targets = Get-Process |
Where-Object { $_.CPU -gt 100 } |
Select-Object -ExpandProperty Name -Unique
# Build objects with a Name property (ByPropertyName binding)
$targets |
ForEach-Object { [pscustomobject]@{ Name = $_ } } |
Stop-Process -WhatIf -Confirm
- Confidence upgrade: see verbose output
Stop-Process -Name $targets -WhatIf -Verbose
Read the syntax, pick the right parameters, respect parameter sets, and use common parameters to stay safe. That’s the whole game.
Quick Recap (TL;DR But Useful)
- Square brackets
[]= optional; angle brackets<>= type/placeholder;{}= script block. - Named vs positional: name it if there’s any ambiguity or you like future-you.
- Switches are booleans you turn on by presence; use
-WhatIfand-Confirmlike seatbelts. - Parameter sets are mutually exclusive shapes; don’t mix across blocks.
- Pipeline binding is either ByValue (whole object) or ByPropertyName (matching property). Check help metadata.
- Common parameters are always available;
-Verbose,-ErrorAction, etc. - Splatting keeps long calls readable.
- Quotes matter: single = literal, double = expand. Arrays are comma-separated.
Final boss move: When a cmdlet feels confusing, don’t guess—parse the syntax and parameter metadata. PowerShell is not cryptic, it’s precise. Which is way better when you’re deleting things for a living.
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!