Remove a Maintenance Window from a specified SCCM Collection

This function removes a Maintenance Window from a collection based on either the provided name or ServiceWindowSchedules ID that you can see when performing a WMI query for collection information. You can also provide an asterisk in the name to indicate a wildcard is used to identify a set of Maintenance Windows should you use for example the same naming pattern for a year with different months.

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).

The below example removes the specified Maintenance Window from the collection and returns true if a change has been made.
Remove-SCCMCollectionMaintenanceWindow without verbose

If you run the same command again you will notice that False is returned because no change has been made since none of the Maintenance Windows matches with the specified name.
Remove-SCCMCollectionMaintenanceWindow without verbose and False returned

Like all previous SCCM related functions you can run this also with the -Verbose output, below an example of multiple Maintenance Windows based on a set prefix and the removal command to show that you can use this function to delete multiple Maintenance Windows when providing an asterisk in the name.
Remove-SCCMCollectionMaintenanceWindow pattern based with Verbose

Code:

Function Remove-SCCMCollectionMaintenanceWindow
{
  <#
    .SYNOPSIS
    Removes a Maintenance Window from the collection specified either by name prefix (includes *) or by ServiceWindowSchedules ID
    .DESCRIPTION
    This function can be used to either remove a set of Maintenance Windows based on a prefix or based on a set name or ServiceWindowSchedules ID.
    If you have multiple Maintenance Windows that use the same name and you define a name they will all be removed, it is advised if that is the case to use the ServiceWindowSchedules ID.

    .EXAMPLE
    Remove-SCCMCollectionMaintenanceWindow -SCCMCollectionID <sccm collection ID> -MaintenanceWindowName "SU-2017-*"
    .EXAMPLE
    Remove-SCCMCollectionMaintenanceWindow -SCCMCollectionID <sccm collection ID> -MaintenanceWindowName "My Maint Window"
    .EXAMPLE
    Remove-SCCMCollectionMaintenanceWindow -SCCMCollectionID <sccm collection ID> -ServiceWindowSchedule "02EF1BC030080000"

    .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 or pattern used to determine which Maintenance Window(s) to remove.
    .PARAMETER ServiceWindowSchedule
    The ServiceWindowSchedule parameter is the schedule token of the Maintenance Window used to determine which Maintenance Window to remove.
    .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=$false)]
    [string]$MaintenanceWindowName,
    [Parameter(Mandatory=$false)]
    [string]$ServiceWindowSchedule,
    [Parameter(Mandatory=$false)]
    [string]$SiteServer = "mysiteserver.example.com",
    [Parameter(Mandatory=$false)]
    [string]$SiteCode = (Get-WmiObject -Namespace "root\SMS" -Class SMS_ProviderLocation -ComputerName $SiteServer).SiteCode
  )
  Begin
  {
    $RemovedMaintWindow = $False
    $ExecuteChangesOnSCCM = $False
    $MaintenanceWindowLikeMatch = $False
    $MaintenanceWindowNameSpecified = $False
    $ServiceWindowScheduleSpecified = $False
    Write-Verbose "SCCM Site Server                   : $($SiteServer)"
    Write-Verbose "SCCM Site code                     : $($SiteCode)"
    Write-Verbose "SCCM Collection ID                 : $($SCCMCollectionID)"
    If ($MaintenanceWindowName)
    {
      $MaintenanceWindowNameSpecified = $True
      Write-Verbose "Maintenance Window Name/Prefix     : $($MaintenanceWindowName)"
      If ($MaintenanceWindowName.Contains("*") -eq $True)
      {
        $MaintenanceWindowLikeMatch = $True
      }
      Write-Verbose "Maintenance Window Like Match      : $MaintenanceWindowLikeMatch"
    }
    If ($ServiceWindowSchedule)
    {
      $ServiceWindowScheduleSpecified = $True
      Write-Verbose "ServiceWindowSchedule ID           : $($ServiceWindowSchedule)"
    }
  }
  Process
  {
    If (($MaintenanceWindowNameSpecified -eq $True) -or ($ServiceWindowScheduleSpecified -eq $True))
    {
      $CollectionSettings = Get-WmiObject -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_CollectionSettings -ComputerName $SiteServer -Filter "CollectionID = '$($SCCMCollectionID)'"
      If ($CollectionSettings)
      {
        $CollectionSettings = [wmi]$CollectionSettings.__PATH
        $CollectionSettings.Get()
        $class_SMS_ServiceWindow = [wmiclass]"\\$($SiteServer)\ROOT\SMS\Site_$($SiteCode):SMS_ServiceWindow"
        $TmpServiceWindowArray = @()
        ForEach ($MaintWindow in $CollectionSettings.ServiceWindows)
        {
          $KeepMaintenanceWindow = $True
          If ($MaintenanceWindowNameSpecified -eq $True)
          {
            If ($MaintenanceWindowLikeMatch -eq $True)
            {
              If ($($MaintWindow.Name) -like "$($MaintenanceWindowName)")
              {
                Write-Verbose "Deleting Service Window Name       : $($MaintWindow.Name)"
                $KeepMaintenanceWindow = $False
                $ExecuteChangesOnSCCM = $True
              }
            }
            Else
            {
              If ($($MaintWindow.Name) -eq "$($MaintenanceWindowName)")
              {
                Write-Verbose "Deleting Service Window Name       : $($MaintWindow.Name)"
                $KeepMaintenanceWindow = $False
                $ExecuteChangesOnSCCM = $True
              }
            }
          }
          If ($ServiceWindowScheduleSpecified -eq $True)
          {
            If ($($MaintWindow.ServiceWindowSchedules) -eq $($ServiceWindowSchedule))
            {
              Write-Verbose "Deleting Service Window ScheduleID : $($MaintWindow.ServiceWindowSchedules)"
              $KeepMaintenanceWindow = $False
              $ExecuteChangesOnSCCM = $True
            }
          }
          If ($KeepMaintenanceWindow -eq $True)
          {
            $SMS_ServiceWindow = $class_SMS_ServiceWindow.CreateInstance()
            Write-Verbose "WMI Service Window Name            : $($MaintWindow.Name)"
            $SMS_ServiceWindow.Name = "$($MaintWindow.Name)"
            Write-Verbose "WMI Service Window Description     : $($MaintWindow.Description)"
            $SMS_ServiceWindow.Description = "$($MaintWindow.Description)"
            Write-Verbose "WMI Service Window Enabled         : $($MaintWindow.IsEnabled)"
            $SMS_ServiceWindow.IsEnabled = $true
            If ($($MaintWindow.IsEnabled) -eq $False)
            {
              Write-Verbose "Disabling Service Window           : Yes"
              $SMS_ServiceWindow.IsEnabled = $false
            }
            Write-Verbose "WMI Service Window Schedules ID    : $($MaintWindow.ServiceWindowSchedules)"
            $SMS_ServiceWindow.ServiceWindowSchedules = "$($MaintWindow.ServiceWindowSchedules)"
            Write-Verbose "WMI Service Window Type            : $($MaintWindow.ServiceWindowType)"
            $SMS_ServiceWindow.ServiceWindowType = "$($MaintWindow.ServiceWindowType)"
            Write-Verbose "WMI Service Window Starttime       : $($MaintWindow.StartTime)"
            $SMS_ServiceWindow.StartTime = "$($MaintWindow.StartTime)"
            $TmpServiceWindowArray += $SMS_ServiceWindow.psobject.baseobject                
          }
        } 
        If ($ExecuteChangesOnSCCM -eq $True)
        {
          #$TmpServiceWindowArray
          $CollectionSettings.ServiceWindows = $TmpServiceWindowArray
          $CollectionSettings.Put() | Out-Null
          $RemovedMaintWindow = $True
        }
      }
    }
  }
  End
  {
    return $RemovedMaintWindow
  }
}

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

Leave a Reply

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