Rules Extensions – MapAttributesForImport


Update 1/30/2017 (working on Code formatting for presentation)

In this post we will focus on the following section of the Management Agent Rules Extension.

 

In the Synchronization Service click on the MA that you wish to map the Attribute Flows to the above Code.

In this example we were mapping the accountExpires attribute from an object in the Connector Space to an object in the Metaverse converting the value from an integer value to its String equivalent.

Lets take a look at a User Object in Active Directory who has the accountExpires attribute set.

 

this is what it looks like in the ADUC GUI but if we look at the actual value in ADSI Edit or on the Attribute Editor Tab of the Object in ADUC

 

so the actual value within AD is 131026644000000000

When syncing this Value with the FIM / MIM Portal which needs this attribute to be converted to its Date Time Format we use this MapAttributesForImport post as an example to achieve this task.

## Additional information on “IMASynchronization.MapAttributesForImport Method”  can be located here

 

void IMASynchronization.MapAttributesForImport( string FlowRuleName, CSEntry csentry, MVEntry mventry)
        {
            //
            // TODO: write your import attribute flow code
            //
            throw new EntryPointNotImplementedException();
        }

 

In a previous post we detailed 2 Way Account Expires Rules Extension , which utilized the “IMASynchronization.MapAttributesForImport Method” but also focused on the importance of equal precedence and the “IMASynchronization.MapAttributesForExport” method. In this post we will focus on the actual “IMASynchronization.MapAttributesForImportmethod as opposed to an individual function such as accountExpires to employeeEndDate.

 

Now lets look deeper into MapAttributesForImport, the following code snippet includes helper functions which we will point out in the follow up post. For this post we will focus on only the section that is used to Map Attributes for Import or more accurately said the “IMASynchronization.MapAttributesForImport” method and for that reason I have removed all the other methods that would be needed to compile a functioning .dll , the goal is to provide some explanation of how to build your Custom MA Extension one method at a time.


void IMASynchronization.MapAttributesForImport(string FlowRuleName, CSEntry csentry, MVEntry mventry)
{
switch (FlowRuleName)
   {
    case “Getdate”:
          if (mventry.ConnectedMAs[“Contoso ADMA”].Connectors.Count == 0)
          {
                if (mventry[“deprovisionDate”].IsPresent)
                {
                      DateTime depoDate;
                      if (!DateTime.TryParse(mventry[“deprovisionDate”].Value, out depoDate))
                      {
                            mventry[“deprovisionDate”].Value = DateTime.Now.AddDays(90).ToString(“yyyy-MM-ddTHH:mm:ss.000”);
                      }
                      else
                      {
                            mventry[“deprovisionDate”].Value = DateTime.Now.AddDays(90).ToString(“yyyy-MM-ddTHH:mm:ss.000”);
                      }
                  }
                  else
                  {
                       mventry[“deprovisionDate”].Value = DateTime.Now.AddDays(90).ToString(“yyyy-MM-ddTHH:mm:ss.000”);
                  }
          }
    break;
 
    case “RemoveDate”:
          if (mventry.ConnectedMAs[“Contoso ADMA”].Connectors.Count == 1)
          {
                if (mventry[“deprovisionDate”].IsPresent)
                {
                      mventry[“deprovisionDate”].Values.Clear();
                 }
          }
    break;
 
    case “employeeEndDate”:
          if (csentry[“accountExpires”].IntegerValue == 0 || csentry[“accountExpires”].IntegerValue == 9223372036854775807)
               {
                        // This is a special condition, do not contribute and delete any current value
                        mventry[“employeeEndDate”].Delete();
                    }
                    else
                    {
                        DateTime dtFileTime = DateTime.FromFileTime(csentry[“accountExpires”].IntegerValue);
                        mventry[“employeeEndDate”].Value = dtFileTime.ToString(“yyyy’-‘MM’-‘dd’T’HH’:’mm’:’ss’.000′”);
               }
    break;
 
     case “pwdLastSet”:
          if (csentry[“pwdLastSet”].IsPresent && csentry[“pwdLastSet”].IntegerValue != 0)
          {
                mventry[“pwdLastSet”].Value = ConvertFileTimeToFimTimeStamp(csentry[“pwdLastSet”].IntegerValue);
          }          
          else
          {
                mventry[“pwdLastSet”].Delete();
          }
    break;
 
    case “lastLogonTimestamp”:
          if (csentry[“lastLogonTimestamp”].IsPresent && csentry[“lastLogonTimestamp”].IntegerValue != 0)
          {
                mventry[“lastLogonTimestamp”].Value = ConvertFileTimeToFimTimeStamp(csentry[“lastLogonTimestamp”].IntegerValue)
          }
          else
          {
                mventry[“lastLogonTimeStampString”].Delete()
          }
    break;
                   
    case “GetDomain”:
           mventry[“domain”].StringValue = getDomain(csentry);
    break;
                   
    case “objectSidString”:
          byte[] objectSidString = csentry[“objectSid”].BinaryValue;
          mventry[“objectSidString”].StringValue = ConvertSidToString(objectSid);
    break;
   
}
}

// The below Section is the supporting Helper functions that are used in some of the attribute attribute flows listed above.
       
    #region Help Functions
 
    private static string ConvertFileTimeToFimTimeStamp(long fileTime)
    {
        return DateTime.FromFileTimeUtc(fileTime).ToString(“yyyy-MM-ddTHH:mm:ss.000”);
    }
   
    private static bool shouldProject(CSEntry csentry, out string MVObjectType)
    {
        string fsp = “foreignSecurityPrincipal”;
        const string FSP = “foreignSecurityPrincipal”;
        const string ADMA1 = “Contoso ADMA”;
        const string ADMA2 = “Fabrikam ADMA”;
        const string ADMA3 = “Fabrikam SharePoint ADMA”;
        bool ShouldProject = false;
        MVObjectType = null;
        switch (csentry.MA.Name)
        {
            case ADMA3:
            switch (csentry.ObjectType)
                case FSP:
                {
                    MVObjectType = fsp;
                    if (csentry[“whatever”].StringValue.Length >= 30)
                    {
                        ShouldProject = true;
                    }
                }
                break;
        }
        break;
        case ADMA2:
        break;
        case ADMA1:
        break;
       
        return ShouldProject;
    }
   
    string getCSValueAsString(CSEntry entry, string attribName, bool forceUpper = false)
    {
        if (entry[attribName].IsPresent)
            if (forsceUpper)
                return entry[attribName].StringValue.ToUpper();
            else
                return entry[attribName].StringValue;
            else
                return null
    }
    private static string ConvertSidToString(byte[] objectSid)
    {
        string objectSidString;
        SecurityIdentifier SI = new SeurityIdentifier(objectSid, 0);
        objectSidString = SI.ToString();
        return objectSidString;
    }
#endregion

}

 

NOTE:

After you have you code compiled for all attribute flows that will call one of the functions in this method be sure to select the flow direction of Import and use the case when setting the Flow rule name: which is within the Advanced mapping type See Management Agent Advanced Attribute Flows Post.

Additionally be sure to select all attributes from the Data Source that the function uses to build the value for the Metaverse attribute.

 

Questions? Comments? Love FIM/MIM so much you can’t even stand it?

EMAIL US!

>WE WANT TO HEAR FROM YOU<

## https://blogs.msdn.microsoft.com/connector_space##

Comments (0)

Skip to main content