当 PowerShell 脚本失败时,我都有哪些选择?

Posted

技术标签:

【中文标题】当 PowerShell 脚本失败时,我都有哪些选择?【英文标题】:What are my options when a PowerShell script fails?当 PowerShell 脚本失败时,我有哪些选择? 【发布时间】:2013-10-28 13:15:25 【问题描述】:

不想使用我的 APC 附带的 APC 软件,我编写了一个 PowerShell 脚本来监控我的 UPS 并在电池电量达到 30% 时启动我的服务器的关闭序列。

脚本通过 USB 重定向在虚拟化服务器上​​运行。该窗口始终保持打开状态,因为它监控主 UPS 电池电量的 WMI 输入。该脚本运行良好,但是我多次登录服务器并注意到屏幕上出现以下错误

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

我认为这是由 WMI 活动中的一个问题引起的 - 我读过论坛说这是由 WMI 崩溃引起的。无论如何,这是有问题的,因为如果脚本需要运行并且它出错了,那么它对我没有好处。经常检查服务器并不理想,所以我想要一种方法

失败时重新执行脚本 至少在脚本失败时通知我

我已经阅读了-ErrorAction 开关,但不确定如何在我的情况下实现它,或者它是否适用。通常我只会玩弄脚本,直到我能够解决问题,但它似乎只在我的生产环境中出现,而且不一致。我可能需要几个月的时间来解决这个问题,等待错误发生,希望我的修复能奏效。

如果你们能提供任何帮助,我将不胜感激。

脚本如下。

## 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
                

        
    

【问题讨论】:

【参考方案1】:

您可以简单地使用 try catch 块并在发生错误时在您的 catch 块中定义细节。

【讨论】:

以上是关于当 PowerShell 脚本失败时,我都有哪些选择?的主要内容,如果未能解决你的问题,请参考以下文章

当 iOS 开发人员计划达到 100 台设备限制时,我都有哪些选择 [重复]

我的python大作业要选题,这是第一学期啊,我都不知道都有哪些课题可以选啊,求高手指教。

每次系统从睡眠中唤醒时都需要运行一个 powershell 脚本

win10中的Windows PowerShell是啥?都有哪些作用

win10中的Windows PowerShell是啥?都有哪些作用

win10中的Windows PowerShell是啥?都有哪些作用