Using PowerShell with System Center 2012 R2 Configuration Manager Maintenance Tasks

If you have worked with the PowerShell Set-CMSiteMaintenanceTask and Get-CMSiteMaintenanceTask you most likely have already mapped the task name parameter to the actual task name. 

At this time the Get-CMSiteMaintenanceTask reference page on TechNet doesn’t list the Maintenance Task name however, you can reference the SMS_SCI_SQLTask Server WMI Class of the Configuration Manager SDK to get them.

For those that haven’t used the Set-CMSiteMaintenanceTask and Get-CMSiteMaintenanceTask you can use this table for the task names to save some time instead of figuring it out with a trial and error process. I wouldn’t be surprised if these were changed in the future to use a common set of task names for each cmdlet.

ConfigMgr Console

Get-CMSiteMaintenanceTask

Set-CMSiteMaintenanceTask

Backup Site Server

Backup SMS Site Server

BackupSiteServer

Check Application Title with Inventory Information

Check Application Title with Inventory Information

CheckApplicationTitleWithInventoryInformation

Clear Install Flag

Clear Undiscovered Clients

ClearUndiscoveredClients

Delete Aged Application Request Data

Delete Aged Application Request Data

DeleteAgedApplicationRequestData

Delete Aged Client Operations

Delete Aged Client Operations

DeleteAgedClientOperations

Delete Aged Client Presence History

Delete Aged Notification Server History

DeleteAgedClientPresenceHistory

Delete Aged Collected Files

Delete Aged Collected Files

DeleteAgedCollectedFiles

Delete Aged Computer Association Data

Delete Aged Computer Association Data

DeleteAgedComputerAssociationData

Delete Aged Delete Detection Data

Delete Aged Delete Detection Data

DeleteAgedDeleteDetectionData

Delete Aged Device Wipe Record

Delete Aged Device Wipe Record

DeleteAgedDeviceWipeRecord

Delete Aged Devices Managed by the Exchange Server Connector

Delete Aged Exchange Partnership

DeleteAgedDevicesManagedByTheExchangeServerConnector

Delete Aged Discovery Data

Delete Aged Discovery Data

DeleteAgedDiscoveryData

Delete Aged Distribution Point Usage Data

Delete Aged Distribution Point Usage Stats

DeleteAgedDistributionPointUsageStats

Delete Aged Endpoint Protection Health Status History Data

Delete Aged EP Health Status History Data

DeleteAgedEndpointProtectionHealthStatusHistoryData

Delete Aged Enrolled Devices

Delete Aged Enrolled Devices

DeleteAgedEnrolledDevices

Delete Aged Inventory History

Delete Aged Inventory History

DeleteAgedInventoryHistory

Delete Aged Log Data

Delete Aged Log Data

DeleteAgedLogData

Delete Aged Notification Task History

Delete Aged Notification Task History

DeleteAgedNotificationTaskHistory

Delete Aged Replication Summary Data

Delete Aged Replication Summary Data

DeleteAgedReplicationSummaryData

Delete Aged Replication Tracking Data

Delete Aged Replication Data

DeleteAgedReplicationTrackingData

Delete Aged Software Metering Data

Delete Aged Metering Data

DeleteAgedSoftwareMeteringData

Delete Aged Software Metering Summary Data

Delete Aged Metering Summary Data

DeleteAgedSoftwareMeteringSummaryData

Delete Aged Status Messages

Delete Aged Status Messages

DeleteAgedStatusMessages

Delete Aged Threat Data

Delete Aged Threat Data

DeleteAgedThreatData

Delete Aged Unknown Computers

Delete Aged Unknown Computers

DeleteAgedUnknownComputers

Delete Aged User Device Affinity Data

Delete Aged User Device Affinity Data

DeleteAgedUserDeviceAffinityData

Delete Inactive Client Discovery Data

Delete Inactive Client Discovery Data

DeleteInactiveClientDiscoveryData

Delete Obsolete Alerts

Delete Obsolete Alerts

DeleteObsoleteAlerts

Delete Obsolete Client Discovery Data

Delete Obsolete Client Discovery Data

DeleteObsoleteClientDiscoveryData

Delete Obsolete Forest Discovery Sites and Subnets

Delete Obsolete Forest Discovery Sites and Subnets

DeleteObsoleteForestDiscoverySitesAndSubnets

Delete Unused Application Revisions

Delete Aged Application Revisions

DeleteUnusedApplicationRevisions

Evaluate Provisioned AMT Computer Certificates

Evaluate Provisioned AMT Computer Certificates

EvaluateProvisionedAmtComputerCertificates

Monitor Keys

Monitor Keys

MonitorKeys

Rebuild Indexes

Rebuild Indexes

RebuildIndexes

Summarize Installed Software Data

Summarize Installed Software Data

SummarizeInstalledSoftwareData

Summarize Software Metering File Usage Data

Summarize File Usage Metering Data

SummarizeSoftwareMeteringFileUsageData

Summarize Software Metering Monthly Usage Data

Summarize Monthly Usage Metering Data

SummarizeSoftwareMeteringMonthlyUsageData

 

 

Current Bugs

Currently, there are a couple of bugs with each cmdlet. The Get-CMSiteMaintenanceTask doesn’t retrieve the BeginTime and LatestBeginTime properties. The Set-CMSiteMaintenanceTask requires the –DeviceName argument set although it only applies to the BackupSiteServer. You can set the argument to “ “ as a workaround to the bug. (e.g. –DeviceName “ “)

Getting BeginTime and LatestBeginTime

To get the BeginTime and LatestBeginTime properties of a task you can query the SMS_SCI_SQLTask Server WMI Class then convert the DateTime value to a hh:mm string format.

This is a sample wmi query to get the Delete Obsolete Alerts tasks:

$MT = gwmi -Namespace root\sms\site_<SiteCode> -Query "Select * from SMS_SCI_SQLTask Where SiteCode='<SiteCode>' and TaskName = 'Delete Obsolete Alerts'" -ComputerName <computername>
To output the begintime run($MT).BeginTime

When displaying either the BeginTime and LatestBeginTime properties it’ll be returned in a WMI datetime format such as 00000000050000.000000+*** however, when using the[System.Management.ManagementDateTimeConverter]::ToDateTime()method to convert it, it will throw an error. One way of getting the hours and minutes needed is parse it as a string. This function will take the datetime format and return an hh:mm string format.

Function Convert-WMITime{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[Alias("WT")] [string]$CIMdatetime)
return $CIMdatetime.Substring(8,2)+":"+$CIMdatetime.substring(10,2)
}

Getting the Days of Week

The DaysOfWeek for each task is stored as a UInt32 value however, the name of the days is represented as binary. The name of the days are required for the Set-CMSiteMaintenanceTask cmdlet and is just easier to read. 

One method of getting the day names is to convert the decimal value to binary then iterate the binary bits to create an array of day names. 

This table can help visualize the tasks that need to be done.

Decimal Value

64

32

16

8

4

2

1

Binary Position

1

1

1

1

1

1

1

Name of Day

Saturday

Friday

Thursday

Wednesday

Tuesday

Monday

Sunday

Converting the decimal to binary can be used with the .Net Convert method. Since we are working with up to 7 bits (one for each day of the week) it should be padded to the left and included 0’s for empty spaces. For instance, Thursday is the decimal value of 16 and binary value of 10000. Extra zero’s will be added to the left to ensure there are 7 values. This will in turn become 0010000.

$bDays = [Convert]::ToString($MT. DaysOfWeek,2).PadLeft(7,'0')

Match 0010000 with the above table, wherever the bit is set to 1 then add that day to an array.

$aDays = @()
$aDayNames = @("Saturday", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday")
$bDays = $bDays[0..$bDays.length]

for($i=0;$i -lt $bDays.Length;$i++){
if($bDays[$i] -eq "1"){$aDays = $aDays + $($aDayNames[$i])}
{

This is a complete function that can be used to return the DaysOfWeek UInt32 value and return an array of day names:

Function Convert-DecimaltoDays{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[Alias("D")]
[string]$Days
)
$aDays = @()
$aDayNames = @("Saturday", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday")

     $bDays = [Convert]::ToString($Days,2).PadLeft(7,'0')
$bDays = $bDays[0..$bDays.length]
for($i=0;$i -lt $bDays.Length;$i++){
if($bDays[$i] -eq "1"){$aDays = $aDays + $($aDayNames[$i])}
}
return $aDays
}