public/Show-Progress.ps1
|
<#
.SYNOPSIS Performs an operation against each item in a collection of input objects, with a progress bar. .INPUTS System.Management.Automation.PSObject to process. .FUNCTIONALITY PowerShell .EXAMPLE 1..10 |Show-Progress -Activity 'Processing' {"$_"} {Write-Host "item: $_"; sleep 2} Provides a progress indicator for a script block. .EXAMPLE 1..10 |Show-Progress |foreach {Write-Host "item: $_"; sleep 2} Same as previous example, but adds a progress indicator within an existing pipeline. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseProcessBlockForPipelineCommand','', Justification='This script uses $input within an End block.')] [CmdletBinding()] Param( # The progress title text to display. [Parameter(Position=0)][string] $Activity = 'Processing', # A script block to generate status text from each $PSItem ($_). [Parameter(Position=1)][scriptblock] $Status = {$_ |ConvertTo-Json -Compress}, # A script block to execute for each $PSItem ($_). [Parameter(Position=2)][scriptblock] $Process = {$_}, # An item to process. [Parameter(Mandatory=$true,ValueFromPipeline=$true)][psobject] $InputObject ) End { [psobject[]] $values = $input if(!$values) {$values = @($InputObject)} $i,$max,$id = 0,($values.Length/100),(Get-Random) foreach($value in $values) { [Collections.Generic.List[psvariable]] $ctx = New-Object PSVariable _,$value $itemstatus = $Status.InvokeWithContext($null,$ctx,$value) |Select-Object -First 1 if(!$itemstatus) {$itemstatus = '?'} Write-Progress $Activity $itemstatus -Id $id -PercentComplete ($i++/$max) [Collections.Generic.List[psvariable]] $ctx = New-Object PSVariable _,$value $Process.InvokeWithContext($null,$ctx,$value) } } |