SCOM maintenance mode powershell script broke

960 views Asked by At

in my company we use powershell script that puts objects in maintenance mode. problem is that it suddently stop work at all - there are no errors, but script do nothing

maintenance intervals defines by XML file

for example

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

and here is the script

$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.")
 }

any ideas?

2

There are 2 answers

2
Χpẘ On

As Ansgar indicated a good way to address a problem like that is via some sort of debugging.

However you asked for ideas, so here are some: 1. One likely way I see for the script to do "nothing" (assuming it runs at all) is for $GroupMembers to be empty. 2. $GroupMembers relies on $Group evaluating to $true, so if $Group is $null nothing will happen. 3. $Group isn't assigned unless the following evaluates $true:

$StartDay -eq (Get-Date).DayOfWeek -and 
(Get-Date) -ge $StartTime.AddMinutes(-($Interval + 10)) -and 
(Get-Date) -lt $StartTime.AddMinutes($Interval + 10))
  1. That expression being $true depends on the value of $Interval. $Interval is defined based on $IntervalSeconds - whose definition is not shown in the OP. So StackOverflow responders can't help you with that code path.

  2. A couple of other possible failures are Get-SCOMGroup returning $null or GetRelatedMonitoringObjects returning $null.

Since the original question asked for ideas and I gave you several plausible ideas, I'd say I answered the question.

1
Start-Automating On

My company wrote these cmdlets for Microsoft a couple of years ago. This question rung a bell about a SCOM enthusiast friend and the need to change maintenance modes often. I checked, and I believe that the commands Start-SCOMMaintenanceMode and Update-SCOMMaintenanceMode will do the trick (and save you a bunch of code).

Please let me know if this is not the case.