When dealing with complex scripts with lots of running parts and that take some time to complete, it is convenient to have some sort of progress indicator to help visually indicate where a script is in a particular stage. In order to be successful we would need a count of how many items are being processed and what number in that list we are at. From there were can perform some simple math and then that can translate into our progress.
Where to get started? First we can see what cmdlets are available for progress in PowerShell:
[sourcecode language=”powershell”]
Get-Command *progress*
We find that there is only one cmdlet available for progress in PowerShell:<BR>
<em>Name
—-
Write-Progress</em><BR>
In PowerShell progress<BR>
Practical Examples of a Progress Bar<BR>
<em>Example 1</em><BR>
In this example we have a script that is performing a series of tasks. These tasks are responsible for gathering information on an environment. The environment could be anything from Exchange, Active Directory or Office 365. The point would be to concentrate on a series of tasks. Now in this script, we have
Sample Code (not a complete script):
[sourcecode language="powershell"]
# Variables
$Counter = 0
$Tasks = "Task 1","Task 2","Task 3","Task 4","Task 5","Task 6","Task 7","Task 8","Task 9","Task 10","Task 11","Task 12","Task 13","Task 14","Task 15"
Function Task1 {
# Gather AD Domain information
$ADDomains = (Get-ADForest).Domains | Out-file $Destination -Append
}
Function Task2 {
# Group Policy Check
$ScriptFile = "GPOCheck.ps1"
$Fullpath = ".\"+$ScriptFile
Invoke-Expression $FullPath
}
Foreach ($Task in $Tasks) {
$Counter ++
Write-Progress -Activity "Performing Tasks" -Status "In progress: $Task of 15"
$Task
}
[/sourcecode]
Note that when a task starts, the counter going up and we know we are on task number ## of 15. Each of these tasks is a separate function, which makes it easier for use to call and monitor the script progress:
This way if you have a long running script or there are tasks that take some time to run, you will at least know how far a script has progressed.
Example 2
For this example we’ll use the Write-Progress cmdlet to provide a percentage done instead of a overall number like Example 1. We can simply modify the Foreach loop to display a percentage instead of a task number like so:
[sourcecode language=”powershell”]
Foreach ($Task in $Tasks) {
$Counter ++
$Percent = $Counter/15
$I = [math]::Round($Percent,4)*100
Write-Progress -Activity "Performing Tasks" -Status "Task Progress: $I%" -Percent $I
$Task
}
[/sourcecode]
This will then provide a progress bar that looks like this instead:
Inner Loops
In addition to the main progress bars, there is also the option to run a progress bad for an inner loop if you use those. So, for example, if a function has some sub tasks that it runs, this progress bar can then relay where it is, while inside of the main running task.
Sample Code:
[sourcecode language=”powershell”]
Function Task2 {
$SubCounter = 0
$Subtasks = "SubTask 1","SubTask 2","SubTask 3","SubTask 4","SubTask 5"
Foreach ($SubTask in $Subtasks) {
$SubCounter ++
Write-Progress -Activity "Performing Tasks" -Status "In progress: $Task of 15"
Write-Progress -Id 1 -Activity "Performing SubTasks" -Status "In Progress: $SubTask of 10" -CurrentOperation InnerLoop
Start-Sleep 2
}
}
Foreach ($Task in $Tasks) {
$Counter ++
Write-Progress -Activity "Performing Tasks" -Status "In progress: $Task of 15"
Invoke-Expression $Task
}
[/sourcecode]
This would be useful if you have a complex level of tasks and functions. Having a visual clue as to how far the script has progress, even in the smaller tasks of a function, are useful.
Adding a Progress Bar
Categories: