What are my options when a PowerShell script fails?

2

Not wanting to use the APC software that shipped with my APC I have written a PowerShell script to monitor my UPS and initiate a shutdown sequence of my servers if the battery level reaches 30%.

The script runs on a virtualized server via USB redirection. The window is perpetually left open as it monitors the WMI input of the battery level of the primary UPS. The script works beautifully, however several times I've logged onto the server and noticed the following error on the screen

Get-WmiObject : Call was canceled by the message filter. (Exception from HRESULT: 0x80010002 (RPC_E_CALL_CANCELED))
At C:\Users\user\Desktop\upsmonitor.ps1:38 char:27
+     $binfo = Get-WMIObject <<<<  -class Win32_Battery -computername $system -namespace root\cimv2
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

I assume this is caused by a blip in WMI activity - I've read forums that said this is caused by WMI crashing. In any event, this is problematic because if the script ever needs to function and it's error'd out then it does me no good. Checking the server frequently isn't ideal so I'd like a way to either

  • re-execute the script upon failure
  • At a minimum notify me when the script has failed

I have read into the -ErrorAction switch, but am unsure how to implement it in my case, or if it's even applicable. Normally I would just play around with the script until I was able to resolve the issue however it only really seems to present itself on my production environment, and it's not consistent. It could take me months to troubleshoot this issue waiting for the error to occur hoping my fix worked.

I would appreciate any assistance you guys could offer.

The script is listed below.

## Variable Declaration
cls
$system = "."
$namespace = "root\CIMV2"

#SMTP Variables (for e-mail notifications)
$emailFrom = "ups@domain.com"
$emailto = "me@domain.com"
$subject = "UPS Notifications"
$PSEmailServer = "10.0.0.100"

#Check to see if the event log source exists, and create it if it doesn't
$sourceExists = get-eventlog -list | where-object {$_.logdisplayname -eq "UPS Monitor"}
if (! $sourceExists) {
    new-eventlog -LogName "UPS Monitor" -source "UPS Monitor"
    }

#Send the administrator a message to inform them of monitoring
$initialStatus = Get-WMIObject -class Win32_Battery -computer $system -namespace $namespace
send-mailmessage -From $emailFrom -To $emailTo -Subject $subject -Body "UPS Monitor Online: Monitoring UPS Status."
echo "UPS Monitor Online - Currently Monitoring UPS Status. DO NOT CLOSE THIS WINDOW!"

$eruntime = $initialstatus.estimatedruntime

#What's the status of the Battery upon starting the script
if ($initialStatus.batterystatus -eq 2) {
    echo "Battery Status : On AC Power"
    echo "Estimated Time remaining on charge : $eruntime minutes"
} elseif($initialStatus.batterystatus -eq 1) {
    echo "Battery Status : Discharging"
    echo "Estimated Time remaining on charge : $eruntime minutes"
    }

write-eventlog -logname "UPS Monitor" -Source "UPS Monitor" -EntryType Information -EventID 1 -Message "UPS Monitor Online: Currently Monitoring UPS Status"

while($true)
   {
    $binfo = Get-WMIObject -class Win32_Battery -computername $system -namespace root\cimv2
    if($binfo.BatteryStatus -eq 2) {  
       #On AC Power - No action required
        }
      if($binfo.BatteryStatus -eq 1){
            #If UPS status is 1, UPS is discharging - Notifications will begin at 80% Battery Level
            #echo "Battery Charge Percentage : " $binfo.EstimatedChargeRemaining
             if($binfo.EstimatedChargeRemaining -eq 80){
                #When the battery level gets to 80% write an event to the event log and e-mail the administrator
                write-eventlog -logname "UPS Monitor" -Source "UPS Monitor" -EntryType Information -EventID 1 -Message "Power Failure Detected - 80% Battery Life Remaining"
                send-mailmessage -From $emailFrom -To $emailTo -Subject $subject -Body "Power Failure Detected; Servers on Battery Power. Battery level is 80%"
                start-sleep -seconds 30
                 }
             elseif($binfo.EstimatedChargeRemaining -eq 60){
                #When the battery level gets to 60% write an event to the event log and e-mail the administrator
                write-eventlog -logname "UPS Monitor" -Source "UPS Monitor" -EntryType Information -EventID 1 -Message "Power Failure Detected : 60% Battery Life Remaining"
                send-mailmessage -From $emailFrom -To $emailTo -Subject $subject -Body "Power Failure Detected; Servers on Battery Power. Battery level is 60%"
                start-sleep -seconds 30
                 }
             elseif($binfo.EstimatedChargeRemaining -eq 40){
                #When the battery level gets to 40% write an event to the event log and e-mail the administrator and warn of shutdown
                write-eventlog -logname "UPS Monitor" -Source "UPS Monitor" -EntryType Information -EventID 1 -Message "Power Failure Detected : 40% Battery Life Remaining"
                send-mailmessage -From $emailFrom -To $emailTo -Subject $subject -Body "Power Failure Detected & Reserve battery is critical. Servers will be restarted at 30% battery life if AC power is not resumed"
                start-sleep -seconds 30
                }
              elseif($binfo.EstimatedChargeRemaining -le 30){
                #When the battery level gets to 30% being shutting down servers
                write-eventlog -logname "UPS Monitor" -Source "UPS Monitor" -EntryType Information -EventID 1 -Message "Critical Battery Threshold Reached : Commencing Shutdown of servers"
                send-mailmessage -From $emailFrom -To $emailTo -Subject $subject -Body "Power Failure Detected & Critical Battery Threshold has been Reached. Commencing Shutdown of Servers"
                start-sleep -seconds 15
                stop-computer -cn (Get-Content C:\Users\User\Desktop\serverlist.txt) -Force
                }

        }
    }
powershell-2.0
exit-code
asked on Stack Overflow Oct 28, 2013 by DKNUCKLES

1 Answer

0

You could simply use try catch blocks and define specifics in your catch block when the error occurs.

answered on Stack Overflow Oct 28, 2013 by phani

User contributions licensed under CC BY-SA 3.0