src/Utilities/ForEach-ObjectWithProgress.ps1
<#
.SYNOPSIS Process each object and report progress .DESCRIPTION Performs custom action on given collection with progress information. .PARAMETER Collection Object collection to process. .PARAMETER OperationName Name of operation to display in progress bar. .PARAMETER Id Specifies an ID that distinguishes each progress bar from the others. Use this parameter when you are creating more than one progress bar in a single command. If the progress bars do not have different IDs, they are superimposed instead of being displayed in a series. .PARAMETER ParentId Specifies the parent activity of the current activity. Use the value -1 if the current activity has no parent activity. .PARAMETER ProgressStep Define progressbar refresh (Default = 1). Set to bigger value for perf improvements on large collections. .PARAMETER ScriptBlock Custom script to apply for each object. Current object is provided as script block parameter. .EXAMPLE $items = @("1", "2", "3", "4", "5"); ForEach-ObjectWithProgress -Collection $items -OperationName "Simply count items" -ScriptBlock { param($item) Start-Sleep -Seconds 1; Write-Host "Element : $item"; } #> function ForEach-ObjectWithProgress { [CmdletBinding()] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true)] [array] $Collection, [Parameter(Mandatory = $false)] [string] $OperationName = "Processing data...", [Parameter(Mandatory = $false)] [int] $Id = 0, [Parameter(Mandatory = $false)] [int] $ParentId = -1, [Parameter(Mandatory = $false)] [int] $ProgressStep = 1, [Parameter(Mandatory = $false)] [scriptblock] $ScriptBlock ) begin { $StopWatch = [System.Diagnostics.Stopwatch]::StartNew(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Start -Parameters ($MyInvocation.MyCommand.Parameters); } process { if (-not $Collection) { return; } $current = 0; $total = $Collection.Count; if ($total -eq 0) { return; } foreach ($item in $Collection) { $current++; $percent = ($current / $total) * 100; if($current % $ProgressStep -eq 0) { Write-Progress -Id $Id -ParentId $ParentId -Activity $OperationName -Status "Processing item $current of $total ($($percent.ToString('#.##')) %)..." -PercentComplete $percent; } if($item -is [Array]){ Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList (,$item); } else { Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList $item; } } } end { $StopWatch.Stop(); Trace-XrmFunction -Name $MyInvocation.MyCommand.Name -Stage Stop -StopWatch $StopWatch; Write-Progress -Activity $OperationName -Id $Id -Completed; } } Export-ModuleMember -Function ForEach-ObjectWithProgress -Alias *; |