Rules Extensions –Understanding Date Time Conversion Part 2



In this post we will continue the understanding of using functions in a rules extension to manage Date Time Attributes into and out of the Metaverse. The most popular use of these DateTime functions is to convert the accountExpires attribute to the employeeEndDate attribute in the FIM / MIM Portal.

Now lets take a look at the “MapAttributesForImport” section of a Management Agent Rules extension, this section is used to manage attributes from a Connector Space or in simpler terms (a copy of the data source) and it synchronizes that data into the Metaverse and other data sources if any.

You will notice all the functions in this example all deal with DateTime in one format or another, so to simplify this I have also added a helper function that these functions all feed values into. There are 5 default Variables that are defined

1. string csAttrib;
2. string mvAttrib;
3. long dtInt;
4. string targetFormat;
5. string sourceFormat;

void IMASynchronization.MapAttributesForImport(string FlowRuleName, CSEntry csentry, MVEntry mventry)
         {
             string csAttrib;
             string mvAttrib;
             long dtInt;
             string targetFormat;
             string sourceFormat;

            //
             // TODO: write your import attribute flow code
             //
             switch (FlowRuleName)
             {
                 case "getDate":
                     mvAttrib = "deprovisionDate";
                     if (mventry.ConnectedMAs[ADMA1].Connectors.Count == 0)
                     {
                         if (mventry[mvAttrib].IsPresent && !string.IsNullOrWhiteSpace(mvAttrib))
                         {
                             DateTime depoDate;
                             if (!DateTime.TryParse(mventry[mvAttrib].Value, out depoDate))
                             {
                                 //mventry ["deprovisionDate"].Value = DateTime.Now.AddDays(90).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.000'");
                                 mventry[mvAttrib].Value = DateTime.Now.AddDays(90).ToString("yyyy-MM-ddTHH:mm:ss.000");
                             }
                             else
                             {
                                 mventry[mvAttrib].Value = DateTime.Now.AddDays(90).ToString("yyyy-MM-ddTHH:mm:ss.000");
                             }

                        }
                         else
                         {
                             mventry[mvAttrib].Value = DateTime.Now.AddDays(90).ToString("yyyy-MM-ddTHH:mm:ss.000");
                         }
                     }
                     break;

                case "removeDate":
                     mvAttrib = "deprovisionDate";
                     if (mventry.ConnectedMAs[ADMA1].Connectors.Count == 1)
                     {
                         if (mventry[mvAttrib].IsPresent)
                         {
                             mventry[mvAttrib].Values.Clear();
                         }
                     }
                     break;

                case "employeeEndDate":
                     csAttrib = "accountExpires";
                     mvAttrib = "employeeEndDate";
                     dtInt = csentry[csAttrib].IntegerValue;
                     //targetFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.000'";
                     targetFormat = "yyyy-MM-ddTHH:mm:ss.000";
                     //targetFormat = "M/d/yyyy h:mm tt";
                     sourceFormat = string.Empty;
                     GetDateString(csentry, mventry, dtInt, mvAttrib, sourceFormat, targetFormat);
                     break;

                case "pwdLastSet":
                     csAttrib = "pwdLastSet";
                     mvAttrib = "pwdLastSet";
                     dtInt = csentry[csAttrib].IntegerValue;
                     targetFormat = "M/d/yyyy h:mm tt";
                     sourceFormat = string.Empty; ;
                     if (csentry[csAttrib].IsPresent && csentry[csAttrib].IntegerValue != 0)
                         GetDateString(csentry, mventry, dtInt, mvAttrib, sourceFormat, targetFormat);
                     ///mventry[mvAttrib].Value = ConvertFileTimeToFimTimeStamp(csentry[csAttrib].IntegerValue);
                     else
                         mventry[mvAttrib].Delete();
                     break;

                case "pwdExpires":
                     csAttrib = "pwdLastSet";
                     mvAttrib = "pwdExpires";
                     dtInt = csentry[csAttrib].IntegerValue;
                     targetFormat = "M/d/yyyy h:mm tt";
                     sourceFormat = string.Empty;
                     if (csentry[csAttrib].IsPresent && csentry[csAttrib].IntegerValue != 0)
                         GetDateString(csentry, mventry, dtInt, mvAttrib, sourceFormat, targetFormat, 180);
                     ///mventry[mvAttrib].Value = ConvertFileTimeToFimTimeStamp(csentry[csAttrib].IntegerValue);
                     else
                         mventry[mvAttrib].Delete();
                     break;

                case "lastLogonTimestamp":
                     csAttrib = "lastLogonTimestamp";
                     mvAttrib = "lastLogonTimestamp";
                     dtInt = csentry[csAttrib].IntegerValue;
                     targetFormat = "M/d/yyyy h:mm tt";
                     sourceFormat = string.Empty;
                     if (csentry[csAttrib].IsPresent && csentry[csAttrib].IntegerValue != 0)
                         GetDateString(csentry, mventry, dtInt, mvAttrib, sourceFormat, targetFormat);
                     //mventry[mvAttrib].Value = ConvertFileTimeToFimTimeStamp(csentry[csAttrib].IntegerValue);
                     else
                         mventry[mvAttrib].Delete();
                     break;

                case "createdDate":
                     csAttrib = "whenCreated";
                     mvAttrib = "createDate";
                     string dateStr = csentry[csAttrib].StringValue;
                     targetFormat = "M/dd/yyyy h:mm:ss tt";
                     sourceFormat = "yyyyMMddHHmmss.0Z";
                     GetDateString(csentry, mventry, dateStr, mvAttrib, sourceFormat, targetFormat);
                     break;

            }
         }

Notice all the functions above use the following helper function “GetDateString” which requires the default variables defined earlier, “GetDateString(csentry, mventry, dtInt, mvAttrib, sourceFormat, targetFormat)”


The Helper Function below takes a values of the required variables defined by the initializing function and converts the value of the source DateTime to the Desired target DateTime. This one Helper function can be used by multiple functions because each function defines the variable that is required to process the conversion.

private static void GetDateString(CSEntry csentry, MVEntry mventry, long dtInt, string mvAttrib, string sourceFormat, string targetFormat, int days = 0)

{
     if (dtInt == 0 || dtInt == 9223372036854775807)
     {
         // This is a special condition, do not contribute and delete any current value
         mventry[mvAttrib].Delete();
     }
     else
     {
         DateTime dtFileTime = DateTime.FromFileTime(dtInt).AddDays(days);
         if (targetFormat.Equals("LONG", StringComparison.OrdinalIgnoreCase))
         {
             mventry[mvAttrib].Value = dtFileTime.ToLongDateString();

        }
         else if (targetFormat.Equals("SHORT", StringComparison.OrdinalIgnoreCase))
         {
             mventry[mvAttrib].Value = dtFileTime.ToShortDateString();
         }
         else
             mventry[mvAttrib].Value = dtFileTime.ToString(targetFormat);
         // mventry[mvAttrib].Value = DateTime.FromFileTimeUtc(dtInt).ToString(targetFormat);
     }

}

//(CSEntry csentry, MVEntry mventry, long dtInt, string mvAttrib, string targetFormat, int days = 0)

private static void GetDateString(CSEntry csentry, MVEntry mventry, string dateStr, string mvAttrib, string sourceFormat, string targetFormat, int days = 0)

{
     DateTime dt = DateTime.ParseExact(dateStr, sourceFormat, CultureInfo.InvariantCulture);
     GetDateString(csentry, mventry, dt.ToFileTime(), mvAttrib, sourceFormat, targetFormat, days);

}


Now lets take a look at the “MapAttributesForExport” section of a Management Agent Rules extension, this section is used to manage attributes from the Metaverse to the Connector Space or in simpler terms (a copy of the data source).

void IMASynchronization.MapAttributesForExport(string FlowRuleName, MVEntry mventry, CSEntry csentry)
         {

            switch (FlowRuleName)
             {

                case "accountExpires":
                     CultureInfo provider = CultureInfo.InvariantCulture;

                    if (mventry["employeeEndDate"].ToString() != "")
                     {
                         //DateTime dtFileTime = DateTime.ParseExact(mventry["employeeEndDate"].Value, "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.000'", provider);
                         DateTime dtFileTime = DateTime.Parse(mventry["employeeEndDate"].Value, provider);

                        csentry["accountExpires"].IntegerValue = dtFileTime.ToFileTime();
                     }
                     else
                     {
                         csentry["accountExpires"].Value = "9223372036854775807";
                     }

                    break;


             }
         }

To simplify this code the MapAttributesForExport section for this example only contains an attribute flow for converting the “employeeEndDate” attribute from the Metaverse to the “accountExpires” attribute in AD. This is because this is probably the only DateTime attribute in AD you would ever set outside of Active Directory.

Notice the formats of the source and the target, in this case the target is the AD Object and the attribute is the “accountExpires” attribute which only takes one format and considering the “employeeEndDate” attribute in the Metaverse should only be in the other format I did not use the helper function.

Comments (1)

  1. Really helped me the article, thank you.

Skip to main content