2013-12-08 40 views
1

我们使用powershell脚本将对象置于维护模式。问题是,它suddently停止在所有的工作 - 有没有错误,但脚本无可奈何SCOM维护模式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.") 
} 

有什么想法?

+0

您是否启用了启用调试的脚本? –

+0

$ ErrorActionPreference =“停止”,这还不够吗?如何强制ps显示所有错误和警告?像空串等等?我不是程序员( –

+0

)设置'$ ErrorActionPreference =“Stop”'应该让脚本打印一条错误消息,并在出现错误时终止。但是,根据运行方式的不同,您可能会也可能不会看到消息。 ,这个脚本看起来像是写了一个不同类型的错误处理记忆。 –

回答

0

由于Ansgar指出了解决问题的好方法,就像通过某种调试一样。

然而,你询问了一些想法,所以这里有一些: 1.我看到脚本做“没有”(假设它运行)的一种可能方式是$ GroupMembers为空。 2. $ GroupMembers依赖$ Group评估为$ true,因此如果$ Group为$ null,则不会发生任何情况。 3. $组未分配,除非出现以下计算$真:

$StartDay -eq (Get-Date).DayOfWeek -and 
(Get-Date) -ge $StartTime.AddMinutes(-($Interval + 10)) -and 
(Get-Date) -lt $StartTime.AddMinutes($Interval + 10)) 
  1. 这是表达真$依赖于$间隔值。 $ Interval基于$ IntervalSeconds定义 - 其定义未在OP中显示。因此,StackOverflow响应者无法帮助您使用该代码路径。

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

由于原来的问题提出了想法,我给了你几个合理的想法,我会说我回答了这个问题。

+0

intervalseconds = 300后,也会分享这个脚本SCOM社区。无论如何打开所有的错误和警告? –

+0

很多Powershell cmdlet都可以提供详细和/或调试输出。运行'help about_preference_variables'并查找$ DebugPreference和$ VerbosePreference。 Set-StrictMode可用于查找某些类型(通常是编码)的错误。 Trace-Command可以用来获取大量的内部信息。然而,就你而言,通过在脚本中添加一些调试语句(我在调试时使用'write-host')可能会更好。也看起来像@ Start-Automating的答案具有特定于SCOM维护模式的信息。 –

+0

写主机帮助很大,thx –

0

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

如果情况并非如此,请让我知道。

+0

问题是在XML中,因为我猜测,而不是在cmdlet –