Ever ran a report against the vSMS_ServiceWindowtable of SCCM and realized the Schedules object was…. well, not very readable?

Have no fear! Here is a c# solution.

My solution is based off of this pseudocode: How to Configure Hardware Inventory Settings

Here is the SQL Query I use:

select
    c.CollectionID
    ,c.SiteID
    ,c.CollectionName
    ,c.CollectionType
    ,c.ServiceWindowsCount
    ,c.LimitToCollectionID
    ,c.LimitToCollectionName
    ,c.ObjectPath
    ,sw.Name
    ,sw.ServiceWindowType
    ,sw.Description
    ,sw.Enabled
    ,sw.Schedules
from v_Collections c
JOIN vSMS_ServiceWindow sw on sw.SiteID = c.SiteID

I left out the piece which queries a database, and returns data rows. If you are reading this, I assume you can manage to figure that piece out.

using System;
using System.Data;
using System.Diagnostics;
namespace LIB.SCCM.Models
{
/// <summary>
/// SCCM Table - vSMS_ServiceWindow
/// </summary>
/// 
[DebuggerDisplay("{Name} - {Description}")]
public class ServiceWindow
{
public ServiceWindow(DataRow row)
{
this.Name = row.Field<string>("Name");
this.Description = row.Field<string>("Description");
this.WindowType = (ServiceWindowType)row.Field<int>("ServiceWindowType");
this.Enabled = row.Field<bool>("Enabled");
//Parse out the funky schedule...
var Schedule_HEX = row.Field<string>("Schedules");
//Split the hex string into two pieces.
string StartTime_HEX = Schedule_HEX.Substring(0, 8);
string Recurrence_HEX = Schedule_HEX.Substring(8, 8);
//Parse a long from the provided hex values, then convert that to a binary string... Lastly, Pad left, until there are 32 total bits.
var StartTime_BIN = Convert.ToString(long.Parse(StartTime_HEX, System.Globalization.NumberStyles.HexNumber), 2).PadLeft(32, '0');
var Recurrence_BIN = Convert.ToString(long.Parse(Recurrence_HEX, System.Globalization.NumberStyles.HexNumber), 2).PadLeft(32, '0');
//Parse out the start date.
int Min = Convert.ToInt32(StartTime_BIN.Substring(0, 6), 2);
int Hour = Convert.ToInt32(StartTime_BIN.Substring(6, 5), 2);
int Day = Convert.ToInt32(StartTime_BIN.Substring(11, 5), 2);
int Month = Convert.ToInt32(StartTime_BIN.Substring(16, 4), 2);
int Year = Convert.ToInt32(StartTime_BIN.Substring(20, 6), 2) + 1970;
int Duration = Convert.ToInt32(StartTime_BIN.Substring(26, 6), 2);
//Convert those values into a valid date time. Seconds are not supported in sccm schedules.
this.StartTime = new DateTime(Year, Month, Day, Hour, Min, 0);
//Parse out the duration.
int Duration_Hours = Convert.ToInt32(Recurrence_BIN.Substring(0, 5), 2);
int Duration_Mins = Convert.ToInt32(Recurrence_BIN.Substring(5, 5), 2);
//Store those values as the duration Timespan. SCCM does not support seconds in schedules.
this.Duration = new TimeSpan(Duration_Hours, Duration_Mins, 0);
//Is GMT Flag is the last digit. 
bool isGMT = Convert.ToBoolean(Convert.ToInt32(Recurrence_BIN.Substring(31, 1)));
//Parse out the flags...
int Flags = Convert.ToInt32(Recurrence_BIN.Substring(10, 3), 2);
switch (Flags)
{
case 1: //NonRecurring Schedule
this.RecurrenceType = RecurrenceType.NONE;
break;
case 2: //Recurring on predefined interval.
{
this.RecurrenceType = RecurrenceType.DAILY;
//this.RecurrenceType = RecurrenceType.
int rec_Mins = Convert.ToInt32(Recurrence_BIN.Substring(13, 6), 2);
int rec_Hours = Convert.ToInt32(Recurrence_BIN.Substring(19, 5), 2);
int rec_Days = Convert.ToInt32(Recurrence_BIN.Substring(24, 5), 2);
TimeSpan RecurEvery = new TimeSpan(rec_Days, rec_Hours, rec_Mins);
}
break;
case 3: //Recurring on weekly basis.
{
this.RecurrenceType = RecurrenceType.WEEKLY;
int rec_wDay_int = Convert.ToInt32(Recurrence_BIN.Substring(13, 3), 2);
int rec_num_weeks = Convert.ToInt32(Recurrence_BIN.Substring(16, 3), 2);
//The SCCM value for day of week starts at 1. .Net value starts at 0.
DayOfWeek rec_DayOfWeek = (DayOfWeek)(rec_wDay_int - 1);
}
break;
case 4: //Recur monthly, by weekday.
{
this.RecurrenceType = RecurrenceType.MONTHLYBYWEEKDAY;
int WeekDay = Convert.ToInt32(Recurrence_BIN.Substring(13, 3), 2);
//What day of the week this will trigger on.
DayOfWeek rec_DayOfWeek = (DayOfWeek)(WeekDay - 1);
//How many months between reoccurences
int rec_Every_N_Months = Convert.ToInt32(Recurrence_BIN.Substring(16, 4), 2);
//Which Week, ie, First, second, last, etc...
// 0 = Last, 1 = First, 2 = 2nd, 3 = 3rd, 4 = 4th.
int WeekOrder = Convert.ToInt32(Recurrence_BIN.Substring(20, 3), 2);
}
break;
case 5: //Monthly By Date - Custom schedule only!
{
//I didn't finish parsing this piece out... becase, it is not used in my environment.
this.RecurrenceType = RecurrenceType.MONTHLYBYDATE;
//strDate = Next 5 chars of strBinRecurrence convert bin2dec
//strNumMonths = Next 4 chars of strBinRecurrence convert bin2dec
//strUnused = Next 9 chars of strBinRecurrence convert bin2dec
//'Should be 0 (not used by HINV schedules)
//bIsGMT = Last char of strBinRecurrence convert bin2bool
//'0=False,1=True (should be 0, not used by HINV schedules)
//Select Case strDate
//   Case "0"
//      strFriendlyRecurrence = "Occurs the last day of every "
//   Case Else
//      strFriendlyRecurrence = "Occurs day " & strDate &_
//                              " of every "
//End Case
//strFriendlyRecurrence = strFriendlyRecurrence & strNumMonths &_
//                        " month(s)"
}
break;
}
}
public string Name { get; set; }
public string Description { get; set; }
public TimeSpan Duration { get; set; }
public bool Enabled { get; set; }
public RecurrenceType RecurrenceType { get; set; }
public ServiceWindowType WindowType { get; set; }
public DateTime StartTime { get; set; }
}
}
Share this content
  • 10
    Shares
%d bloggers like this: