I'm learning PowerShell and understand that a simple command like `$mySet | ForEach-Object { $_ }` outputs each item in the collection. Can the `{}` script block contain multiple statements and span several lines? For example, I'd like to update a running total while still outputting each number:
```powershell
$mySet = 1..5
[int]$total = 0
$mySet | ForEach-Object {
$total = $total + $_
$_
}
Write-Host "Total: $total"
```
Is this the correct way to perform multiple actions during each iteration?
4 Answers
For a running total, `ForEach-Object` also has `-Begin`, `-Process`, and `-End` script blocks. `-Begin` runs once before iteration, `-Process` runs for each item, and `-End` runs once afterward:
```powershell
$numbers = 1..5
$numbers | ForEach-Object -Begin {
$sum = 0
} -Process {
$sum += $_
$_
} -End {
"Total: $sum"
}
```
That prints the individual numbers and then the final total.
Yes. A script block can contain as many statements as you need, each on its own line. You can also separate statements with semicolons when writing everything on one line:
```powershell
$mySet | ForEach-Object {
$total += $_
$_
}
```
The value of `$_` is the current object being processed. Since the block outputs `$_`, each number is displayed, while `$total` accumulates the sum.
If you don’t need pipeline behavior, a regular `foreach` statement is often easier to read and can be more efficient in a script:
```powershell
$total = 0
foreach ($number in 1..5) {
$total += $number
$number
}
"Total: $total"
```
`ForEach-Object` is a pipeline cmdlet, while `foreach` is a language statement. They solve similar problems, but they aren’t interchangeable in every situation.
You can even store a group of statements in a script-block variable and reuse it:
```powershell
$action = {
$_
"Processed: $_"
}
1..5 | ForEach-Object $action
```
For the original case, though, simply placing each command on its own line inside the braces is all that’s required.

You can also use `Measure-Object -Sum` when you only need the aggregate value:
```powershell
1..5 | Measure-Object -Sum
```
For more complex per-item work, the multi-line `Process` block is usually clearer.