Steve? Why are you writing a post on how to place a group in maintenance mode using powershell?  There are already LOTS of solutions out there to put a group in maintenance mode – why spend time on another?  Good question.  The reason?  Efficiency.

I recently was working on a project where we were placing groups in maintenance mode – some groups with as many as 500 agents in them.  Using the available powershell scripts we noticed a fair amount of latency to show in the UI that all of the agents in the group had entered maintenance mode. 

Looking at available script examples it seemed that all used the approach of identifying the group for maintenance mode and iterating though it to get a list of machines (with a for each statement) and then placing each individual agent contained in the group in maintenance mode from there.  So, for a group with 500 agents you would end up calling the routine to place the agents in maintenance mode (new-maintenancewindow) 500 times!  Not the most efficient approach.

I set out to find a method to allow calling new-maintenancewindow a single time and instead of specifying an agent, I specified a group name.  This works in the OpsMgr UI so figured it had to be workable in Powershell too.  The result of my work is the script below.  Definitely room for additional customization if needed.  I’ve done limited testing but it seems to work like a champ – and seems to be much more efficient than the individual agent approach.  Give it a spin and tell me how you like it!

Sample Commandline:
GroupatonceMM.ps1 GROUPNAME MMDURATIONINHOURS RMSSERVERNAME

Script name:  GroupatonceMM.ps1
param ($groupName, $MMDuration, $rmsServerName)

#Load the Operations Manager snapin and connect to the Root Management Server
add-pssnapin "Microsoft.EnterpriseManagement.OperationsManager.Client";
Set-Location "OperationsManagerMonitoring::";
$mgConn = New-ManagementGroupConnection -connectionString:$rmsServerName;
if($mgConn -eq $null)
{
[String]::Format("Failed to connect to RMS on '{0}'",$rmsServerName);
return;
}

Set-Location $rmsServerName;

$startTime = [DateTime]::Now
$endTime = $startTime.AddHours($MMDuration)
$MonitoringClassCG = get-monitoringclass | where {$_.DisplayName -eq $groupName}
$MonitoringGUID = get-monitoringobject $MonitoringClassCG.Id

New-MaintenanceWindow -startTime:$startTime -endTime:$endTime -reason:"ApplicationInstallation" -comment:"none" -monitoringObject:$MonitoringGUID