Skip to content

Instantly share code, notes, and snippets.

@romero126
Last active January 4, 2023 19:07
Show Gist options
  • Save romero126/9750c8fada843702c55aa6fc7a1ba4ca to your computer and use it in GitHub Desktop.
Save romero126/9750c8fada843702c55aa6fc7a1ba4ca to your computer and use it in GitHub Desktop.
1..20 | Invoke-ForEachObjectWithProgress -Process { Write-Host "$i : $_" -ForegroundColor Blue; start-sleep -Milliseconds 500 } -Begin { Write-Host "Begin" -ForeGroundColor DarkMagenta; $i = "Custom Command Value"; } -End { Write-Host "End" -ForeGroundColor DarkMagenta } -RemainingScripts { Write-Host "Remaining Scripts runs after Process" }
function Invoke-ForEachObjectWithProgress {
[CmdletBinding()]
[Alias("ForEachWP")]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[object] $InputObject,
[Parameter()]
[string] $Activity = "Processing items",
[Parameter()]
[string] $Status = "{0} of {1}",
[Parameter()]
[int] $ContinueAt,
[Parameter()]
[ScriptBlock] $Begin,
[Parameter(Mandatory, Position = 0)]
[ScriptBlock] $Process,
[Parameter()]
[ScriptBlock] $End,
[Parameter()]
[ScriptBlock] $RemainingScripts
)
begin {
$queue = [System.Collections.Generic.Queue[object]]::new()
}
process {
$null = $queue.Enqueue($InputObject)
}
end {
# Create Steppable Pipeline
$cmdlet = Get-Command Microsoft.PowerShell.Core\ForEach-Object
$cmdletParameters = @{}
foreach ($param in $PSBoundParameters.GetEnumerator()) {
if ($param.Key -in @("Begin", "Process", "End", "RemainingScripts")) {
$cmdletParameters[$param.Key] = $param.Value
}
}
$cmdletScriptBlock = { & $cmdlet @cmdletParameters }
$cmdletPipeline = $cmdletScriptBlock.GetSteppablePipeline()
# Progress Information
$progressPos = 0
$progressCount = $queue.Count
# Process input
$cmdletPipeline.Begin($true)
foreach ($item in $queue) {
# Calculate Status Message
$progressPos = $progressPos + 1
$progressPercent = (($progressPos / $progressCount) * 100)
$statusMessage = $Status -f $progressPos, $progressCount
if ($Resume -ne $null -and $Resume -gt $progressPos) {
continue
}
Write-Progress -Activity $Activity -Status $statusMessage -PercentComplete $progressPercent
$cmdletPipeline.Process($item)
}
#$queue.Dispose()
$cmdletPipeline.End()
$cmdletPipeline.Dispose()
}
}
@romero126
Copy link
Author

Invoke with

1..20 | Invoke-ForEachObjectWithProgress -Process { Write-Host "$i : $_" -ForegroundColor Blue; start-sleep -Milliseconds 500 } -Begin { Write-Host "Begin" -ForeGroundColor DarkMagenta; $i = "Custom Command Value"; } -End { Write-Host "End" -ForeGroundColor DarkMagenta } -RemainingScripts { Write-Host "Remaining Scripts runs after Process" }

Example Output
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment