1

在我的公司中,我们使用将对象置于维护模式的 powershell 脚本。问题是它突然停止工作 - 没有错误,但脚本什么也不做

维护间隔由 XML 文件定义

例如

<MMWindow>
<Name>MMG 129OP SVC WEBSOA</Name>      ---group containing objects
<Schedule>Mon 19:30-Mon 23:00</Schedule> ---monday 19:30 to 23:00
</MMWindow>

这是脚本

$ErrorActionPreference = "stop"

$oAPI = new-object -comObject "MOM.ScriptAPI"
$Error.Clear()

If ($Debug -ne "true")
{
    $Debug = [bool]$false
}
else
{
    $Debug = [bool]$true
}

$DateTime = Get-Date
$Interval = $IntervalSeconds / 60

If ($Debug)
 { 
    $oAPI.LogScriptEvent("MaintenanceWindows.ps1",800,4,"The script 'MaintenanceWindows.ps1' is starting at $DateTime.")
 }

$setupKey = Get-Item -Path "HKLM:\Software\Microsoft\Microsoft Operations Manager\3.0\Setup"
$installDirectory = $setupKey.GetValue("InstallDirectory") | Split-Path
$psmPath = $installdirectory + "\Powershell\OperationsManager\OperationsManager.psm1"
Import-Module $psmPath
#Import-Module "C:\Program Files\System Center 2012\Operations Manager\Console\Microsoft.EnterpriseManagement.OperationsManager.ClientShell.dll"

New-SCOMManagementGroupConnection -ComputerName 123.ru
$XmlPath = "C:\Monitoring\Maintenance\MaintenanceWindows.xml"
[xml]$MMContent = Get-Content $XmlPath

If ($Debug -and $Error)
 { 
    $oAPI.LogScriptEvent("MaintenanceWindows.ps1",802,4,"Error: $Error. Time: $DateTime.")
 }

if ($MMContent.HasChildNodes)
{
    foreach ($MMWindow in $MMContent.MMWindows.MMWindow)
    {
       $ScheduledDays = ($MMWindow.Schedule).Split(",")

       foreach ($ScheduledDay in $ScheduledDays)
       {
            $StartDay = ($ScheduledDay.Split("-").GetValue(0)).Split(" ").GetValue(0)

             Switch ($StartDay)
            {
                "Mon" {$EndDay = "Monday"
                      $EndDayCount = 1}
                "Tue" {$EndDay = "Tuesday"
                      $EndDayCount = 2}
                "Wed" {$EndDay = "Wednesday"
                      $EndDayCount = 3}
                "Thu" {$EndDay = "Thursday"
                      $EndDayCount = 4}
                "Fri" {$EndDay = "Friday"
                      $EndDayCount = 5}
                "Sa" {$EndDay = "Saturday"
                      $EndDayCount = 6}
                "Su" {$EndDay = "Sunday"
                      $EndDayCount = 7}
            }

            $EndDay = ($ScheduledDay.Split("-").GetValue(1)).Split(" ").GetValue(0)

            Switch ($EndDay)
            {
                "Mon" {$EndDay = "Monday"
                      $EndDayCount = 1}
                "Tue" {$EndDay = "Tuesday"
                      $EndDayCount = 2}
                "Wed" {$EndDay = "Wednesday"
                      $EndDayCount = 3}
                "Thu" {$EndDay = "Thursday"
                      $EndDayCount = 4}
                "Fri" {$EndDay = "Friday"
                      $EndDayCount = 5}
                "Sa" {$EndDay = "Saturday"
                      $EndDayCount = 6}
                "Su" {$EndDay = "Sunday"
                      $EndDayCount = 7}
            }

            [DateTime]$StartTime = ($ScheduledDay.Split("-").GetValue(0)).Split(" ").GetValue(1)
            if ($EndDayCount -lt $StartDayCount)
            {
                [DateTime]$EndTime = ([DateTime]($ScheduledDay.Split("-").GetValue(1)).Split(" ").GetValue(1)).AddDays(7 - ($StartDayCount - $EndDayCount))
            }
            else
            {
                [DateTime]$EndTime = ([DateTime]($ScheduledDay.Split("-").GetValue(1)).Split(" ").GetValue(1)).AddDays($EndDayCount - $StartDayCount)
            }

            If ($StartDay -eq (Get-Date).DayOfWeek -and (Get-Date) -ge $StartTime.AddMinutes(-($Interval + 10)) -and (Get-Date) -lt $StartTime.AddMinutes($Interval + 10))
            {
                    $Group = Get-SCOMGroup -DisplayName $MMWindow.Name

            If ($Debug -and $Error)
            { 
                $oAPI.LogScriptEvent("MaintenanceWindows.ps1",803,4,"Error: $Error. Time: $DateTime.")
            }

                    If($Group)
                    {
                            $GroupMembers = $Group.GetRelatedMonitoringObjects()
                            If($GroupMembers.Count -gt 0)
                            {
                                Foreach ($Instance in $GroupMembers)
                                    {
                                    if (!$Instance.InMaintenanceMode)
                                    {
                                    Start-SCOMMaintenanceMode -Instance $Instance -EndTime $EndTime.ToUniversalTime() -Reason "PlannedOther"  -Comment "Planned Maintenance Mode by Script"
                                    $oAPI.LogScriptEvent("MaintenanceWindows.ps1",805,4, "Start MM for object: " + $Instance.DisplayName + ". End MM: " + $EndTime)
                            If ($Debug -and $Error)
                            { 
                                $oAPI.LogScriptEvent("MaintenanceWindows.ps1",804,4,"Error: $Error. Time: $DateTime.")
                            }
                                    }
                                }
                        }
                }
            }
        }
    }
}
If ($Debug)
 { 
    $oAPI.LogScriptEvent("MaintenanceWindows.ps1",801,4, "The script 'MaintenanceWindows.ps1' is finished.")
 }

有任何想法吗?

4

2 回答 2

0

正如 Ansgar 指出的那样,解决此类问题的好方法是通过某种调试。

但是,您询问了一些想法,所以这里有一些: 1. 我看到脚本“什么都不做”(假设它完全运行)的一种可能方式是让 $GroupMembers 为空。2. $GroupMembers 依赖于 $Group 对 $true 的评估,因此如果 $Group 为 $null,则不会发生任何事情。3. 除非以下计算 $true,否则不会分配 $Group:

$StartDay -eq (Get-Date).DayOfWeek -and 
(Get-Date) -ge $StartTime.AddMinutes(-($Interval + 10)) -and 
(Get-Date) -lt $StartTime.AddMinutes($Interval + 10))
  1. 该表达式为 $true 取决于 $Interval 的值。$Interval 是基于 $IntervalSeconds 定义的 - 其定义未在 OP 中显示。因此 StackOverflow 响应者无法帮助您处理该代码路径。

  2. 其他几个可能的失败是 Get-SCOMGroup 返回 $null 或 GetRelatedMonitoringObjects 返回 $null。

由于最初的问题要求提供想法,并且我给了您几个看似合理的想法,所以我会说我回答了这个问题。

于 2013-12-08T19:08:07.380 回答
0

几年前,我的公司为 Microsoft 编写了这些 cmdlet。这个问题敲响了一个关于 SCOM 爱好者朋友和需要经常改变维护模式的钟声。我检查了一下,我相信命令 Start-SCOMMaintenanceMode 和 Update-SCOMMaintenanceMode 可以解决问题(并为您节省大量代码)。

如果不是这种情况,请告诉我。

于 2013-12-09T08:45:11.063 回答