Building a Countdown Timer with PowerShell

Comments 0

Share to social media

When one thinks of PowerShell, one thinks of it as a scripting language. Generally, this is true. While you can write a script that prompts for input and provides output, usually there are no real GUI elements involved, and a cursory glance at the list of PowerShell cmdlets reinforces this idea.

However, it is possible to create a GUI with PowerShell; it just takes a bit more work. Furthermore, once one understands how to do this, it can lead to far more powerful scripts in the future.

A Simple Timer

As with some of my projects, this one started as sort of a challenge to myself. I wanted to create a script that created a form on the screen, and I wanted it to do something. I decided to start with something simple, a form that counted down the time and then closed. (NOTE: The examples in this article work in classic PowerShell but not PowerShell Core since Core is multiplatform.)

Save the following script as Countdown Timer_1.ps1.

The loop should be self-evident. It starts with the selected $delay value and counts down, sleeping for 1 second at a time until it hits 0. Note that due to how PowerShell works, the one-second delay in start-sleep has some slop to it. You should not use this script to launch a space shuttle, but for everyday use it’s fine.

The interesting part of this script is not the loop; it’s the New-Object System.Windows.Forms.Form line. To anyone who has worked with C# or VB.Net or any other .Net managed code, this should look familiar. You are simply calling into the .Net Framework to create a form. This innocuous statement will mean huge ramifications later.

Once you have your form object, you can start to assign some properties, in this case, the title (in the .text) property and height and width.

Finally, you need to put a new object on this form, a label. Once you’ve done that, you simply loop through for the length of your $delay and the form will count down. You should see a screen that looks like this. (Note that the scripts in this article were tested on Dell and Lenovo laptops, an old HP desktop, and an Azure VM but no guarantee that the forms will look the same on all machines. You may have to tweak some of the numbers in the scripts to see the same results.)

It’s not pretty, but it gets the job done. To fix some of the more obvious problems and create something a bit nicer looking, save the following script as Coutndown Timer_2.ps1.

You should get something like this when you run the script:

 

You now have a countdown timer that you can control the label position, font size, style and color which is all very useful. In this case, I took advantage of the ability to move the label down a bit, make the font larger and to change color and size as the countdown approached 0.

Adding Functionality

The previous example is a simple timer, but to make it useful, you will need to add some controls. Again, you can take advantage of the fact that classic PowerShell can make calls into the Windows forms dll.

In addition, you will take advantage of the ability to pass parameters as you start to make this a fully functional application. This time, you will add a new label, a text edit box and OK and Cancel buttons. Combined, all these should give you a fully functional countdown timer.

The following script combines all of the above:

You can call it from the command line and pass the parameter –EventLabel “Now we can really rock!”

When you run it, you will get something like this:

Clicking the Ok button will result in the following:

I will leave it to you as the reader to figure out how to add the possibility of editing the passed in EventLabel parameter within the dialog box.

Controlling the Form Position

When you run this multiple times, you will notice that the position of the dialog box itself changes each time. The next version will fix this. In fact, in the next step, you will make this a fairly functional countdown timer that fills up most of the screen and looks professional.

You’ve now created a fully functional countdown timer that will automatically scale to the size of the screen and allow you to configure how long it runs for and what primary message it displays. Future improvements might be to allow the option of having a background graphic and being able to more easily abort the timer in the middle of it running.

Conclusion

Hopefully, now you can see that through the power of PowerShell, in combination with the built-in .Net capabilities, you can create full-fledged applications that can interact with the user, prompting them for input and also providing them with output. In fact, pretty much anything you can do in C# or VB.Net can be done in a very similar fashion in PowerShell without needing to write a full-blown application. That said, writing an application like this using PowerShell ISE can be tedious. For example, it took me a while to get the positioning correct, mostly due to a few typos here and there (for example, using width when I meant height and vice versa). There are plug-ins for Visual Studio and other stand-alone IDEs that can make this task easier. But I wanted to demonstrate the power of PowerShell out of the box without any further add-ons or tools.

All scripts in this article are also available at: https://github.com/stridergdm/SimpleTalk_PowerShell-Scripts

 

About the author

Greg Moore is a graduate of RPI. There, he majored in CompSci, but probably spent as much time hiking, canoeing, caving and rock-climbing as he did studying. He started working with SQL Server 4.21a in 1995 and has survived numerous upgrades. He's been a Director and later VP of IT at several startups including PowerOne Media, TownNews and Traffiq and now consults. These days, when he's not busy with playing with SQL Server or spending time with his family, he can often be found underground caving or teaching cave rescue with the NCRC. While his focus is on the operations side of DBA, his interests include DR, performance and general IT problem solving. He is the author of: IT Disaster Response: Lessons Learned in the Field.