Hi Everyone!
My name is Fabian Sick, Cloud Solution Architect at Microsoft Germany for Microsoft Endpoint Manager related topics. In some of my previous engagements I have been analysing and troubleshoot Site Maintenance Task related problems and developed a strategy to improve Site Maintenance Tasks.
This blog post will cover the following topics:
- What are Site Maintenance Tasks
- Sources and helpful commands
- Ensure all Site Maintenance Tasks are up and running
- Check the defined timespans
- Synchronize a global MEMCM hierarchy
- Disable Site Maintenance Tasks for Hierarchy Updates
What are Site Maintenance Tasks
The MEMCM built-in Maintenance Tasks can be configured and used to automatically clean up obsolete and old data from your Configuration Manager database. The Site Maintenance Tasks are located at:
Administration > Overview > Site Configuration > Sites > Properties > Site Maintenance
Starting with Configuration Manager Version 1906, there is an additional category at the bottom of the console.
If you open one of these tasks, you can enable/disable it, define the data scope (e.g. the age of data) and the schedule, in which this task attempts to run and perform the intended operation. Note: You cannot define the exact start time of the individual task. Configuration Manager controls the amount and sequence of all scheduled tasks and continuously evaluates, if there is enough time left to start and complete the next task within the allowed timeframe.
If there is an open slot during the defined timeframe, the task will be executed. If the timeframe is over or nears to end shortly, the task will or may not be started and waits until the next scheduled run. Only the ‘Backup SMS Site Server’ Task will terminate other running tasks, to ensure and enforce its own completion.
Sources and Helpful Commands
Microsoft Documentation:
Maintenance tasks for Configuration Manager
Reference for maintenance tasks in Configuration Manager
Related Logs:
%MECM_installdir%\Logs\smsdbmon.log
SQL Execution Status:
Select * from SQLTaskStatus
Enforce a Site Maintenance Task to ‘run now’:
Powershell (Credits go to Herbert Fuchs for this script):
$SiteCode = 'FOX'
$MT = Get-CMSiteMaintenanceTask -SiteCode $SiteCode -Name 'Delete Aged Scenario Health History'
$MethodParam = New-Object 'System.Collections.Generic.Dictionary[String,Object]'
$MethodParam.Add('SiteCode',$($SiteCode))
$MethodParam.Add('TaskName',$($MT.TaskName))
$ConfigMgrCon = Get-CMConnectionManager
$ConfigMgrCon.ExecuteMethod('SMS_SQLTaskStatus','RunTaskNow',$MethodParam)
SQL:
Update SQLTaskSiteStatus set RunNow = '1' where taskName = '$TaskName' and SiteNumber = '$SiteNumber'
Get Runtime:
SQL:
SELECT *,
DATEDIFF(ss,LastStartTime,LastCompletionTime)
AS Runtime, SiteCode = CASE SiteNumber
WHEN '0' THEN 'CAS'
WHEN '1' THEN 'PS1'
WHEN '8' THEN 'PS2'
WHEN '9' THEN 'PS3'
ELSE 'Help'
END from SQLTaskSiteStatus
Where LastStartTime like '%2021%'
--AND SiteNumber = '1'
order by Runtime DESC
/*Available Timespans:
hour hh
minute mi, n
second ss, s
millisecond ms
microsecond mcs
nanosecond ns*/
Ensure all Site Maintenance Tasks are up and running
Using the Get Runtime SQL Query will give you an overview of all Site Maintenance Tasks on your Site with a LastStartTime timestamp in 2021.
If you find a task with a negative value in the ‘Runtime’ column, it’s an indicator that the task is not running properly and did not complete successfully on the last attempt (please ignore the ‘Evaluate Provisioned AMT Computer Certificates’ if it shows up, it’s an outdated task).
To fix a maintenance task with negative runtime, you can use the "Enforce a Site Maintenance Task to ‘run now’” Powershell Script or SQL Query to trigger the task immediately, regardless of its defined schedule:
After this task is completed, the data is cleaned up and removed from the database. If this task is still failing, you will have to start troubleshooting the specific task.
The most common reason for a failing task, is when its overlapping with other tasks. Sometimes the task cannot be started during the defined timeframe or will be terminated by the “Backup SMS Site Server” task, which will result in the intended data not getting cleaned up and will continue to pile up. This may kick off an avalanche of problems coming your way.
Check the defined timespans
The most challenges are:
- Ensure that all Site Maintenance Tasks are running
- Ensure that there are no blocking tasks
- Synchronize the tasks with the backup
- Ensure that the load is evenly balanced
So I recommend all to build a view (Example Excel Sheet is attached) and enter the ‘external’ indicators like:
- Distribution Point Content Validation
- Collection Evaluation
- External SQL Backup
- Maintenance Scripts (for example Ola Hallengren)
After that, you should add the Active Site Maintenance Tasks and the Runtime for this Site:
Now you can start to plan the Site Maintenance Tasks. I prefer a system where ‘related categories’ get consolidated and the runtime does not exceed 50% of the defined timeslot:
Summarized Categories:
- Specific Site Cleanup Tasks
- The Central Administration Site and the Primary Site got separated Tasks which are only vailable on the specific Site Role
- Client related Information Cleanup
- Delete all Client related stuff
- Replication Data
- All Data which has to be replicated at the Infrastructure
- Maintenance Scripts
- Like Ola Hallengren SQL Maintenance Scripts
- Backup
Synchronize a Global MECM hierarchy
I recommend to synchronize the Site Maintenance Task Timeslots in a hierarchy.
This will benefit in:
- Minimizing the administrative effort
- Minimizing the replication data
- Minimizing the replication time, especially during a Disaster Recovery
This is quite easy if you have a hierarchy running in the same time zone. If you are running a global hierarchy, I would recommend using the time zone of your CAS as the baseline time and calculate to synchronize it with the other time zones of your primary sites (Example: CAS runs in EMEA and the Primary Site on UTC +6):
Now you can simply copy/paste the timespans to the other time zone and synchronize the global Replication Data.
Disable Site Maintenance Tasks for Hierarchy Updates
It’s a Microsoft recommendation to ensure that no Site Maintenance Tasks are running during an MECM hierarchy update. To ensure this I recommend to disable all Tasks. But the work doing this manually step by step is a time wasting action so I would like to share three Powershell scripts with you to disable the Tasks:
Preparation:
Copy the attached Scripts to your Server and create the following Folders:
- Backup
- Data
- Logs
Edit the following Points at the Scripts:
- $Sitecode (Script 1)
- $ProviderMachineName (Script 1)
- %Scriptpath% (Script 1, 2, 3)
1_Get_Site_Maintenance_Tasks.ps1
This is the first script will create an .csv file with all Site Maintenance Task values. If you run it the second time it will backup your existing .csv File to the Backup folder. This ensures that no data is lost when someone runs this script on the wrong time.
$SiteCode = "XYZ"
$ProviderMachineName = "Servername.FQDN"
$ExportFile = "%Scriptpath%\Data\SiteMaintenanceValues.csv"
$Bkup = "%Scriptpath%\Backup\SiteMaintenancesValues_"+[DateTime]::Now.ToString("ddMMyyyy_hhmmss")+".csv"
if (Test-Path $ExportFile)
{
Copy-Item -Path $ExportFile -Destination $Bkup
Remove-Item $ExportFile
}
$initParams = @{}
if((Get-Module ConfigurationManager) -eq $null)
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" @initParams
}
if((Get-PSDrive -Name $SiteCode -PSProvider CMSite -ErrorAction SilentlyContinue) -eq $null) {
New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $ProviderMachineName @initParams
}
Set-Location "$($SiteCode):\" @initParams
Get-CMSiteMaintenanceTask | Export-csv $ExportFile
2_Disable_Site_Maintenance_Tasks.ps1
This script is the second one and will disable all enabled Tasks except 'Update Application Catalog Tables' which are marked es -enabled out of the .csv of the first script.
$Values = Import-CSV "%Scriptpath%\Data\SiteMaintenanceValues.csv"
$Log = "%Scriptpath%\Logs\Disable_SiteMaintenanceTasks.log"
$Time = Get-Date -Format "dd-MM-yyyy // hh-mm-ss"
"$Time New Run - Set back to default Values." | out-file "$Log" -Append
foreach ($Item in $Values)
{
$SiteCode = $Item.Sitecode
$ProviderMachineName = $Item.PSComputerName
$DeleteOlderThan = $Item.DeleteOlderThan
$DeviceName = $Item.DeviceName
$Name = $Item.TaskName
"Start working at $Name on $SiteCode." | out-file $log -Append
$initParams = @{}
if((Get-Module ConfigurationManager) -eq $null) {
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" @initParams
}
if((Get-PSDrive -Name $SiteCode -PSProvider CMSite -ErrorAction SilentlyContinue) -eq $null) {
New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $ProviderMachineName @initParams
}
Set-Location "$($SiteCode):\" @initParams
Set-CMSiteMaintenanceTask -SiteCode $SiteCode -MaintenanceTaskName $Name -Enabled 0
"Finished $Name on $SiteCode" | out-file $log -Append
"---" | out-file $log -Append
}
3_Enable_Site_Maintenance_Tasks.ps1
This is the third script and should run after the Update is done. It will enable all -enabled marked Site Maintenance Tasks except of "Backup SMS Site Server". The "Backup SMS Site Server" has to be enabled manually. This is caused by the .csv backuped data. If you run an Environment with an delocated SQL Server the Backup Path Value will be stored as "F:\SCCM_Backup|Y:\SQL_Backup" and Powershell is unable to work with the pipe at the Value. I also prepared the opportunity to write the settings back but it’s not necessary because the values will be saved at the Infrastructure.
$Values = Import-CSV "%Scriptpath%\Data\SiteMaintenanceValues.csv"
$Log = "%Scriptpath%\Logs\Enable_SiteMaintenanceTasks.log"
$Time = Get-Date -Format "dd-MM-yyyy // hh-mm-ss"
"$Time New Run - Set back to default Values." | out-file "$Log" -Append
foreach ($Item in $Values)
{
$SiteCode = $Item.Sitecode
$ProviderMachineName = $Item.PSComputerName
$DeleteOlderThan = $Item.DeleteOlderThan
$DeviceName = $Item.DeviceName
$Name = $Item.TaskName
$Enabled = $Item.Enabled
if ($Enabled -eq 'TRUE')
{
"Start working at $Name on $SiteCode." | out-file $log -Append
$initParams = @{}
if((Get-Module ConfigurationManager) -eq $null) {
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" @initParams
}
if((Get-PSDrive -Name $SiteCode -PSProvider CMSite -ErrorAction SilentlyContinue) -eq $null) {
New-PSDrive -Name $SiteCode -PSProvider CMSite -Root $ProviderMachineName @initParams
}
Set-Location "$($SiteCode):\" @initParams
if ($Name -eq "Backup SMS Site Server")
{
"$Name could not be restored." | out-file $log -Append
"---" | out-file $log -Append
}
else
{
Set-CMSiteMaintenanceTask -Name $Name -Enabled 1 -SiteCode $SiteCode
}
"Enabled $Name on $SiteCode" | out-file $log -Append
"---" | out-file $log -Append
}
else
{
"$Name on $SiteCode is deactivated per Design and will be skipped." | out-file $log -Append
"---" | out-file $log -Append
}
}
Fabian Scherer
CE
Disclaimer
The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.