Showing posts with label MIIS. Show all posts
Showing posts with label MIIS. Show all posts

Saturday, March 31, 2012

FIM PCNS And A Lack of Trust

If you read through the FIM documentation for setting up PCNS, you will find that either FIM and PCNS need to be in the same forest or be part of a forest trust. From http://technet.microsoft.com/en-us/library/cc720594(v=ws.10).aspx:

 

Forest trusts are only required if PCNS and ILM 2007 are located in different forests. If this is the case, a forest-level trust must be established. This is required for Kerberos mutual authentication for the ILM 2007 server to accept the request from a remote forest host.

This can become extremely limiting, especially if both forests do not have the proper forest and domain levels.  Theoretically, however, it’s possible to make Kerberos work over an External Trust (http://blogs.technet.com/b/activedirectoryua/archive/2010/08/04/conditions-for-kerberos-to-be-used-over-an-external-trust.aspx).  With an External Trust, we don’t have any of the same forest functional level restrictions, opening up PCNS as a viable option for more customers.  I would love to know if anyone has been able to get PCNS working in this configuration.  In the mean time, I will have to set up a lab and try it out.  I will report back on the results and let you know!

Thursday, May 26, 2011

TEC 2011

For those of you who were able to make it to my presentation at TEC 2011 (State side), I promised a blog entry going into some more technical detail on the Ensynch Accelerated SQL XMA (coming soon).  If you are interested in the slides I presented you can get them here.  Jeremy also had another suggestion that I will be trying out, so keep an eye out, I will let you know how it goes!

Friday, April 22, 2011

File Based Management Agents In MIIS/ILM/FIM

I had a recent need to really compare the capabilities of each of the file based Management Agents in FIM.  Can you name all five? Don't worry, I won't leave you hanging, they are:

  • Attribute-value pair text file
  • Delimited text file
  • Directory Services Markup Language (DSML) 2.0
  • Fixed-width text file
  • LDAP Data Interchange Format (LDIF)

Here are some of the things that they can and can't do (this is for you Joe) and just for kicks, I also added in the SQL MA. If you are using one of these file types in an Extensible Management Agent (XMA), the following still applies: 

 

Multi-valued Attributes

Attribute Level Updates 1

Multi-valued Level Attribute Updates 2

Attribute-value pair

YES

NO

NO

Delimited

YES 3

NO

NO

DSML

YES

NO 4

NO

Fixed-width

YES 3

NO

NO

LDIF

YES

YES

ON IMPORT ONLY 5

SQL MA

YES

YES

NO 6



Okay, now for the caveats (can’t get away without some of those):

  1. An Attribute Level Update implies that a delta import can contain only the attribute that has changed (along with the other required columns, like the type of change and the anchor)

    So, here’s what that might look like.  Suppose I have a user with the following attributes:
      ID: 12345
      Name: Sarah
      Status: Active
      Phone: 555-123-4567
                                         
    If Sarah’s phone number changes to 555-987-6543, I can simply tell FIM something like: 
      ID: 12345 
      Type Of Change: Update
      Phone: 555-987-6543

    This has the advantage of giving FIM less work to do to determine what has changed on the records being imported and greatly speeds up delta imports. 
     
  2. A Multi-valued Level Attribute Update supports adding and deleting specific values from a multi-valued attribute
     
    Let’s take another look at Sara’s record:
      ID: 12345 
      Name: Sarah 
      Status: Active 
      Phone: 555-123-4567
      Phone: 555-456-7890
                                          
    Now, Sarah has two Phone numbers, or a single attribute with multiple values. With multi-value level attribute update support, we can do things like add a new phone number to the list, delete a phone number from the list or update a phone number (in essence by doing an add of the new value and then a delete of the old one):
      ID: 12345 
      Type Of Change: Add
      Phone: 555-987-6543

    Without this support, the source system would be required to do a “replace” action and provide FIM with all of the current values at the time of import which FIM will use to override all the values that it has for that attribute.  So if we start with Sarah’s record as listed just above and add the phone number 555-987-6543 and remove the phone number 555-123-4567, we would have to pass:
      ID: 12345 
      Type Of Change: Replace
      Phone: 555-987-6543
      Phone: 555-4567-7890

    As with attribute level updates, multi-valued level attribute update can greatly reduce the amount of work that FIM needs to accomplish.  To illustrate, just imagine applying this scenario to attributes like member on an AD group that can have thousands of values.
     
  3. Using a multi-valued attribute in a delimited or fixed-width file requires the use of a header on the import file

    So for a comma delimited file this would look like: 
                                           ID, NAME, PHONE, PHONE, PHONE
                                           12345, Sarah, 555-123-4567, 555-987-6543, 555-456-7890

    This would import a record for Sarah with three attributes - ID, NAME and PHONE, the last of which will have three values. A fixed width file would work the same way.
     
  4. While the DSML specifications themselves can actually handle attribute level updates using the addRequest, delRequest and modifyRequest operations, FIM only implements the ability to import a SearchResultEntry element which must contain all of the attributes on the object

    Just a side note for those that might be curious, you can actually place the addRequest, delRequest and modifyRequest nodes in the DSML file.  FIM will be able to parse the file and it wont cause any errors, however these elements are completely ignored and aren’t processed by FIM.  I also tried sending a DSML delta to FIM with just the attribute that changed and a change type of “modify”, and I suppose not surprisingly, the object in the connector space was updated so that it only had the one attribute I specified,  all the other attributes originally on the object were removed. Had any of these attributes been defined as required, this update would have failed.
     
  5. While you can import an update to a specific value in a multi-valued attribute, if you were to export this same change to an LDIF file, it will come through as a replace operation containing all values now present on the attribute
     
  6. While the SQL MA does not support updates to a specific value on a multi-valued attribute out of the box, I hear rumor that some customizations can be done to make this happen

Small Bug Found in MIIS/ILM/FIM Identity Manager UI….

Okay, so it’s so small its hardly worth mentioning.  However, if you happen to run into the error “no-start-file-open” when running an import/export step or see the following message when trying to browse to your files while configuring the import step, you may be a victim of this issue.

UIErrorMessage

The problem occurs when you have given your MA a name that ends in one or more periods (“.”).  While this is considered legal by the Identity Manager UI (FYI - Identity Manager will not allow periods at the beginning of the MA Name), the periods will get stripped off of the MaData folder automatically by Windows.  In my test case I named my MA “ma ,, test – with __special ,, characters – ..”, a bit excessive I know, but hey, I was testing.  However, my MaData folder actually turned out like:

AddressBar

You can see why ILM could then have a problem finding the files specified in the run profile since its using the MA Name to determine the file path (i.e. its looking for it in D:\Program Files\Microsoft Identity Integration Server\MAData\ma ,, test – with __special ,, characters – ..\).  Further proof that this is the case can be found in the Event Viewer:

EventViewer

The fix?  Simply open the MA properties in Identity Manager, remove any periods from the end of the MA name and it should begin working as expected.

Sunday, April 19, 2009

Cannot connect to MMS WMI Service

Having trouble with the WMI service for MIIS/ILM? Try running the following commands at a command prompt:

  1. regsvr32 "C:\Program Files\Microsoft Identity Integration Server\Bin\mmswmi.dll"
  2. mofcomp -N:root\MicrosoftIdentityIntegrationServer "C:\Program Files\Microsoft Identity Integration Server\Bin\mmswmi.mof"

This will re-register the libraries with the OS. Give the WMI call another try, if you continue to have problems with an Access Denied error…

  1. Open the Component Services Console in the Administrative Tools Folder.
  2. Navigate to Console Root, Computers, My Computer, DCOM Config and then Microsoft Metadirectory Services.
  3. Right click on the application entry and select Properties.
  4. Go to the security tab and alter any security necessary.
  5. Click OK on the Application Properties page and close out the Component Services and Computer Management Consoles.

Sunday, April 5, 2009

A Small MIIStake

Okay, so to be fair the issue is actually with ILM (Version 3.3.118.0). In the previous version, MIIS 3.2.559.0, I would frequently run MAs from the Operations tab, like so... From the Operations tab, right click on the MA run of interest, and select the Run… option:


The resulting Run Management Agent window would then pre-populate the Management agent drop-down box and the Run profile list box with the same values as the original operation selected. Simply click OK and the selected run would be restarted (which makes it really easy to re-run a particular profile):


Now if you attempt to do follow this same procedure in ILM…


The drop down menu is not automatically set to the MA selected. If you are used to being able to simply click the OK button from this dialog, you may inadvertently run the wrong MA. In fact you can see where I ran an ADAM MA by accident in the middle of the test MA series of runs:


So the bad news, for those of you using the current version of ILM, get use to using the drop-down menu to select the MA you want to run. The good news… this is a planned fix in a future hotfix! Not sure which one, or when. Anyone out there know?

Monday, October 20, 2008

Hit or MIIS

While working out at a client site on their MIIS implementation, occasionally during a sync on one of their MAs, the Identity Manager Application would become almost completely unresponsive. I couldn't start or stop the running of an MA, execute a Preview, complete an MV Search, perform any manual Joins or Disconnections. It was all very frustrating, I would have to wait a few minutes until MIIS came back from the abyss to continue my work. The only other information that I had was from performing a SQL Profiler Trace. MIIS was definitely working on something, but what and why? <spoiler>The Answer: it has to do with the Joining activity that MIIS does while sync'ing an object.</spoiler> So, here's a little more background...

While configuring a Management Agent, you are given the ability to define rules that MIIS can use to determine if the object that its currently looking at should be linked to user data that it already has from other systems. This can be done by simply going to the Configure Join and Projection Rules in the Metaverse Designer and clicking on the New Join Rule button at the bottom:

In its simplest form, a Join Rule can be designed that directly correlates data in the source with data in MIIS. For example, if the First and Last Name are the same, join the identities together:

On the backend, MIIS is executing a query against the Metaverse table to get all of the object_ids of user's with data matching the join criteria:
select distinct [mms_metaverse].object_id from [mms_metaverse] with (holdlock) where (([<MVAttributeName>] =N'<CSAttributeValue>'))
So if we are sync'ing an individual named Joe Smith, we get a query like (and, yes, there really are both sets of parentheses around each expression):
select distinct [mms_metaverse].object_id from [mms_metaverse] with (holdlock) where (([givenName] =N'Joe')) and (([sn] =N'Smith))
It will then run the following series of queries to build a portfolio about every object_id returned:
exec mms_getmvsvall_xlock @mvobjid = '<object_id>';
exec mms_getmvmulti @mvobjid = '<object_id>';
exec mms_getmvrefasobjid @mvobjid = '<object_id>';
Once MIIS has all of this data, it can join with an existing identity for Joe Smith, if one is found. In this scenario, if more than one Joe Smith is found, MIIS will consider this a Non-match and move onto the next join rule. It will continue to execute the join rules one after the other, in turn, until either a join is made or it reaches the end of the list. If no join is made, MIIS will then move onto projection, if this option has been defined.

Now, In an actual deployment these join scenarios are usually a little more complicated. To resolve a more complicated search/match, we usually have to go out to our rules extension code. There are two places you can inject code during the join procedure. The first of these is done by using the Rules extension mapping type. This will allow you to add some additional logic around the attribute equivalency search. Here is what I mean... you are trying to join based on Social Security Number and the source system has SSNs stored as 123-456-789 but MIIS has it stored as 123456789, while these two are not technically equivalent if doing a direct evaluation, we can add code to ensure that evaluation is done "correctly" via code executed in the MapAttributesForJoin Method.

The second place we can inject code is to pick the proper join out of the X number of candidates found by the Join search. So continuing from our example above, if we have defined a join based on SSN, but our data tends to be pretty dirty and multiple people have the same SSN. We have ensured that our SSN matching is performed properly above in the MapAttributesForJoin by reformatting the data, but the match/search logic finds 5 people that could potentially match my source SSN of 123-456-789. We can add additional code in the ResolveJoinSearch method to determine, based on other data elements, say last name, that number 3 of the 5 people found is the right individual to join with.

So, here is a more real world example. What if we want to join people base on their birth date with a last name or previous last name match? In this case we will have to go out to code to determine whether a join candidate can be found. We would start by creating a join rule based on birth date:

We have decided to use a Mapping Type of Rules extension to allow us to go out to code to reformat the birth date to ensure that it matches the format in MIIS. In our rules extension, MIIS would be looking for an entry point of "cd.person#1:mccdDOB->mccdDOB" in the MapAttributesForJoinMethod:
switch (FlowRuleName)
{

     case "cd.person#1:mccdDOB->mccdDOB":

          if ( csentry["mccdDOB"].IsPresent )
          {

               //reformat the dob with style used in the MV
               values.Add( System.Convert.ToDateTime(csentry["mccdDOB"].StringValue).ToString("yyyy-MM-dd") );

          }

          break;

     default:
          throw new EntryPointNotImplementedException();

}
We have also selected the Use rules extension to resolve option. This will allow us to add code to check current and previous last names against those individuals found with the same birth date. This is done using the following code in the ResolveJoinSearch Method:
//set index of final join candidate to -1 to indicate no join found
imventry = -1;

//create a variable to keep our place in the loop
int curIndex = 0;

switch (joinCriteriaName)
{

     case "cd.student#1":

          //loop through each person to check current/prev last name
          foreach (MVEntry mventry in rgmventry)
          {

               if ( csentry["sn"].IsPresent && mventry["sn"].IsPresent)
               {

                    //try to join on last name
                    if ( csentry["sn"].StringValue == mventry["sn"].StringValue )
                    {

                         //its a match, return the index of this individual
                         imventry = curIndex;

                    }

               }
               else if ( csentry["prevSn"].IsPresent && mventry["sn"].IsPresent)
               {

                    //try to join on previous last name
                    if ( csentry["prevSn"].StringValue == mventry["sn"].StringValue )
                    {

                         //its a match, return the index of this individual
                         imventry = curIndex;

                    }

               }

               //we are moving to the next object, increment the counter
               curIndex++;

          }

          break;

     default:
          throw new EntryPointNotImplementedException();

}

//return index of individual found
return imventry;
So, now that we have all of the basics of joining down, we can get back to the problem. Did you catch it? When MIIS is performing the join search, it executes a set of stored procedures to get all of the data about the matching Metaverse objects using an exclusive lock, locking up our Metaverse table from any other reads or updates until the search is complete. This usually isn't a problem because this process happens so quickly you usually won't notice it. With that said, be very careful not to create inefficient join rules that return more than a few results. If more than a few records need to be returned and evaluated, not only will being to see a degradation in the UI response of Identity Manager, it will also take exponentially longer for the MA to complete.