The best of PowerShell 7
Write modern PowerShell with ternaries, null operators, pipeline chains, -Parallel and friendlier errors.
- Use the ternary, null-coalescing and null-conditional operators
- Chain commands with && and ||, and run work in parallel with ForEach-Object -Parallel
- Use PowerShell 7 conveniences: Get-Error, -AsArray, Join-String, $IsWindows and more
PowerShell 7 added a run of small features that make scripts shorter and clearer. This lesson’s examples are not runnable in the browser - the runner here is PowerShell 6.2 - so open pwsh on your own machine and try each one. (Every output shown was checked against PowerShell 7.)
| Feature | Example | Since |
|---|---|---|
| Ternary operator | $big ? 'barn' : 'cottage' | 7.0 |
| Null-coalescing | $nickname ?? 'no nickname' | 7.0 |
| Null-coalescing assignment | $config ??= @{} | 7.0 |
| Null-conditional member access | ${dragon}?.Name | 7.1 |
| Pipeline chain operators | Test-Path $f && Remove-Item $f | 7.0 |
ForEach-Object -Parallel | 1..10 | ForEach-Object -Parallel { ... } | 7.0 |
Get-Error | a detailed view of the last error | 7.0 |
ConvertTo-Json -AsArray | always produce a JSON array | 7.0 |
$PSStyle | colors and formatting in the console | 7.2 |
Ternaries and null operators
1$wingspan = 12
2$wingspan -ge 10 ? 'needs the big barn' : 'fits the cottage'
3$nickname = $null
4$nickname ?? 'no nickname'
5$settings = $null
6$settings ??= @{ Theme = 'ember' }
7$settings.Theme
8$dragon = $null
9"[$(${dragon}?.Name)]"
10$dragon = [pscustomobject]@{ Name = 'Skyla' }
11${dragon}?.Nameneeds the big barn no nickname ember [] Skyla
condition ? a : breplaces a four-lineif/elsewhen you just need a value.$x ?? defaultgives$xunless it’s$null. Unlikeif ($x), an empty string or 0 still counts as a value.$x ??= valueassigns only when$xis$null- lazy initialization in one line.${x}?.Propertygives$nullinstead of an error when$xis$null(and the braces are required, because?is a legal character in variable names).
Pipeline chains: && and ||
a && b runs b only if a succeeded; a || b runs b only if a failed. Success means $? was true - for native programs, an exit code of 0. They make build-and-deploy one-liners read like Bash:
Write-Output 'fed Ember' && Write-Output 'then fed Glim'
Get-Item 'no-such-dragon.txt' 2>$null || Write-Output 'no file, so fall back'
Get-Item 'no-such-dragon.txt' 2>$null && Write-Output 'never printed'fed Ember then fed Glim no file, so fall back
Parallel processing
ForEach-Object -Parallel runs the script block for several items at the same time in separate threads. Results arrive in whatever order they finish, so sort them if order matters. Outside variables need $using:.
1$multiplier = 7
2$readings = 'volcano', 'lagoon', 'tower' | ForEach-Object -Parallel {
3 Start-Sleep -Milliseconds 200
4 '{0}: {1}' -f $_, ($_.Length * $using:multiplier)
5} -ThrottleLimit 3
6$readings | Sort-Objectlagoon: 42 tower: 35 volcano: 49
Smaller conveniences
1'Ember', 'Glim', 'Skyla' | Join-String -Separator ', ' -OutputPrefix 'Dragons: '
2[pscustomobject]@{ Name = 'Glim' } | ConvertTo-Json -AsArray -Compress
3$parsed = '{"name":"Vesper","meals":3}' | ConvertFrom-Json -AsHashtable
4$parsed['meals'] + 1
5$IsWindows -or $IsLinux -or $IsMacOS
6'{"name":"Pebble"}' | Test-JsonDragons: Ember, Glim, Skyla
[{"Name":"Glim"}]
4
True
TrueKey takeaways
Ternary
? :,??,??=and${x}?.Propshorten everyday checks (7.0+,?.7.1+).&&and||chain commands on success or failure, Bash-style.ForEach-Object -Parallelruns work concurrently; use$using:and sort the results.Join-String, -AsArray, -AsHashtable, Test-Json, Get-Error and $IsWindows are small but handy - and
#Requires -Version 7documents the dependency.
Lesson quiz
7 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…