Font Size

SCREEN

Cpanel

o IT

SCCM schedule token parser

System Center Configuration Manager still surprise me from time to time. Few days ago i need to create dump from SCCM database to get detailed information's about all collections and theirs settings. All properties like LastChangeTime, LastMemberChangeTime etc. are in readable time-format. But the most important property - schedule - is scrambled in 16-char string called SMS schedule token.

This token contains information's about how often and when is the collection updated. It is used also for scheduling HW and SW inventory on the clients. And how to read this token? There are several ways how to convert it to readable format:

 

  • On-paper manual method

 

using the algorithm described by Jeff Huston in this article: http://jeff.squarecontrol.com/archives/92

 

  • WMI method

 

Connect to SMS provider and invoke ReadFromString or WriteToString WMI method

 

  • Powershell

 

Import ConfigMgr powershell module and use New-CMSchedule or Convert-CMSchedule cmdlet

The last two options requires to have access  to the SMS provider or computer with ConfigMgr powershell module. Also the output is not user friendly. Therefore I have created simple C program to do the work without any prerequisites. Here are some examples of the outputs:

 

Input

Output

Enter Schedule string. : A9788980001B4000

This is a custom schedule with startTime: 24 Aug 2008 at 11:42

Evaluated every 2 week(s) on Tuesday at 11:42.

Enter Schedule string. : 0001200000100038

This is a simple schedule.

Evaluated every 7 day(s).

Enter Schedule string. : 7D98898000280400

This is a custom schedule with startTime: 24 Aug 2008 at 12:31

Evaluated the last day of every 1. month(s) at 12:31.

There is no error control implemented so keep in mind that when you provide bad schedule token to the script, you will receive nonsense in the output. Already compiled program can be downloaded here: SCCM_ScheduleString_parser.zip

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* FUNCTIONS */
unsigned long long int parse_DecBin(unsigned long long int number, int start, int lenght) {
int rem, binary=0, i=1, counter=32;
    while (number!=0) {
        rem=number%2;
        number/=2;
        counter--;
        if ((counter < (lenght + start -1)) && (lenght > 0)) {
            binary+=rem*i;
            i*=10;
            lenght--;
        }
    }
    return binary;
}
int binary_decimal(int number) {
int decimal=0, i=0, rem;
    while (number!=0) {
        rem = number%10;
        number/=10;
        decimal += rem*pow(2,i);
        ++i;
    }
    return decimal;
}
/* MAIN */
int main(void) {
unsigned long long int strHex, strHexStarttime, strHexSchedule;
int strScheduleType, strStartMin, strStartHour, strStartDay, strStartMonth , strStartYear;
int  strFlags;
int strMinutes, strHours, strDays, strWeekDay, strNumWeeks, strNumMonths, strWeekOrder, strDate;
char *days_of_week[] = {"","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
const char *month[] = {"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
const char *week_order[] = {"Last","First","Second","Third","Fourth",};
    printf("Enter Schedule string. : ");
    scanf("%llx", &strHex);
    strHexStarttime = (strHex>>32) & 0xFFFFFFFF;
    strHexSchedule = strHex & 0xFFFFFFFF;
/* PARSING Schedule StartTime */
    if (strHexStarttime == 0x00012000) {
        printf("This is a simple schedule.\n");
        strScheduleType = 0;
    }
    else {
    printf("This is a custom schedule with ");
    strScheduleType = 1;
    strStartMin = binary_decimal(parse_DecBin(strHexStarttime,1,6));
    strStartHour = binary_decimal(parse_DecBin(strHexStarttime,7,5));
    strStartDay = binary_decimal(parse_DecBin(strHexStarttime,12,5));
    strStartMonth = binary_decimal(parse_DecBin(strHexStarttime,17,4));
    strStartYear = binary_decimal(parse_DecBin(strHexStarttime,21,6)) + 1970;
    printf("startTime: %d %s %d at %02d:%02d\n",strStartDay, month[strStartMonth], strStartYear, strStartHour, strStartMin);
 }
/* PARSING Schedule Recurrence */
    strFlags = binary_decimal(parse_DecBin(strHexSchedule,11,3));
    switch (strFlags) {
    // SMS_ST_NonRecurring
    case 1:
        printf("With no evaluation schedule");
        strScheduleType = 0;
        break;
    // SMS_ST_RecurInterval
    case 2:
        strMinutes = binary_decimal(parse_DecBin(strHexSchedule,14,6));
        strHours = binary_decimal(parse_DecBin(strHexSchedule,20,5));
        strDays = binary_decimal(parse_DecBin(strHexSchedule,25,5));
        if (strMinutes != 0){
            printf("Evaluated every %d minute(s)",strMinutes);
        }
        else if (strHours != 0) {
            printf("Evaluated every %d hour(s)",strHours);
        }
        else if (strDays != 0) {
            printf("Evaluated every %d day(s)",strDays);
        }
        break;
    // SMS_ST_RecurWeekly
    case 3:
        strWeekDay = binary_decimal(parse_DecBin(strHexSchedule,14,3));
        strNumWeeks = binary_decimal(parse_DecBin(strHexSchedule,17,3));
        printf("Evaluated every %d week(s) on %s",strNumWeeks,days_of_week[strWeekDay]);
        break;
    // SMS_ST_RecurMonthlyByWeekday
    case 4:
        strWeekDay = binary_decimal(parse_DecBin(strHexSchedule,14,3));
        strNumMonths = binary_decimal(parse_DecBin(strHexSchedule,17,4));
        strWeekOrder = binary_decimal(parse_DecBin(strHexSchedule,21,3));
        printf("Evaluated the %s %s of every %d month(s)",week_order[strWeekOrder], days_of_week[strWeekDay], strNumMonths);
        break;
    // SMS_ST_RecurMonthlyByDate
    case 5:
        strDate  = binary_decimal(parse_DecBin(strHexSchedule,14,5));
        strNumMonths  = binary_decimal(parse_DecBin(strHexSchedule,19,4));
        if (strDate == 0) printf("Evaluated the last day of every %d. month(s)",strNumMonths);
        else printf("Evaluated day %d of every %d. month(s)",strDate, strNumMonths);
        break;
    default:
        printf("Wrong strFlag");
        strScheduleType = 0;
    }
    if (strScheduleType == 1) printf(" at %d:%d.\n",strStartHour, strStartMin);
    else printf(".\n");
 return 0;
}

Přidat komentář