The pattern
terminal / powershell
$i = 0; $bytes = 0L
Get-ChildItem $Path -Recurse -File -Force -ErrorAction SilentlyContinue | ForEach-Object {
$i++; $bytes += $_.Length
if (($i % 512) -eq 0) { Write-Progress -Activity 'Scanning' -Status "$i files, $([math]::Round($bytes/1MB)) MB" }
# …per-file work…
}Why modulo-beats-time tick
- Item-count beats wall-clock: printing on elapsed interval can lag minutes on slow disks; every 512 files guarantees the user sees movement exactly at the rate data moves.
- Write-Progress is free: native progress host rendering, no console churn, automatic disappearing on completion.
- Cease politicking: rethrow-not-swallow — this loop is
ErrorAction SilentlyContinuebecause per-file locks are expected; that's still documentably different fromtry{}catch{}around the whole tree.
For library-grade work use IProgress<T> with SynchronizationContext marshaling for UIs; for scripts the modulo heartbeat covers 95% of the value at 5% of the machinery.