Script Blocks
Prerequisites: Functions
A script block — code in braces — is a value you can store, pass
around, and run later. You've already used them with Where-Object and
ForEach-Object.
$double = { param($x) $x * 2 }
& $double 21
$double.Invoke(5)
$operations = @{
Add = { param($a, $b) $a + $b }
Multiply = { param($a, $b) $a * $b }
}
& $operations.Multiply 6 7
42
10
42
&(the call operator) runs a script block (or a command whose name is in a variable).- Script blocks can take
param()like functions — they're anonymous functions.
Passing behavior to a function
function Invoke-WithRetry {
param(
[scriptblock]$Action,
[int]$MaxAttempts = 3
)
for ($i = 1; $i -le $MaxAttempts; $i++) {
try {
return & $Action
} catch {
Write-Output "Attempt $i failed: $($_.Exception.Message)"
}
}
throw "All $MaxAttempts attempts failed"
}
$script:calls = 0
Invoke-WithRetry -Action {
$script:calls++
if ($script:calls -lt 3) { throw 'service unavailable' }
'Success on call 3'
}
Attempt 1 failed: service unavailable
Attempt 2 failed: service unavailable
Success on call 3
The retry logic is written once; what to retry is passed in.
Measuring time
Measure-Command { ... } runs a script block and returns how long it
took — handy for comparing approaches:
# illustrative
(Measure-Command { 1..100000 | ForEach-Object { $_ } }).TotalMilliseconds
(Measure-Command { foreach ($i in 1..100000) { $i } }).TotalMilliseconds
412.8
18.3