Skip to content

Commit 9a53dc4

Browse files
authored
Add script 🏓
1 parent 1753fc6 commit 9a53dc4

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
<#
2+
.SYNOPSIS
3+
With SCOM Monitoring, sometimes you want to want to put a certain monitor into "Maintenance Mode", however, monitors cannot be placed into maintenance mode. BUT, the underlying object can,
4+
which in turn puts the monitor into "Maintenance Mode".
5+
6+
For example, the monitor "TCP/IP NetBIOS Service Health" is a core Windows Operating System monitor that looks at the "LmHosts" service to see if it's running or not. This monitor targets the
7+
Windows Operating System class. Let's say we want to silence this monitor, this does not appear as an option in the MM Scheduler, and rightfully so, instead what we can do is put the TARGET of
8+
the monitor into maintenance mode. So, if we want to put the "TCP/IP NetBIOS Service Health" monitor into "Maintenance", we need to put the whole Windows Operating System object into maintenance
9+
for the target server.
10+
11+
That's what this script does. It takes the input of the monitor display name to silence, and puts the underlying target into maintenance mode for the set duration in minutes.
12+
13+
.NOTES
14+
For best results, run from a management server, or after connecting to a management group in the current PowerShell process (ex. New-SCManagementGroupConnection -ComputerName "MS1.contoso.com" -Credential (Get-Credential))
15+
16+
.AUTHOR
17+
Lorne Sepaugh
18+
19+
.VERSION
20+
v2.0.0 - July 2024
21+
v1.0.0 - May 2021
22+
23+
.PARAMETER MonitorDisplayName
24+
This is the Display Name of the monitor that we want to place into maintenance mode (Alias: DisplayName)
25+
26+
.PARAMETER Comment
27+
Comment on the reason to place the monitor into maintenance mode
28+
29+
.PARAMETER Duration
30+
Provide the number of minutes the monitor should be placed into Maintenance Mode from the start of the script
31+
32+
.PARAMETER ComputerName
33+
You can provide either a path to a text file containing a list of servers (ex. .\ServerList.txt), or an inline comma-delimited list of servers (ex. "server01.contoso.com,server02.contoso.com")
34+
35+
.PARAMETER StartMaintenance
36+
(Default) Indicate that we will be starting maintenance, and set a duration for the maintenance to automatacally end after.
37+
38+
.PARAMETER StopMaintenance
39+
If you need to stop an existing maintenance schedule early.
40+
41+
.EXAMPLE
42+
PS> .\"Set-SCOMMonitorMaintenanceMode.ps1" -monitorDisplayName "TCP/IP NetBIOS Service Health" -comment "Server maintenance" -StartMaintenance -duration 90 -ComputerName ".\Serverlist.txt"
43+
44+
.EXAMPLE
45+
PS> .\"Set-SCOMMonitorMaintenanceMode.ps1" -monitorDisplayName "TCP/IP NetBIOS Service Health" -comment "Server maintenance" -StopMaintenance -ComputerName "agent01.contoso.com,agent02.contoso.com"
46+
#>
47+
48+
[CmdletBinding(DefaultParametersetName="StartMaintenance")]
49+
param (
50+
    [Parameter(ParameterSetName="StartMaintenance")]
51+
    [Switch] $StartMaintenance,
52+
 
53+
    [Parameter(ParameterSetName="StopMaintenance")]
54+
    [Switch] $StopMaintenance,
55+
   
56+
    [Parameter(Mandatory)][Alias('DisplayName')]
57+
    [ValidateNotNullOrEmpty()]
58+
    [String] $MonitorDisplayName,
59+
   
60+
    [Parameter()]
61+
    [String] $Comment,
62+
   
63+
    [Parameter(Mandatory, ParameterSetName="StartMaintenance")]
64+
    [ValidateNotNullOrEmpty()]
65+
    [Int] $Duration = 90,
66+
   
67+
    [Parameter(Mandatory)]
68+
    [ValidateNotNullOrEmpty()]
69+
    [String] $ComputerName,
70+
   
71+
    [Parameter(DontShow)]
72+
    [String] $ScriptPath = (split-path -parent $MyInvocation.MyCommand.Definition)
73+
)
74+
 
75+
Start-Transcript -Path "$($scriptPath)\ScriptTranscript.log" -IncludeInvocationHeader -Force
76+
 
77+
# Log the parameters to transcript
78+
Write-Output @"
79+
-- Parameter Values Provided --
80+
monitorDisplayName = '$($monitorDisplayName)'
81+
comment = '$($comment)'
82+
duration = $($duration)
83+
computerName = '$($computerName)'
84+
------
85+
"@
86+
 
87+
# Import the SCOM Module so that we can load all the cmdlets
88+
Import-Module OperationsManager
89+
 
90+
# Set the starting variables
91+
$EndTime = ((Get-Date).AddMinutes($($duration)).ToString("yyyy-MM-dd HH:mm:ss.fff")) # Set the end time for maintenance based on the indicated duration
92+
$monitor = Get-SCOMMonitor -DisplayName $monitorDisplayName # Get the correct monitor based on the displayName
93+
$targetClass = Get-SCOMClass -Id $($monitor.Target.Id.Guid) # Get the target class for the monitor
94+
$targetClassInstances = $targetClass | Get-SCOMClassInstance # Get the targeted class instances for the monitoring object
95+
 
96+
# Import the list of servers we'll be working with
97+
Switch (Test-Path -path $computerName) {
98+
    $true  { $serverList = Get-Content $ComputerName }
99+
    $false { [array]$serverList = $ComputerName -split ","}
100+
}
101+
 
102+
If ($startMaintenance) {
103+
 
104+
    Write-Output "Setting a Maintenance Window for the monitor '$monitorDisplayName' that will end at '$($EndTime)'`n"
105+
 
106+
    ForEach ($server in $serverList) {
107+
   
108+
        # Get the class instance for the current server in the list
109+
        $currentInstance = $targetClassInstances | Where {$_.Path -like "$($server)*" -or $_.DisplayName -like "$($server)*"}
110+
 
111+
        # Check to see if the current class instance is already in maintenance
112+
        $mmCheck = $currentInstance | Get-SCOMMaintenanceMode -ErrorAction SilentlyContinue
113+
 
114+
        # If an instance of the target class exists for the current server in our list, continue
115+
        If ($currentInstance -eq $null) {
116+
              # negative path – just go to the next iteration in the loop
117+
              Write-Warning "Maintenance Mode did NOT get set for '$($server)', as no class instances were found for it under monitor '$($monitorDisplayName)'."
118+
              continue
119+
         }
120+
 
121+
        # If the current isntance is not already in maintenance mode, continue
122+
        If ($mmCheck -ne $null){
123+
              # negative path – just go to the next iteration in the loop
124+
              Write-Warning "Maintenance Mode was ALREADY scheduled for the '$($currentInstance.DisplayName)' object for '$($server)' and ends at '$($mmCheck.ScheduledEndTime)'."
125+
              continue
126+
        }
127+
       
128+
       # Try setting maintenance for the current class instance
129+
        Try {
130+
            # Set MM schedule for the target instance    
131+
            $currentInstance | Start-SCOMMaintenanceMode -EndTime $EndTime -Reason PlannedApplicationMaintenance -Comment $comment -ErrorAction SilentlyContinue
132+
           
133+
            # Check if maintenance mode was set
134+
            $mmCheck = $currentInstance | Get-SCOMMaintenanceMode
135+
       
136+
            # If maintenance mode was set, rejoice, but continue either way
137+
            If ($mmCheck) {
138+
                Write-Information "Maintenance Mode was scheduled for the '$($currentInstance.DisplayName)' object for '$($server)'."
139+
            }
140+
            Else {
141+
                Write-Warning "Maintenance Mode did NOT get set for '$($server)', this could be due to it already being in maintenance, not having the target object, or something else."
142+
            }
143+
        }
144+
 
145+
        # If setting the maintenance schedule failed, then tell us why
146+
        Catch {
147+
            Write-Error "Maintenance Mode did NOT get set for '$($server)' due to error: $($_)."
148+
        }
149+
    }
150+
}
151+
 
152+
 
153+
If ($StopMaintenance) {
154+
 
155+
    Write-Output "Stopping Maintenance Window for the monitor '$monitorDisplayName'`n"
156+
 
157+
    ForEach ($server in $serverList) {
158+
   
159+
        # Get the class instance for the current server in the list
160+
        $currentInstance = $targetClassInstances | Where {$_.Path -like "$($server)*" -or $_.DisplayName -like "$($server)*"}
161+
 
162+
        # Check to see if the current class instance is currently in maintenance
163+
        $mmCheck = $currentInstance | Get-SCOMMaintenanceMode -ErrorAction SilentlyContinue
164+
       
165+
        # If an instance of the target class exists for the current server in our list, continue
166+
        If ($currentInstance -eq $null) {
167+
              # negative path – just go to the next iteration in the loop
168+
              continue
169+
       }
170+
           
171+
        # If the current isntance is currently in maintenance mode, continue
172+
        If ($mmCheck -eq $null){
173+
              # negative path – just go to the next iteration in the loop
174+
              Write-Information "No current maintenance schedule found for the '$($currentInstance.DisplayName)' object for '$($server)'."
175+
              continue
176+
        }
177+
           
178+
        # Try setting maintenance for the current class instance
179+
        Try {
180+
            # Stop MM schedule for the target instance    
181+
            $currentInstance | Get-SCOMMaintenanceMode | Set-SCOMMaintenanceMode -EndTime ((Get-Date).ToString("yyyy-MM-dd HH:mm:ss.fff"))
182+
                               
183+
            # Check if maintenance mode was stopped
184+
            $mmCheck = $currentInstance | Get-SCOMMaintenanceMode
185+
 
186+
            # If maintenance mode was stopped, rejoice, but continue either way
187+
            If ($mmCheck -eq $null) {
188+
                Write-Information "Maintenance Mode was stopped for the '$($currentInstance.DisplayName)' object for '$($server)'."
189+
            }
190+
            Else {
191+
                Write-Warning "Maintenance Mode did NOT get stopped for the '$($currentInstance.DisplayName)' object for '$($server)'."
192+
            }
193+
        }
194+
        Catch{
195+
            Write-Error "Could not stop Maintenance Mode schedule on the '$($currentInstance.DisplayName)' object for '$($server)'. Error message: $($_)."
196+
        }
197+
    }
198+
}
199+
 
200+
Stop-Transcript

0 commit comments

Comments
 (0)