Skip to content

Instantly share code, notes, and snippets.

@dancing-groot
Last active October 8, 2025 22:49
Show Gist options
  • Select an option

  • Save dancing-groot/b6b381c48e98409b70cb84c810893b2e to your computer and use it in GitHub Desktop.

Select an option

Save dancing-groot/b6b381c48e98409b70cb84c810893b2e to your computer and use it in GitHub Desktop.
Generic function for using progress bars - based on https://adamtheautomator.com/write-progress/
#region FUNCTIONS
function New-ProgressHelper
{
<#
.SYNOPSIS
Create variables for a progress bar
.LINK
https://gist.github.com/dancing-groot/b6b381c48e98409b70cb84c810893b2e
.NOTES
Version: 2025.10.08
Author: @dancing-groot
#>
[CmdletBinding()]
param (
[int]$Id = 0,
[int]$ParentId = -1,
[Parameter(Mandatory)][string]$Activity,
[Parameter(Mandatory)][int]$TotalSteps
)
$newProgressHelper = @{
Activity = $Activity
Id = $Id
ParentId = $ParentId
TotalSteps = $TotalSteps
StepNumber = 0
}
return $newProgressHelper
} # New-ProgressHelper
function Write-ProgressHelper
{
<#
.SYNOPSIS
Generic function for using progress bars
.LINK
https://gist.github.com/dancing-groot/b6b381c48e98409b70cb84c810893b2e
.NOTES
Version: 2025.10.08
Author: @dancing-groot
#>
[CmdletBinding(DefaultParameterSetName = 'Running')]
param (
[Parameter(ParameterSetName = 'Running')][Parameter(ParameterSetName = 'Finished')][int]$Id = 0,
[Parameter(ParameterSetName = 'Running')][Parameter(ParameterSetName = 'Finished')][int]$ParentId = -1,
[Parameter(Mandatory, ParameterSetName = 'Running')][Parameter(Mandatory,ParameterSetName = 'Finished')][string]$Activity,
[Parameter(Mandatory, ParameterSetName = 'Running')][Parameter(ParameterSetName = 'Finished')][string]$Status,
[Parameter(Mandatory, ParameterSetName = 'Running')][Parameter(ParameterSetName = 'Finished')][int]$StepNumber,
[Parameter(Mandatory, ParameterSetName = 'Running')][Parameter(ParameterSetName = 'Finished')][int]$TotalSteps,
[Parameter(Mandatory, ParameterSetName = 'Finished')][switch]$Completed
)
switch ($PSCmdlet.ParameterSetName)
{
'Running' { Write-Progress -Activity $Activity -Status $Status -Id $Id -ParentId $ParentId -PercentComplete (($StepNumber / $TotalSteps) * 100); break }
'Finished' { Write-Progress -Activity $Activity -Id $Id -Completed; break }
}
} # Write-ProgressHelper
#endregion FUNCTIONS
#region MAIN
#region EXAMPLE1
Write-Host "EXAMPLE 1 - If you only need one progress bar in your script" -ForegroundColor Green
# Declare variables for example 1 progress bar
$Folder = "C:\Program Files\Common Files"
$Foo = Get-ChildItem -Path $Folder -Directory
$ProgressHelperFolder = New-ProgressHelper -Activity "List Folders in '$Folder'" -TotalSteps $Foo.Count
# Run example 1
Write-ProgressHelper @ProgressHelperFolder -Status "Starting..."
foreach ($Bar in $Foo)
{
$ProgressHelperFolder.StepNumber = $ProgressHelperFolder.StepNumber + 1
Write-ProgressHelper @ProgressHelperFolder -Status $Bar.Name
Write-Host $Bar.Name
Start-Sleep -Milliseconds 250
}
Write-ProgressHelper @ProgressHelperFolder -Completed
Write-Host "EXAMPLE 1 COMPLETED."
Start-Sleep 3
#endregion EXAMPLE1
#region EXAMPLE2
Write-Host "EXAMPLE 2 - If you need to run a progress bar using a different iteration" -ForegroundColor Green
# Declare variables for example 2 progress bar
$CustomProgressTotalSteps = 10
$ProgressHelperCustom = New-ProgressHelper -Activity "Counting from 1 to $CustomProgressTotalSteps" -TotalSteps $CustomProgressTotalSteps
# Run example 2
for ($i = 1; $i -le $CustomProgressTotalSteps; $i++)
{
$ProgressHelperCustom.StepNumber = $i
Write-ProgressHelper @ProgressHelperCustom -Status "$i/$CustomProgressTotalSteps"
Write-Host $i
Start-Sleep 1
}
Write-ProgressHelper @ProgressHelperCustom -Completed
Write-Host "EXAMPLE 2 COMPLETED."
Start-Sleep 3
#endregion EXAMPLE2
#region EXAMPLE3
Write-Host "EXAMPLE 3 - If you need to run nested progress bars" -ForegroundColor Green
# Declare variables for example 1 progress bar
$ParentFolder = "C:\Program Files\Common Files"
$Parent = Get-ChildItem -Path $ParentFolder -Directory
$ProgressHelperParentFolder = New-ProgressHelper -Activity "List Folders in '$ParentFolder'" -TotalSteps $Parent.Count
# Run example 3
if ($Parent.Count -eq 0)
{
Write-Host "No folders found in '$ParentFolder'." -ForegroundColor Yellow
return
}
Write-ProgressHelper @ProgressHelperParentFolder -Status "Starting..."
foreach ($ChildOfParent in $Parent)
{
$ProgressHelperParentFolder.StepNumber = $ProgressHelperParentFolder.StepNumber + 1
Write-ProgressHelper @ProgressHelperParentFolder -Status $ChildOfParent.Name
Write-Host $ChildOfParent.Name
# Process child folder
$ChildFolder = "C:\Program Files\Common Files\$($ChildOfParent.Name)"
$Child = Get-ChildItem -Path $ChildFolder -Directory
$ProgressHelperChildFolder = New-ProgressHelper -Id 1 -ParentId 0 -Activity "-> List Folders in '$ChildFolder'" -TotalSteps $Child.Count
if ($Child.Count -eq 0)
{
Write-Host "No folders found in '$ChildFolder'." -ForegroundColor Yellow
}
else
{
Write-ProgressHelper @ProgressHelperChildFolder -Status "Starting..."
foreach ($ChildOfChild in $Child)
{
$ProgressHelperChildFolder.StepNumber = $ProgressHelperChildFolder.StepNumber + 1
Write-ProgressHelper @ProgressHelperChildFolder -Status $ChildOfChild.Name
Write-Host "`t\$($ChildOfChild.Name)"
Start-Sleep -Milliseconds 250
}
Write-ProgressHelper @ProgressHelperChildFolder -Completed
Start-Sleep -Milliseconds 250
}
}
Write-ProgressHelper @ProgressHelperParentFolder -Completed
Write-Host "EXAMPLE 3 COMPLETED."
#endregion EXAMPLE3
#endregion MAIN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment