Monitoring with PowerShell: UPS Status (APC, Generic, and Dell)

So we’re using several types of UPS’s at our clients, and sometimes bump into generic USB UPS systems too. To monitor these we use a couple of methods that all have benefits and downsides. Let’s get started.

If a generic USB UPS is installed, Windows Server recognizes this as a Battery Unit. The status is sent to the server by using a generic Windows Driver called “Microsoft Compliant Control Method Battery” which is quite the mouthfull. The good thing is that with this driver we can use a couple of small PowerShell commands to find the exact status of the battery.

USB UPS systems

 $Battery = Get-CimInstance -ClassName win32_battery
Switch ($Battery.Availability) {
    1  { $Availability = "Other" ;break}
   2  { $Availability =  "Not using battery" ;break}
   3  { $Availability = "Running or Full Power";break}
   4  {$Availability =  "Warning" ;break}
   5  { $Availability = "In Test";break}
   6  { $Availability = "Not Applicable";break}
   7  { $Availability = "Power Off";break}
   8  { $Availability = "Off Line";break}
   9  { $Availability = "Off Duty";break}
   10  {$Availability =  "Degraded";break}
   11  {$Availability =  "Not Installed";break}
   12  {$Availability =  "Install Error";break}
   13  { $Availability = "Power Save - Unknown";break}
   14  { $Availability = "Power Save - Low Power Mode" ;break}
   15  { $Availability = "Power Save - Standby";break}
   16  { $Availability = "Power Cycle";break}
   17  { $Availability = "Power Save - Warning";break}
    }

$BatteryStatus = $Battery.Status
$BatteryName = "$($Battery.name)"
$Remaining = $Battery.EstimatedChargeRemaining
$EstRunTimeMinutes = $Battery.EstimatedRunTime
$BatAvailability = $Availability

The script gets the battery status out of WMI, it shows if the machine is running on battery or not, and you can alert on this. We’ve set our systems up to make sure that when the battery status changes from anything but “Not using battery” it alerts, and possibly shuts down the machine.

Another thing to pay attention to is the Battery Status – Most APCs and Dell’s connected to USB even tell the OS if the battery is in a warning state or failed, you should alert on anything but “OK” for the status.

We can’t really monitor network UPS systems with this, as they do not get their data in w32_battery, so we’ll have to use a couple of different solutions for this. I’ll try covering this in a future blog. As always, happy PowerShelling!

10 Comments

  1. Dec1slh September 20, 2019 at 4:11 am

    Doe the script run constantly in a loop or something

    1. Kelvin Tegelaar September 20, 2019 at 7:57 am

      These scripts are made to implement into a RMM system, which runs the script on a schedule you set. Most RMMs allow you to run this each minute.

    2. Matthew Griffore December 16, 2020 at 3:26 pm

      Possible for PowerShell to monitor a network UPS server?

  2. bitboy October 8, 2019 at 9:54 am

    Hi, thx for the script. I’ve tried it but i got no result. Is it possible, thats not working if powershute from APC is installed?

    1. Kelvin Tegelaar October 8, 2019 at 10:09 am

      The script should work, as long as your USB UPS is recognized in Windows as a battery unit.

      1. Miguel October 11, 2019 at 11:58 am

        We are experienncing the same issue. Most likely this is because when you install PowerChute the driver gets replaced by the APC UPS driver and not the default HID UPS driver which writes the events to the win32_battery class.

        From what I find online this has been an issue for years already where it’s usually fixed by removing the APC Powerchute software.

  3. Vincent Loosveld January 31, 2020 at 12:06 pm

    Nice post!
    I am using a very stable VB-script to monitor the UPS-status and shutdown a Hyper-V server when battery is lower than a given percentage.
    But VB-script… With powershell it looks much better.
    Will have to convert it using your info, if I have some testing-time. Must be stable!!

    Thanks,
    Vincent

  4. Stefano Giunchi April 20, 2020 at 1:19 pm

    Thank for your script, I’m using it with Datto RMM.

    Some servers, without UPS attached, return “$Battery = Get-CimInstance -ClassName win32_battery” empty.

    It would raise an alert, so I added the 999 value at the end of the switch:
    Switch ($Battery.Availability) {
    1 { $Availability = “Other” ;break}
    2 { $Availability = “Not using battery” ;break}
    […]
    999 { $Availability = “Not using battery”}
    }

    1. Kelvin Tegelaar April 20, 2020 at 1:31 pm

      Yeah, it does tend to do that. Our RMM allows filtering on UPS availability, but I understand DattoRMM does not have that luxury. Your solution would be a good one then.

  5. JASON REYNOLDS September 7, 2020 at 5:21 pm

    Just came across this myself. The APC driver disables all native windows battery management. I went back to the default driver. Brief history, when I had the powerchute software and APC driver installed, my PC would go to hibernate, on power resume, the UPS would stay on battery for about a minute. At that time it would drop all power to everything and switch to AC finally.

    This happened across two UPS’s from APC.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.