In my last blog post, here, I spoke about how to place SCOM group in maintenance mode. This script is really interesting with an integration in Windows Task Scheduler. At the end, the main purpose is to plan a maintenance window of our different servers.

Let’s see how we can do that with PowerShell script.

First, I try to use the cmdlet Register-ScheduledTask, which can be used to register a scheduled task definition on a local computer. But, I quickly encountered a problem when I wanted to schedule my task every fourth Thursday of each month with the cmdlet New-ScheduledTaskTrigger. I was a little bit disappointed to see that it is not possible… Just daily and weekly recurring schedule are available… no monthly possibility… oups 😥

After a small search on the web, I found what I was looking for. I will create a COM object with the “schedule.service” ProgID (Programmatic IDentifier). It is an older method than the first solution I found but it guaranteed the possibility to schedule my task as I want.

First I need to provide some input parameters to my script:

  • TaskName: mandatory parameter containing the name ot the scheduled task
  • TaskDescr: mandatory parameter containing the description of the scheduled task
  • ManagementServer: mandatory parameter containing management server name
  • GroupName: mandatory parameter containing display name of the target group
  • DurationTimeMin: mandatory parameter containing the duration maintenance time in minutes of the maintenance task
  • Comment: mandatory parameter containing a comment for the maintenance task

Of course, I could define more parameters. Please, feel free to add more parameters to this script, according to your needs.
With PowerShell:

param(
[Parameter(Mandatory=$true)][string]
$TaskName,
[Parameter(Mandatory=$true)][string]
$TaskDescr,
[Parameter(Mandatory=$true)][string]
$ManagementServer,
[Parameter(Mandatory=$true)][string]
$GroupName,
[Parameter(Mandatory=$true)][string]
$DurationTimeMin, 
[Parameter(Mandatory=$true)][string]
$Comment
)

Now, I create my new Com object:

# Attach the Task Scheduler com object
$service = new-object -ComObject("Schedule.Service")

I connect it to my local machine:

# connect to the local machine.
$service.Connect()
$rootFolder = $service.GetFolder("\")

I define a new task which I enable, add my description coming from a parameter, allow to start my task on demand and enable the task as now:

$TaskDefinition = $service.NewTask(0)
$TaskDefinition.RegistrationInfo.Description = "$TaskDescr"
$TaskDefinition.Settings.Enabled = $true
$TaskDefinition.Settings.AllowDemandStart = $true
# Time when the task starts
$TaskStartTime = [datetime]::Now

My task will execute the script to set my SCOM group in maintenance mode. I will specify the path to my script, use PowerShell to execute my command and give arguments to my script:

# Task Action command
$TaskCommand = "powershell.exe"
# PowerShell script to be executed
$TaskScript = "C:\powershell\GroupMaintenanceMode.ps1"
# The Task Action command argument
$TaskArg = '-ExecutionPolicy Bypass "c:\powershell\GroupMaintenanceMode.ps1" -ManagementServer "' + $ManagementServer + '" -GroupName "''' + $GroupName + '''" -DurationTimeMin ' + $DurationTimeMin + ' -Reason "PlannedOther" -Comment "''' + $Comment + '''"'

At this step my task is now created, but it still needs a schedule time. You can find all the information about how to schedule a task in MSDN here. In my context, I will use create(5) to trigger the task every fourth Thursday of each month:

$triggers = $TaskDefinition.Triggers
$trigger = $triggers.Create(5)
$trigger.DaysOfWeek = '16'
$trigger.MonthsOfYear = '4095' #all month: j:1 f:2 m:4 a:8 m:16 j:32 j:64...
$trigger.WeeksOfMonth = '8'
$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH:mm:ss"

To trigger my task one time at a specific time of day, I should use:

$trigger = $triggers.Create(1)
$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH:mm:ss")

To trigger my task on a monthly schedule, every first day of the month, I can use:

$trigger = $triggers.Create(1)
$trigger.StartBoundary = $TaskStartTime.ToString("yyyy-MM-dd'T'HH:mm:ss")

All scheduling time is possible and have to be tried.
I create the action part of my schedule task, assign my command and the argument for my command:

$Action = $TaskDefinition.Actions.Create(0)
$action.Path = "$TaskCommand"
$action.Arguments = "$TaskArg"

It’s time to create my task. There are multiple possibilities to create the task, you can have a look here for more details.
I will create or update my task depending on whether or not it already exists. For information, I use the domain administrator credentials for the execution.

# 6: create or update the task if it exists
$rootFolder.RegisterTaskDefinition("$TaskName",$TaskDefinition,6,"ADSTS\Administrator","*********",1)

I open a PowerShell windows to execute my script with the following command:

.\ScheduleTask.ps1 -TaskName "Schedule Maintenance 1" -TaskDescr "Task schedule with PowerShell" –ManagementServer 'SCOM2012R2.adsts.local' -GroupName "SQL Server Production Instances" -DurationTimeMin "5" -Comment "Maintenance for Patching"

ScheduleTask1
My schedule task has been created with the action and trigger I mentioned earlier:

ScheduleTask2

ScheduleTask3

ScheduleTask4

ScheduleTask5

I  hope this blog post will help you managing your maintenance periods for SCOM groups.
Happy scripting 😉