Changing A Value Used By Join Logic

Today I’d like to take a few moments and discuss something that I think is a common misconception around join logic. Let’s say we have a simple environment with a FIM portal and Active Directory. For user objects, let’s say we’re joining on AcountName->sAMAccountName. The question I get asked quite frequently is, “What happens if I change sAMAccountName in AD? Will that break my join?”. While this would seem logical (after all, if that value changes, how will FIM know to associate those people?), the answer may surprise you. As it turns out, changing the join attribute on the ADMA will not break joins. Don’t believe me? Let’s step through the process…

First, let’s take a look at the configured join logic on our ADMA:

Here we see two configured rules. First, attempt a join on “employeeNumber->PoliticianID”. If that fails, attempt a join on “sAMAccountName->accountName”.

Likewise, if we look at our inbound user synchronization rule, we see the following relationship mapping:

Again, “sAMAccountName->accountName”, as well as a static attribute flow of the same:

If we pick a random pre-existing user in the FIM portal to look at, we can see both the Account Name (sAMAccountName)

As well as the PoliticianID (employeeNumber).

So, we now know that we are joining (or at least attempting to join) on “sAMAccountName -> accountName” or “employeeNumber -> PoliticianID”. We have also now confirmed both of those attributes on our target side (in this case, the FIM portal). Knowing this, let’s go change one (or both) of those values in Active Directory.

Here, we have added a “b” to the sAMAccountName

And changed the employeeNumber from “0016” to “1616”.

With both attributes changed, when we do an import of the ADMA, we should see one update (for our modified user). Following that with a synchronization, we can now check the FIMMA “pending exports” and should see:

Here, we see the old and new attribute values for both AccountName (sAMAccountName) and PoliticianID (employeeNumber). Both are anchor attributes used for join logic, both have now been changed in the data source.

Following an export of the FIMMA, we can now get into the portal and will see:

Notice both “Account Name” and “PoliticianID” have been changed.

Now, for the question that’s on everyone’s mind: how? The answer is both simple and complex. Simple in that once an object has been managed by FIM (i.e., the initial join has occurred for pre-existing objects, or the user has been provisioned in the case of new objects), FIM no longer associates that object using the anchor attributes. Rather (and here comes the complexity), relationships between the connector space and metaverse are actually maintained in link tables within the SQL database. I don’t want to get too specific on this piece, but the main thing is that objectID is the value in use (which equates to csObjectID in the connector space and mvObjectID in the metaverse). It is also worth noting that join and projection logic is skipped once an object reaches the state of “connector”. In other words, once  an initial association (join) has occurred, sAMAccountName is, essentially, no longer needed (because the object is now considered a regular connector).

Questions? Comments? Love FIM so much you can't even stand it?


## ##

Comments (10)
  1. Mike@UNIBZ says:

    @ktackett, @Anthony:
    I think you both are undoubtedly FIM experts and still I think this article could have been written in a clearer and “cleaner” way.
    In my opinion the most problematic point is the phrase “…changing the anchor attribute on the ADMA will not break joins…”. It connects two concepts which – and I think we all agree – are not connected at all! The term “anchor” is only used (in official MS documentation) to nominate the attribute by which an MA maintains the correlation between an external system and a connector space object. And this is true for (probably) every MA. The ADMA is somewhat hiding the anchor (=objectGUID attribute), the SQLMA is (obviously) leaving it up to the admin to decide, but both use an anchor attribute. This is the key point!
    Join rules are not related to the term “anchor” in the above sense. And you should only use it in the above sense! The correlation between connector space objects and metaverse objects is maintained – and I think we all still agree – by the “internal database link”. The Join rule does not maintain any “link”, it is only evaluated in the absence of such “link”, using some (more or less arbitrary) attributes.

    1. hmmmmmm
      When we speak of “link” between Connector Space and Metaverse we are speaking in regards to the object is clearly defined when viewing the object in the Connecter Space looking at the Lineage where it displays info about how the object is “connected” to the MV and other Data sources. Doing so you can see which MA Projected the object or if which MAs the object was provisioned to or even which MAs the Object has a “join” to hence the “link”

  2. Fahad says:

    Nice post. However this does not work for any other MAs. E.g I am using a SQL MA and sAMAccountName as the AnchorID. sAMAccountName is the only attribute unique in this situation. There are instances where the sAMAccountName has to change but this is a DeleteAdd for FIM. Is there any other way the sAMAccountName which used as an AnchorID can be changed?

  3. itch76 says:

    hey guys !

    Thank for the exchange.

    I've found a solution to my problem !

    I have changed my AD connector filter from "declared import filter" to a "rules extension" where I disconnect the object if I detect an update of the attribute used by join logic:

    Moreover, this flow chart helped me a lot to understand in which order rules are called:…/jj572803%28v=ws.10%29.aspx

    This flowchart give me the idea to play with filter to solve my problem:

    in my ADMAExtension code:

    public bool FilterForDisconnection(CSEntry csentry){

     check that csentry and mventry exists and are not null


     //if employeeID is update, object is disconnected

     if (csentry["employeeID"].Value != mventry["employeeID"].Value){

       return true;



     other filter code


     return false;


    So now, i planned two successive sync where:

    first sync : cs_object is set as disconnector (with code above)

    second sync : cs object is re-evaluated and rejoin or projected with new employeeID value

    I don't how how much i am clear with my explanations, but your exchange, and more generally your blog helped me a lot.

    Thx again,


  4. @Nosh

    Let me first thank you for visiting the blog and adding a much needed conversation around an extremely complex topic. let me also add that there was a time when people might have respectfully disagreed with columbus when he believed the earth was flat but it didn't stop him from making his famous voyage across the sea, nor did it make the earth less round in fact it did quite the opposite. My colleague and i often re read, and edit our previous post to endure that every effort is taken to provide the most detailed post written and the least technical way to reach the broadest audience. Some topics are not as easily written in this format due to the nature of the topics / technology. Now with that said a lot of times people have issues and when searching the internet have a hard time locating a post that is detailed enough to provide an answer but broad another to be not specifically to one scenario.

    Now you are absolutely correct "Anchors" and "Join Logic" are different in fact they aren't even close to being the same. The Anchor is a characteristic that must exist at the data source and "Join Logic" is calculated from the CS (Connector Space) into the MV (Metaverse) with out the Anchor object the object would not have made it that far.

    In the example of a SQL DB if i have rows of data with the anchor attribute set for employeeID than not only does employeeID have to exist it also needs to be unique. After the import from the SQL DB into the CS it is the Sync that takes that object and goes thought the process of Join Project and Provision..

    Is there an object in the Metaverse that meets the criteria of the Join Logic if yes it attempts to join and with a successful join depending on Attribute Precedence were determine if specific attributes get updated from the MV or if the MV takes the updated values from the connected object.

  5. ktackett says:

    @Nosh Mernacaj

    Let me clarify as I don't believe you understand the purpose of this post of what is actually going on. First, there is no confusion between an anchor attribute and join logic. On applicable management agents (typically databases and text files) it is standard to have both an anchor attribute and join logic. In the context of AD, we join. While I did use AD as an example, the purpose of this post is not to illustrate join logic, but rather, what is occurring on the back end. Because a relationship is made in the dbo.mms_cs_mvlinks table in SQL (csObjectID=mvObjectID=csObjectID), the value of the attribute used to join can change.

    Also, as to my misconception on this, you're comment is basically just restating the last paragraph from my original post:

    "FIM no longer associates that object using the anchor attributes. Rather (and here comes the complexity), relationships between the connector space and metaverse are actually maintained in link tables within the SQL database. I don’t want to get too specific on this piece, but the main thing is that objectID is the value in use (which equates to csObjectID in the connector space and mvObjectID in the metaverse). It is also worth noting that join and projection logic is skipped once an object reaches the state of “connector”."

  6. Nosh Mernacaj says:

    I am sorry, but I have to respectfully disagree with this.

    1. You are using AD MA example to generalize on a broader topic. Wrong! Each MA type behaves differently.

    2. You are confusing anchor object with Join Rules.  If you did this in any other MA, but AD MA

    3. Let me explain how this works.

    -AD uses GUID as Anchor Object not sAMAccountName or emplouyeeNumber.  AD MA is a special MA.  

    – Once the object is joined, the join rules are not relevant anymore.  So it is OK to change the attributes used in join rules

    – Unless you change the anchor object, the join will not break

    – In a nutshell – Your misconception is with the fact that you are thinking sAMAccountName is anchor and that is the part that is not true

  7. itch says:


    Hi Anthony, thank you for fast reply

    Here's more details:

    My user can be created both by an ADMA and a SQLMA in the metaverse. There is only one join rule on the two agents (the same join rule on each MA). It is based on a field called "employeeID" (it's just a string, like "AA123123").

    My joins rules works well, objects are join with no problem, as long as AD admins fill the good employeeID in their AD. And that is where my problem happend:

    Sometimes, they make some typing errors on the employeeID in AD end-user profiles (for example they enter AA123122 instead of AA123123), and so the resulting join (or projection) is wrong (because of data quality, which is normal).

    What I have been asked is to automatically correct the join when they correct the employeeID in their AD.

    Hope my problem is better explained now.

  8. @itch

    First lets understand your particular issue you are having,

    Do you have incorrectly joined objects?

    Are your Objects just not joining?

    are you trying to join different resource / object types to one another?

    Do you have multiple potential joins for connector space? ie do you have 2 objects in a single connector space that meet the join logic?

    could you provide more detail?

  9. itch says:


    This is a very interresting article.

    You describe well the problem, but do you have any idea on how to solve this?

    For example :

    – detect that the value used by join logic has been update (i.e. mventry[attr].value != csentry[attr].value)

    – remove all joins on the object

    – re-evalute join with the new udpate value

    from a theoretical point of view, this seems very to simple to achieve, but in fact, I do no succeed at doing this. Any idea?

    Thx in advance 🙂

    Sorry for my english, i'm sadly french 🙂

Comments are closed.

Skip to main content