Function to create and set a Maintenance Window on a specified SCCM Collection

This function creates a new Service Window/Maintenance Window for a Configuration Manager collection all using WMI but does require the other previously posted functions in order to perform as expected. This prevents the need to use the other functions separately to create the Maintenance Window and performs a verification once the Maintenance Window has been created in order to ensure a success.

You need the below functions available in your PowerShell session when using this combined function.

NOTE: By including the SYNOPSIS and other information you can use get-help on the function to find out what parameters you can specify or read what this function actually can be used for. I can highly recommended to always include this information in your PowerShell function(s) so that anybody can understand it.

Examples:
In the below examples names pointing to a sitecode, collection ID or server name are blurred out (this is a real site server behind a FAKE FQDN).

Below you can see the command line and returned information that creates the requested Maintenance Window on the collection. In this example we create a Maintenance Window that starts on 22:30 on 11-9-2019 (dd-mm-yyyy), after having created the Maintenance Window a check is performed for verification which in this case returns True because it was successful.
Set-SCCMCollectionMaintenanceWindow Example without Verbose output
If you open the collection properties you can see the newly created Maintenance Window.
Set-SCCMCollectionMaintenanceWindow Created Maintenance Window Collection Properties
If you open the properties page for the newly created Maintenance Window you can see that all our provided parameters are correctly used.
Set-SCCMCollectionMaintenanceWindow created Maintenance Window Properties

Should you run the same command line as before but with the -Verbose parameter than during the function execution the value of $VerbosePreference is automatically set to Continue which means that we execute all other required functions also with the -Verbose parameter so that the full verbose output is provided. This can cause a lot of output on the screen but can help for example to determine if the other functions also use the same values.
Set-SCCMCollectionMaintenanceWindow Example with verbose

Code:

Function Set-SCCMCollectionMaintenanceWindow
{
  <#
    .SYNOPSIS
    Sets a Maintenance Window on the collection specified, if provided for the specified year/month and time.
    .DESCRIPTION
    This function requires other functions output as input in order to set the Maintenance Window on a collection.
    By default the duration in minutes is set to 5 (day and hour to 0), you can override this using parameters.
    By default the start hour is set to 23 and minute set to 00, you can override this using parameters.
    
    .EXAMPLE
    Set-SCCMCollectionMaintenanceWindow -SCCMCollectionID <sccm collection ID> -MaintenanceWindowName "My Maint Window"
    .EXAMPLE
    Set-SCCMCollectionMaintenanceWindow -SCCMCollectionID <sccm collection ID> -MaintenanceWindowName "My Maint Window" -Day 11 -Month 9 -Year 2019 -DurationDay 0 -DurationHour 3 -DurationMinute 30 -StartHour 22 -StartMinute 30
    
    .PARAMETER SCCMCollectionID
    The SCCMCollectionID parameter is the actual collection on which you want to set the new Maintenance Window.
    .PARAMETER MaintenanceWindowName
    The MaintenanceWindowName parameter is the name of the Maintenance Window
    .PARAMETER MaintenanceWindowDescription
    The MaintenanceWindowDescription parameter is optional and the the description of the Maintenance Window
    .PARAMETER Month
    The month parameter is used to define the month but if not provided the current month is set
    .PARAMETER Year
    The year parameter is used to define the year but if not provided the current year is set
    .PARAMETER Day
    The day parameter is used to define the day but if not provided the current day is set
    .PARAMETER DurationDay
    This parameter defines the duration in day(s)
    .PARAMETER DurationHour
    This parameter defines the duration in hour(s)
    .PARAMETER StartHour
    This parameter defines the starting hour (24-hour format) of the Maintenance Window if not provided a default of 23 is defined.
    .PARAMETER DurationMinute
    This parameter defines the duration in minute(s)
    .PARAMETER StartMinute
    This parameter defines the starting minute(s) of the Maintenance Window if not provided a default of 00 is defined.
    .PARAMETER SiteServer
    This parameter defines the site server to connect to and is optional as a default is provided in the function
    .PARAMETER SiteCode
    This parameter is optional and by default uses WMI to gather this based on the SiteServer parameter
  #>
 Param(
    [Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$True)] 
    [string]$SCCMCollectionID,
    [Parameter(Mandatory=$true)]
    [string]$MaintenanceWindowName,
    [Parameter(Mandatory=$false)]
    [string]$SiteServer = "mysiteserver.example.com",
    [Parameter(Mandatory=$false)]
    [string]$MaintenanceWindowDescription,
    [Parameter(Mandatory=$false)]
    [string]$SiteCode = (Get-WmiObject -Namespace "root\SMS" -Class SMS_ProviderLocation -ComputerName $SiteServer).SiteCode,
    [Parameter(Mandatory=$false)]
    [int]$DurationDay = 0,
    [Parameter(Mandatory=$false)]
    [int]$DurationHour = 0,
    [Parameter(Mandatory=$false)]
    [string]$StartHour = "23",
    [Parameter(Mandatory=$false)]
    [int]$DurationMinute = 5,
    [Parameter(Mandatory=$false)]
    [string]$StartMinute = "00",
    [Parameter(Mandatory=$false)]
    [int]$Month = (Get-Date).Month,
    [Parameter(Mandatory=$false)]
    [int]$Day = (Get-Date).Day,
    [Parameter(Mandatory=$false)]
    [int]$Year = (Get-Date).Year
  )
  Begin
  {
    $ConfigureMaintWindowSuccess = $False
    Write-Verbose "SCCM Site Server                   : $($SiteServer)"
    Write-Verbose "SCCM Site code                     : $($SiteCode)"
    Write-Verbose "SCCM Collection ID                 : $($SCCMCollectionID)"
    Write-Verbose "Maintenance Window Day             : $($Day)"
    Write-Verbose "Maintenance Window Month           : $($Month)"
    Write-Verbose "Maintenance Window Year            : $($Year)"
    Write-Verbose "Maintenance Window Hour            : $($StartHour)"
    Write-Verbose "Maintenance Window Minute(s)       : $($StartMinute)"    
    Write-Verbose "Duration Hour(s)                   : $DurationHour"
    Write-Verbose "Duration Day(s)                    : $DurationDay"
    Write-Verbose "Duration Minute(s)                 : $DurationMinute"
    If (!($MaintenanceWindowDescription))
    {
      $MaintenanceWindowDescription = "Occurs on $($Day)-$($Month)-$($Year) $($StartHour):$($StartMinute)"
    }
    Write-Verbose "Maintenance Window Name            : $($MaintenanceWindowName)"
    Write-Verbose "Maintenance Window Description     : $($MaintenanceWindowDescription)"
  }
  Process
  {
    [datetime]$MaintenanceWindowStartDateTime = Get-Date -Day $Day -Month $Month -Year $Year -Hour $StartHour -Minute $StartMinute -Second "00"
    Write-Host "Maintenance Window Date/Time is $($MaintenanceWindowStartDateTime)"
    If ($VerbosePreference -eq "continue")
    {
      $ConfigMgrStartDateTime = Convert-NormalDateToConfigMgrDate -StdDateTime $MaintenanceWindowStartDateTime -Verbose
    }
    Else
    {
      $ConfigMgrStartDateTime = Convert-NormalDateToConfigMgrDate -StdDateTime $MaintenanceWindowStartDateTime
    }
    If ($VerbosePreference -eq "continue")
    {
      $SMSScheduleMethodsToken = New-ScheduleToken -StartDateTime $ConfigMgrStartDateTime -DurationDay $DurationDay -DurationHour $DurationHour -DurationMinute $DurationMinute -Verbose
    }
    Else
    {
      $SMSScheduleMethodsToken = New-ScheduleToken -StartDateTime $ConfigMgrStartDateTime -DurationDay $DurationDay -DurationHour $DurationHour -DurationMinute $DurationMinute
    }
    Write-Verbose "SCCM Schedule Token                : $SMSScheduleMethodsToken"
    If ($VerbosePreference -eq "continue")
    {
      New-SMSServiceWindow -MaintenanceWindowName $MaintenanceWindowName -MaintenanceWindowDescription $MaintenanceWindowDescription -SCCMScheduleString $SMSScheduleMethodsToken -SCCMCollectionID $SCCMCollectionID -StartDateTime $MaintenanceWindowStartDateTime -Verbose
    }
    Else
    {
      New-SMSServiceWindow -MaintenanceWindowName $MaintenanceWindowName -MaintenanceWindowDescription $MaintenanceWindowDescription -SCCMScheduleString $SMSScheduleMethodsToken -SCCMCollectionID $SCCMCollectionID -StartDateTime $MaintenanceWindowStartDateTime
    }
    $CollectionSettings = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_CollectionSettings -ComputerName $SiteServer -Filter "CollectionID = '$($SCCMCollectionID)'"
    ForEach ($CollectionSetting in $CollectionSettings)
    {
      $CollectionSetting.Get()
      ForEach ($MaintenanceWindow in $CollectionSetting.ServiceWindows)
      {
        ForEach ($ServiceWindowName in $CollectionSetting.ServiceWindows.Name)
        {
          If ($ServiceWindowName -eq $MaintenanceWindowName)
          {
            ForEach ($ServiceWindowSchedule in $MaintenanceWindow.ServiceWindowSchedules)
            {
              If ($ServiceWindowSchedule -eq $SMSScheduleMethodsToken)
              {
                Write-Verbose "Collection Service Window Name     : $ServiceWindowName"
                Write-Verbose "Service Window Schedule            : $($MaintenanceWindow.ServiceWindowSchedules)"
                Write-Verbose "Service Window StartTime           : $($MaintenanceWindow.StartTime)"
                [datetime]$CollectionServiceWindowDateTime = [Management.ManagementDateTimeConverter]::ToDateTime($($MaintenanceWindow.StartTime))
                $SCCMMaintWindowDateTime = Get-Date $CollectionServiceWindowDateTime
                Write-Verbose "Service Window StartTime (nice)    : $SCCMMaintWindowDateTime"
                $RequestedMaintWindowDateTime = Get-Date $MaintenanceWindowStartDateTime
                Write-Verbose "Defined/Requested StartTime (nice) : $RequestedMaintWindowDateTime"
                If (($RequestedMaintWindowDateTime.Day -eq $SCCMMaintWindowDateTime.Day) -and ($RequestedMaintWindowDateTime.Month -eq $SCCMMaintWindowDateTime.Month) -and ($RequestedMaintWindowDateTime.Year -eq $SCCMMaintWindowDateTime.Year))
                {
                  Write-Verbose "Day,Month,Year matches?            : Yes"
                  If (($RequestedMaintWindowDateTime.Hour -eq $SCCMMaintWindowDateTime.Hour) -and ($RequestedMaintWindowDateTime.Minute -eq $SCCMMaintWindowDateTime.Minute))
                  {
                    Write-Verbose "Hour,Minute matches?               : Yes"
                    $ConfigureMaintWindowSuccess = $True
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  End
  {
    return $ConfigureMaintWindowSuccess
  }
}

Posted in Maintenance Window, PowerShell, System Center Configuration Manager, WMI.

Leave a Reply

Your email address will not be published. Required fields are marked *