Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET! Learn What IT Pros Need to Know About Windows 11 - August 24th at 1 PM ET!
PowerShell

More Battery Reporting Fun with PowerShell

In an earlier article I guided you through the process of creating a PowerShell based tool to keep track of battery power. Even if you didn’t need the end result, the process I followed and techniques can be helpful in your own projects. In this article I want to continue exploring what I can do with my previous work. I’m always looking to see how far I can push my PowerShell projects. Sometimes PowerShell, or Windows, pushes back but even that can be educational.

With my battery check tool, one limiting factor is that I have to remember to periodically run the function in my PowerShell session. But then there’s that whole typing-thing. Oh, the agony. To alleviate my pain and suffering, I first need something that will give me a more visual clue about battery life.

Creating a PowerShell Battery Report Popup Dialog

I decided I wanted an old-fashioned popup box. Being an old-school VBScript guy I always liked the Popup() method from the Wscript.Shell object. This is even easier to use in PowerShell.

$shell = new-object -ComObject wscript.shell
$shell.Popup("Hey! What are you looking at?")
powershell battery report
Using wscript.shell to create a popup dialog. (Image: Jeff Hicks)

The Popup() method has additional parameters to control the title, the button selection and icons. What I especially like about this method is that unlike the VBScript MessageBox, I can set a timeout value so that if I don’t click on a button, the popup will still automatically dismiss after a specified number of seconds.

Sponsored Content

Read the Best Personal and Business Tech without Ads

Staying updated on what is happening in the technology sector is important to your career and your personal life but ads can make reading news, distracting. With Thurrott Premium, you can enjoy the best coverage in tech without the annoying ads.

$shell.Popup("Hey! What are you looking at?",10,"Popup",0+48)
Setting a time out value using $shell.Popup. (Image: Jeff Hicks)

The second parameter, 10, is the number of seconds to display the popup. If you set it to -1 the popup will remain until the user clicks a button. The last parameter is a combination of buttons and icons. You can learn more about these values by reading the official MSDN documentation for the popup method.

For my needs, I only need to present a popup if the battery level reaches a certain level and is not connected to power. Here’s the brief monitoring script I came up with that I call Watch-Battery.ps1.

#requires -version 3.0

<#
Watch-Battery.ps1

Test battery and display popup when it gets too low

Limit is the percent remaining battery power.
Timeout is the number of seconds to display the popup message.
This script is meant to be run locally.

#>

[cmdletbinding()]
Param(
[int]$Limit=50,
[int]$Timeout = 10
)

Write-Verbose "$(Get-Date) Testing battery"

#get battery data
$battery = Get-CimInstance -ClassName Win32_Battery 

Write-Verbose ($battery | out-string)

$charge = $battery.EstimatedChargeRemaining

#run if charge is <= the limit and battery is not charging
if ($charge -le $Limit -AND $battery.batteryStatus -ne 2) {
    [string]$Runtime = New-TimeSpan -minutes $battery.EstimatedRunTime

#define a message here string which must be left justified
$msg = @"
The battery is at $charge% with a remaining runtime of $runtime.
You might consider plugging in some power.
"@

    Write-Verbose $msg

    #display the message using a Wscript Popup
    $wscript = New-Object -ComObject Wscript.shell
    $wscript.Popup($msg,$Timeout,"Battery Alert",48) | out-Null

} #close if

Write-Verbose "$(Get-Date) Finished testing battery."

#end of script

The script checks the Win32_Battery class and compares the EstimatedChargeRemaining property to the parameterized Limit. If the value is less than or equal than the limit, then the script creates and displays the popup. The TimeOut parameter controls how long the popup is displayed in seconds.

I use a here string to define the message, inserting values from variables. When using a here string in a script file, it needs to be left justified. Technically not all of it does but I find it just as easy to left justify the entire thing.

Here’s an example of the script in action. At the prompt I can type:

C:\scripts\watch-battery.ps1 -Limit 75

And get this:

A sample battery alert created using PowerShell. (Image: Jeff Hicks)

Of course I still have to manually type the command. I first tried creating a PowerShell scheduled job.

$options = New-ScheduledJobOption -ContinueIfGoingOnBattery -StartIfOnBattery
#check every 15 minutes
$trigger = New-JobTrigger -RepeatIndefinitely -RepetitionInterval (New-Timespan -Minutes 15) -Once -at "12:00AM" 

$paramHash = @{
 FilePath = "C:\scripts\watch-battery.ps1"
 Name = "BatteryCheck"
 Trigger = $Trigger
 MaxResultCount = 8
 ArgumentList = 75
 ScheduledJobOption = $options
 RunNow = $True
}

Register-ScheduledJob @paramHash

While the job technically ran, I never saw the popup on my screen. PowerShell scheduled jobs run in separate PowerShell instances that are not interactive when launched by the Task Scheduler.

Although I suppose instead of displaying the popup I could have the script email me or send me a text message on my phone. But the interactive popup appears to be a non-starter with scheduled jobs. I did try using a Scheduled Task which worked slightly better.

#requires Windows 8 and later

$paramHash = @{
 Once = $True
 at = "12:00AM"
 RepetitionInterval = (New-Timespan -Minutes 15)
 RepetitionDuration = (New-Timespan -Hours 24)

}

$Trigger = New-ScheduledTaskTrigger @paramHash
 $paramHash = @{
 AllowStartIfOnBatteries = $True
 DontStopIfGoingOnBatteries = $True
}


$settings = New-ScheduledTaskSettingsSet @paramHash

#use a threshhold of 30
$paramHash = @{
 Execute = "PowerShell.exe"
 Argument = "-nologo -noprofile -windowstyle Hidden -file c:\scripts\watch-battery.ps1 30"
}

$action = New-ScheduledTaskAction @paramHash

$paramHash = @{
 TaskName = "BatteryCheck"
 Trigger = $trigger
 Action = $action
 Settings = $settings
}

Register-ScheduledTask @paramHash

I got the popup, but I end up with a flashing PowerShell window. So what to do? I’ll cover that in a separate article.

In the meantime, look at your PowerShell tools and see where else you can take them. It can make for an exciting journey.

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

Register for Advanced Microsoft 365 Day!

GET-IT: Advanced Microsoft 365 1-Day Virtual Conference - Live August 24th!

Join us on Tuesday, August 24th and hear from Microsoft MVPs and industry experts about how to take advantage of Microsoft 365 at a technical level and dive deep into the features and functionality that will make your environment more secure and compliant.

RSVP Now

Sponsored By