A set of PowerShell functions to be used as timers and countdown tools.
This module is available from the PowerShell Gallery and should install in Windows PowerShell 5.1 and PowerShell 7.
Install-PSResource PSTimersInstalling the module will also install the
Microsoft.PowerShell.ThreadJobmodule if it isn't already installed. If you attempt to install the module withInstall-Moduleand you have the legacyThreadJobmodule installed, you might get a warning message. If this happens, runInstall-Module PSTimers -AllowClobber. This error doesn't seem to happen when usingInstall-PSResource.
The commands should also work on PowerShell 7 cross-platform except for those that utilize WPF. It is recommended that you run PowerShell 7.2 or later on non-Windows systems. This module incorporates commands from a previous module that creates simple timer objects.
| Name | Alias | Synopsis |
|---|---|---|
| Export-MyTimer | Export a timer object to an XML file. | |
| Get-HistoryRuntime | ghr | Get a history runtime object. |
| Get-MyTimer | Get the current status of a simple timer. | |
| Import-MyTimer | Import a timer variable from an XML file. | |
| Remove-MyTimer | Remove a MyTimer object. | |
| Reset-MyTimer | Reset a MyTimer object. | |
| Restart-MyTimer | Restart a MyTimer object. | |
| Resume-MyTimer | Resume a paused MyTimer object. | |
| Set-MyTimer | Modify a MyTimer object. | |
| Start-MyTimer | ton | Start a simple timer. |
| Start-PSCountdown | spsc | Start a graphical countdown display using Write-Progress. |
| Start-PSCountdownTimer | Start a WPF-based countdown timer. | |
| Start-PSTimer | spst | Initiates a countdown before running a command. |
| Start-PSCountdownTitle | TitleCountdown | Start a countdown timer in the console title. |
| Stop-MyTimer | toff | Stop your simple timer. |
| Stop-PSCountdownTimer | Stop a Countdown Timer. | |
| Suspend-MyTimer | Pause-MyTimer | Pause a MyTimer object. |
PowerShell 7 will display how long a command took to complete when using Get-History. Get-HistoryRuntime will provide the same functionality in Windows PowerShell. By default, it gets the runtime of the last history item.
PS C:\> $s = dir c:\scripts
PS C:\> Get-HistoryRuntime
ID RunTime
-- -------
292 00:00:00.2392380The command has an alias of ghr and you can specify any history item.
PS C:\> ghr 295 -Detail
ID RunTime Status Command
-- ------- ------ -------
295 00:00:07.7998983 Completed get-winevent system -MaxEvents 1000π The MyTimer class and related commands have been heavily revised and extended. There are several breaking changes from previous versions of this module. It is recommended that you clear existing timers before upgrading and using this version of the module.
The MyTimer object is defined in a private PowerShell class.
TypeName: MyTimer
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetCurrentTimer Method MyTimer GetCurrentTimer()
GetHashCode Method int GetHashCode()
GetStatus Method timespan GetStatus()
GetType Method type GetType()
PauseTimer Method void PauseTimer()
Refresh Method void Refresh()
ResetTimer Method void ResetTimer()
RestartTimer Method void RestartTimer()
ResumeTimer Method void ResumeTimer()
StartTimer Method void StartTimer()
StopTimer Method void StopTimer()
ToString Method string ToString()
Description Property string Description {get;set;}
Duration Property timespan Duration {get;set;}
End Property datetime End {get;set;}
Name Property string Name {get;set;}
Running Property bool Running {get;set;}
Start Property datetime Start {get;set;}
Status Property MyTimerStatus Status {get;set;}
History PropertySet History {Name, Start, End, Duration, Description}Many of the methods are called from related commands.
You can create a new timer from the prompt.
PS C:\> Start-MyTimer revisions -Description "module updates"
Name Start Stop Duration Status Description
---- ----- ---- -------- ------ -----------
revisions 3/31/2025 5:27:48 PM 00:00:00:00 Running module updatesYou can start as many timers as you need.
PS C:\> $a = Start-MyTimer mail -Description email
PS C:\> $b = Start-MyTimerUse Get-MyTimer to view.
PS C:\> Get-MyTimer
Name Start Stop Duration Status Description
---- ----- ---- -------- ------ -----------
revisions 3/31/2025 5:27:48 PM 00:00:00:36 Running module updates
mail 3/31/2025 5:28:04 PM 00:00:00:20 Running email
MyTimer 3/31/2025 5:28:12 PM 00:00:00:12 RunningWhen you are finished, you can stop the timer.
PS C:\> Stop-MyTimer mail -PassThru | Format-List
Name : mail
Start : 3/31/2025 5:28:04 PM
End : 3/31/2025 5:29:08 PM
Duration : 00:01:03.8458479
Running : False
Description : email
Status : StoppedThe timer will exist for the duration of your PowerShell session.
PS C:\> Get-MyTimer -Status Stopped | Select History
Name : revisions
Start : 3/31/2025 5:27:48 PM
End : 3/31/2025 5:29:54 PM
Duration : 00:02:06.5184936
Description : module updates
Name : mail
Start : 3/31/2025 5:28:04 PM
End : 3/31/2025 5:29:08 PM
Duration : 00:01:03.8458479
Description : emailAlthough there are provisions for exporting and importing timers.
The module includes a format ps1xml file that uses ANSI to highlight timers based on status.
Timers are managed through two hashtables created as global variables, $MyTimerCollection and $MyWatchCollection. Do not delete these variables. The MyTimer commands will update these hashtables as needed.
The Start-PSCountdown command uses Write-Progress to display countdown information. PowerShell 7.2 uses a minimized progress display and a different set of color options based on $PSStyle.
If you would like to use the legacy progress display in PowerShell 7, you should configure it before running Start-PSCountdown.
$PSStyle.View = "Classic"Set it to Minimal to restore.
Start-PSCountdown will automatically detect $PSStyle and adjust colors accordingly. It is recommended that you use PowerShell 7.2 or later.
Use Ctrl+C to terminate a countdown.
For a more traditional countdown timer, you can use Start-PSTimer. This is an ideal command when you have a simple countdown, say, from 10. You can invoke a script block at the countdown completion.
PS C:\> Start-PSTimer -ScriptBlock {Get-Date} -Message "Let's Do This Thing!" -Title "Get-Ready"Another timer option is to display it in the console title bar. Although for most people, this will mean the profile tab in Windows Terminal. You can use Start-PSCountdownTitle to display a countdown timer in the console title bar. It will not work in the PowerShell ISE or VS Code.
Specify the timer in seconds. You can optionally specify a short message to display in the title bar and a short message to display after the countdown finishes.
Start-PSCountdownTitle -Seconds 120 -CountdownText "Resuming in"By default, the original tab title will be restored after 10 seconds. But you can configure this with the -Wait parameter. Set it to -1 to leave the title as is after the countdown completes.
If you are running a Windows-platform, you can use a WPF-based countdown timer.
An alternative to Start-PSCountdown is Start-PSCountdownTimer and related Stop-PSCountdownTimer
$splat = @{
Seconds = 600
Message = 'The PowerShell magic begins in '
FontSize = 64
Color = 'SpringGreen'
OnTop = $True
}
Start-PSCountdownTimer @splatThis is a transparent WPF form that displays a countdown timer and an optional message. You can control it by changing values in the $PSCountdownClock synchronized hashtable.
PS C:\> $PSCountdownClock
Name Value
---- -----
OnTop True
RunSpace System.Management.Automation.Runspaces.LocalRunspace
StartingPosition
Color SpringGreen
WarningColor Red
FontFamily Segoi UI
Warning 30
Started 3/31/2025 5:36:56 PM
FontWeight Normal
Action
AlertColor Yellow
Seconds 600
CurrentPosition {1334, 532}
FontSize 64
Message The PowerShell magic begins in
FontStyle Normal
Running True
Alert 50
PS C:\> $PSCountdownClock.OnTop = $FalseAt 50 seconds the color will change to yellow and then to red at 30 seconds.
You can stop the clock by right-clicking on the form, setting the Running hashtable value to $False, or running Stop-PSCountdownTimer. This is the recommended way. The WPF countdown runs in a separate runspace. If you close the PowerShell session where you started the countdown, the timer will terminate.
Because the timer runs in a separate runspace, the timer itself cannot initiate an action at the end of the timer. If you would like to create automation around the countdown timer, you could create a PowerShell script like this. The sample requires a Windows platform.
Clear-Host
$splat = @{
Seconds = 600
Message = 'The PowerShell magic begins in '
FontSize = 64
Color = 'SpringGreen'
OnTop = $True
}
Start-PSCountdownTimer @splat
Do {
Start-Sleep -Seconds 1
} While ($PSCountdownClock.Running)
Write-Host "Are you ready for some PowerShell?" -ForegroundColor magenta -BackgroundColor gray
#play a startup song
Add-Type -AssemblyName PresentationCore
$filename = "c:\work\01-Start.mp3"
$global:MediaPlayer = New-Object System.Windows.Media.MediaPlayer
$global:MediaPlayer.Open($filename)
$global:MediaPlayer.Play()
#the media player launches with no UI. Use the object's methods to control it.
# MediaPlayer.stop()
# $MediaPlayer.close()For a related project, take a look at the PSClock module. Or if you need a simple to-do manager, look at the PSWorkItem module.