SCOM Maintenance Mode PowerShell

My thanks to Matt Taylor and Kevin Holman, Ralph Kyttle, and John Kavanagh for their guidance!

Updated 24 Jun 2022



Read on if these apply
Trying to start, update, or end SCOM MM

Get alerts when MM is updated
PowerShell only in your shop!
SCORCH in play but need to convert runbooks to straight PowerShell

Ran into issues using Set-SCOMMaintenanceMode, as the cmdlet doesn’t put ALL the recursive classes under Windows Computer




Set-SCOMMaintenanceMode cmdlet is actually “by design.”  ☹


Start-SCOMMaintenanceMode assumes you want recursive action when you start maintenance mode….

Pick a Windows Computer and it places the Windows Computer object (AND all contained objects) into MM.


Computer in MM

All contained objects in MM



However, the problem is that Set-SCOMMaintenancemode does not have an understanding of recursiveness.

Command changes the MM entry for the Windows Computer, but NOT all the contained objects.  So they retain the original setting.


Health explorer looks like this, resulting in unwanted alerts





NOTE these $Time and DateTime Method are dependent on the delay between running the commands
If you start MM, and wait 5 minutes, then update, the total MM duration will be ~20 minutes




Maintenance Mode options and examples

# Setup variables for MM

# Example 1 Windows Computer

$server = “Servername.FQDN”

$instance = (get-scomclass -DisplayName “Windows Computer” |Get-SCOMClassInstance | ? { $_.DisplayName -eq $server } )

# Set time for 6 minutes

$Time = (Get-Date).addMinutes(6)

Start-SCOMMaintenanceMode -Instance $Instance -EndTime $Time -Comment “Starting Maintenance Mode.” -Reason “PlannedOther”


# Example 2

# Business needs require Windows Operating System monitoring to occur while Application is in maintenance

# My Example is Defender, could be SQL, MSMQ, Lync, Skype, or your custom class created for your application

$Class = (get-scomclass)
$Class | ? { $_.Name -like “*Defender*” } | fl DisplayName,Name
$Class | ? { $_.Name -like “*Defender*” } | fl DisplayName,Name

DisplayName : Protected Endpoint
Name        : Microsoft.WindowsDefender.ProtectedServer

DisplayName : Protected Candidate
Name        : Microsoft.WindowsDefender.ProtectedServerCandidate

DisplayName : Unprotected Endpoint
Name        : Microsoft.WindowsDefender.UnprotectedServer

DisplayName : Microsoft Windows Defender Class
Name        : Microsoft.Windows.Defender.Class

# Choose the class needed

$server = “Servername.FQDN”

$instance = ( $Class | ? { $_.Name -like “Microsoft.Windows.Defender*” } |Get-SCOMClassInstance | ? { $_.DisplayName -eq $server } )

# Verify Instance variable


PS C:\Users\scomadmin> $instance

HealthState     InMaintenanceMode  DisplayName
———–     —————–  ———–
Success               False


# Don’t forget to add time variable

$Time = (Get-Date).addMinutes(6)

# Start maintenance mode

Start-SCOMMaintenanceMode -Instance $Instance -EndTime $Time -Comment “Starting Maintenance Mode.” -Reason “PlannedOther”





Start, Update, End and Verify Maintenance mode syntax


# Start MM via PoSH cmdlet

Start-SCOMMaintenanceMode -Instance $Instance -EndTime $Time -Comment “Starting Maintenance Mode.” -Reason “PlannedOther”



# Start MM using method vs. PowerShell cmdlet

Note Recursive in $WCobj.ScheduleMaintenanceMode

$windowsComment=”Testing Maintenance Mode”

$server= “”
$instance = (get-scomclass -DisplayName “Windows Computer” |Get-SCOMClassInstance | ? { $_.DisplayName -eq $server } )
$instance.ScheduleMaintenanceMode([datetime]::Now.touniversaltime(),([datetime]::Now).addminutes($windowDuration).touniversaltime(), “$windowReason”, “$windowsComment” , “Recursive”)

# Drop Recursive if you don’t want it (but can’t imagine why you would!)



# Update MM

# Make sure you’ve put object in MM

$server= “”
$instance = (get-scomclass -DisplayName “Windows Computer” |Get-SCOMClassInstance | ? { $_.DisplayName -eq $server } )

# 15 minutes in the future
$instance.UpdateMaintenanceMode([System.datetime]::Now.touniversaltime().addminutes(15),[Microsoft.EnterpriseManagement.Monitoring.MaintenanceModeReason]::PlannedOther,[System.string]::”Adding 15 minutes to the end time.”,[Microsoft.EnterpriseManagement.Common.TraversalDepth]::Recursive);


# Stop MM

# Make sure you’ve put object in MM

# Immediate

My thanks to Jan Nevaril





Verification steps


# Verify MM

get-scommaintenancemode -ComputerName $instance.Name|fl MonitoringObjectId,StartTime,ScheduledEndTime

NOTE This will error if you’ve stopped maintenance


PS C:\Users\scomadmin> get-scommaintenancemode -ComputerName $instance.Name
get-scommaintenancemode : The Data Access service is either not running or not yet initialized. Check the event log
for more information.
At line:1 char:1
+ get-scommaintenancemode -ComputerName $instance.Name
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (Microsoft.Syste…anceModeCommand:GetSCMaintenanceModeCommand) [Get-S
COMMaintenanceMode], ServiceNotRunningException
+ FullyQualifiedErrorId : ExecutionError,Microsoft.SystemCenter.OperationsManagerV10.Commands.GetSCMaintenanceMode



# Validate MM through Operations Manager Event ID’s 1215 and 1216 logged

get-eventlog -LogName “Operations Manager” | ? { $_.EventID -eq 1215 -OR $_.EventID -eq 1216 } |fl EventID,TimeGenerated,Message

# Alternate command to check latest 100 events

get-eventlog -LogName “Operations Manager” -newest 100 | ? { $_.EventID -eq 1215 -OR $_.EventID -eq 1216 } |fl EventID,TimeGenerated,Message



# Error if object NOT in MM

Cannot find an overload for “UpdateMaintenanceMode” and the argument count: “1”.

At line:1 char:1

+ $WCobj.UpdateMaintenanceMode(([System.datetime]::Now).addminutes(15). …

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], MethodException

    + FullyQualifiedErrorId : MethodCountCouldNotFindBest


PS C:\Windows\system32>


Testing System datetime

PS C:\Windows\system32> [System.datetime]::Now.addminutes(15)


Thursday, August 24, 2017 9:18:04 AM



PS C:\Windows\system32> ([System.datetime]::Now.addminutes(15)).touniversaltime()


Thursday, August 24, 2017 2:18:16 PM






2012 PowerShell cmdlets

2016 PowerShell cmdlets

2019 PowerShell cmdlets


Ralph Kyttle Blog

DateTime Methods

SCOM 2019 Maintenance Mode

MSDN MaintenanceModeReason Method

MSDN StopMaintenanceMode Method

UpdateMaintenanceMode Method


MM deluxe custom script

Basic Admin ‘How-to’ Series


This is a series of blog posts to help with SCOM best practices, and things that make SCOM easier to administer.


Associate MPX files in Notepad++ blog

Backup management packs via PowerShell blog

Get to know your monitor blog

Load Test MP with Report blog

Load Test MP Fragments blog

Maintenance Mode PowerShell blog

Manage DB storage with DWdataRP blog

Managing Subscriptions blog

PowerShell Rule/Monitor/PerfCounter MP and Fragments blog

Registry Key discovery MP Fragment clarification blog

Run As PowerShell monitor fragment blog

Sealing Management packs with 2012R2 and 2016 blog

Subscriptions blog

Subscription Set up Guide blog

Uncommon MP Fragments blog

Verifying Overrides blog


Best Practices

Agent Management pack KH Blog

Enable proxy as a default KH blog

How to be heard blog

Manage alerts/events/performance KH Blog

Office Analytics (find where all the time goes) blog

Optimize SQL blog

Recommended Registry tweaks KH blog

SCOM Agent Version Addendum KH blog

Set SCOM Agent to remotely managed KH Blog

SQL Engineering Blog

SYSTEM CENTER 2016 Operations Manager – Anti-Virus Exclusions blog

Update VMM MP’s for SCOM when SCVMM patched blog



MP Viewer blog

Download Notepad++ here

Kevin Holman blog on extracting scripts from MP’s using Transform tool from codeplex

Test fire events using EventLog Explorer here

Alternate tool to fire any events here