locked
Exclude connector space from provisioning

    Question

  • I want to export Metaverse objects to a SQL database. I have created a metaverse rules extension to provision objects to a new MA. When I Sync the other MAs I can see Outbound Synchronization results to the new MA. How do I control the source MAs in the provisioning code?

     

    Friday, July 28, 2006 10:51 PM

Answers

  • Because the objects in the telephone management connectorspace are disconnectors.....Provisioning code will never run on them...

    Provisioning code will only run if the object  was joined to a metaverse object and  made a change to that metaverse object...

    There has to be a metaverse object in the metaverse to run provisioning code...

    Since the telephone management is set to join, it does not create (project) a metaverse object,

     leaving your object as a disconnector if the join criteria is not made.

    If these accounts don't join up to the HR system, then they would not join to the metaverse object and would be marked as disconnectors..

    Since you are making the objects explicit disconnectors, then the objects will never be evaluated, so they will never have the opportunity to join to the metaverse...

     

    HTH,

     

    Joe

    Tuesday, August 01, 2006 5:23 PM

All replies

  • What exactly would you like to do?

    We need some more information..

    Do you use a specific attribue?

    Would you like to only create an account if another account exists in only one ma?



    Joe
    Saturday, July 29, 2006 12:20 AM
  • I had 5 Management Agents, three project to the Metaverse and two join. When I run Full Synchronizations, all 5 MAs provide provisioning adds to my new MA. I would like to know the VB code to exclude specific MAs from the provisioning code.
    Monday, July 31, 2006 3:31 PM
  • Provisioning is a metaverse centric trigger. This method is by design independent from a change originator.

     

    If provisioning is triggered, it translates to “a change has been applied to a metaverse object that was not its deletion – now what?”

     

    You can’t prevent a specific MA from causing a provisioning trigger.

     

    Cheers,

    Markus

     

    ///////////////////////////////////////////////////////////////////////
    Markus Vilcinskas

    Technical Writer
    Microsoft Identity Integration Server
    mailto:markvi@microsoft.com.NO_SPAM

    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at
    http://www.microsoft.com/info/copyright.htm
    ///////////////////////////////////////////////////////////////////////

     

    Monday, July 31, 2006 4:01 PM
  • By the way – I have a little “dirty trick” ;o) for.

    The synchronization cycle is implemented as one transaction on a per object basis...

    What you can do, is to set a transaction property (Utils.TransactionProperties) in an advanced disconnector filter (FilterForDisconnection).

     

    The disconnector filter is the only synchronization rule that is definitely triggered during a synchronization run.

     

    The idea of the transaction property is to have a little stack between inbound and outbound synchronization. So, if the property is set, only your specific MA could have set it.

     

    While this is from the technical perspective an answer to what you are looking for, I would like to know why it is necessary to isolate provisioning triggers from a specific MA.

    I’m calling this a “dirty trick” because the provisioning function should by default – as mentioned before – be independent from trigger causing source MA.

      

    Cheers,

    Markus

     

    ///////////////////////////////////////////////////////////////////////
    Markus Vilcinskas

    Technical Writer
    Microsoft Identity Integration Server
    mailto:markvi@microsoft.com.NO_SPAM

    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at
    http://www.microsoft.com/info/copyright.htm
    ///////////////////////////////////////////////////////////////////////

    Monday, July 31, 2006 4:14 PM
  • As Markus says, this is by design...

    Are you talking about when you fun the first MA, it provisions to your MA.......(It shows a provisioning ADD)

    When you run your second MA, if also provisions to your MA.......(This is how it is supposed to work)

    You would also see a provisioning disconnect.....Which is deleting the  connector that you created through the first MA...

    To stop this from happening you could just do an export on the new MA which each one is provisioning too......

    Example.....

    Change your run profiles to something like this....

    MA1    Full Import Full Sync

    NewMA Export (You should always run a confirming import, Delta would be the best, if possible)

    MA2 Full Import Full Sync

    NewMA Export (You should always run a confirming import, Delta would be the best, if possible)

    MA3 Full Import Full Sync

    NewMA Export (You should always run a confirming import, Delta would be the best, if possible)

    MA4 Full Import Full Sync

    NewMA Export (You should always run a confirming import, Delta would be the best, if possible)

    MA5 Full Import Full Sync

    NewMA Export (You should always run a confirming import, Delta would be the best, if possible)

     

    Now what you should see when you run the full synchs are just the export flows from the other connectors...

    I'm not totally sure if this is what your talking about.....But I hope it help anyway...

     

    Joe

    Monday, July 31, 2006 4:54 PM
  • Sorry, this is probably just my misunderstanding of provisioning. I was concerned that when the provisioning code runs (through the metaverse rules extension) that new objects would be created in my new MA (by the provisioning code) from ALL other management agents. I have two MAs that only provide supporting data to metaverse objects they are joined to. I was concerned that I would provision objects that I did not want from those two supporting MAs. But if I understand you both correctly, the provisioning code will only create objects in the new MA from MAs that project to the metaverse. MAs that join to metaverse objects will not be provisioned to the new MA. Is that correct?

    Tuesday, August 01, 2006 3:19 AM
  • The best way of thinking about synchronization rules is that they are an indicator for a trigger. The provisioning method is triggered by a change to a metaverse object that was not the deletion of it. The creation of a MV object is an example for such a trigger as well as an applied attribute update to a metaverse object or an established link between a CS and MV object.

     

    If you have only a join rule (and no projection rule) configured on MA X and an object from CS X was joined to a metaverse object, the provisioning method is triggered. “Someone has applied a change to a metaverse object – what am I supposed to do with that?” – this is what your provisioning code needs to answer.

     

    Keep in mind, the provisioning method is called any time an attribute value of a metaverse object has been changed by a connector space object…

     

    Whether or not your provisioning code needs to create a new connector be answered on the basis of the current state of your metaverse object – not on the basis of where the last change came from.

     

    This is the 80% rule. You should start your synchronization rules design from the perspective of “it shouldn’t matter where the change to a metaverse object comes from”.

     

    Now, it is possible that you have a scenario in which a change that comes from a specific connector space will never require any action of your provisioning code. In this case, you can use the transaction property technique. It can simplify your provisioning code significantly.

     

    I’m just calling this method “a dirty trick” because I want to indicate that this method does not fall under the 80% case. When you are using this technique, you should be 100% certain that there is under no circumstances a need to do anything in your provisioning code in case of a change applied by a CS object from a specific connector space.

     

    The need to isolate changes applied by the CS objects from a specific is is a rare (20%) case – but it is possible.

     

    To prevent yourself from implementing a solution that doesn’t work, you should think very hard about whether it is really necessary to isolate changes originated in a specific connector space. If the answer is yes, then you know now what you can do ;o)

     

    I hope this helps.

    Please let me know if you have questions.

     

    Cheers,

    Markus

     

    ///////////////////////////////////////////////////////////////////////
    Markus Vilcinskas

    Technical Writer
    Microsoft Identity Integration Server
    mailto:markvi@microsoft.com.NO_SPAM

    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at
    http://www.microsoft.com/info/copyright.htm
    ///////////////////////////////////////////////////////////////////////

     

    Tuesday, August 01, 2006 9:15 AM
  •  

    As markus says, anytime you have an import flow that changes a value in the metaverse, provisioning code will be called....

    It doesn't matter whether it is a project or join.... Usually if you have provisioning code setup.... You will see the project cause the

    provisioning code to run.....That's because there was no object in the metaverse yet...you need an object to run the code on.....

    And when you have a join that flows an attribute to that metaverse object....It will try to "re-provision the account" but only if the account has not been exported yet....

    From reading your post I am a little confused......

    (Here's part of the post)

     "I was concerned that when the provisioning code runs (through the metaverse rules extension) that new objects would be created in my new MA (by the provisioning code) from ALL other management agents."

    What exactly do you mean??

    Are you worried that the provisioning code will create mutliple objects of the same person??

    Unless you have some provisioning code that will create multiple connectors per metaverse object...It should only create one connector...

    So if you already provisioned the account, when you join on it...the provisioning code will run....but it already sees the account so....it doesn't "re-provision" it.....

     

    HTH,

     

    Joe

     

     

    Tuesday, August 01, 2006 12:57 PM
  • Thanks again Markus and Joe for your responses. I will try to answer your question Joe by providing more detail. We have the simple scenario of an HR database that is projected to the metaverse, a telephone database and an Active Directory OU are joined to objects in the metaverse based on a first name, last name match. There are many disconnects (hundreds) that I have made explicit because they will never match to the HR system or the Active Directory (they represent a different group in our organization that are not part of our payroll (HR system) or computer landscape, but are provided with telephones). We are now implementing a new database application that needs a list of active employees. I want to use MIIS to provide the user data from the HR system that is already in the metaverse to the new system. So my plan it to use provisioning code to create accounts in the new system automatically. What I do not want is for the many hundred explicitly disconnected objects from the telephone database to also be provisioned to the new database.

    So my concern is that objects that are meaningless to me, but exist in the telephone database, will be projected to the new database. My plan was to eliminate the telephone database from provisioning all together. I thought the response from this forum would suggest code like:

    If Not ManagementAgentName = "Telephone Database" Then...

    If I understand you correctly Markus, this is not a concern because the explicitly disconnected objects are not projected to the metaverse and therefore will not be a trigger for provisioning. Am I on the right track now?

    Tuesday, August 01, 2006 3:46 PM
  • Yes, this is correct. Explicit disconnectors are blocked in the CS.

    They are not automatically processed towards the metaverse and will not trigger provisioning.

     

    Just to be complete in conjunction with your scenario…

    Even if the disconnectors weren’t explicit and even if you would project / join them into the metaverse, they wouldn’t be a concern.

     

    Typically, you have at least one CDS – in most cases the HR system – that is authoritative for object distribution.

     

    In case of a provisioning trigger, the question would not be “If Not ManagementAgentName = "Telephone Database" Then...” it would be (in pseudo code) “if mventry.ConnectedMAs("HR").Connectors.Count = 1 and mventry.ConnectedMAs("someTargetMA").Connectors.Count < 1 then”

     

    Do you see the difference? The primary question is not where the change came from, the question is whether the mv object has a connector in the HR system and no connectors in your provisioning target. This is an indicator “to do something” otherwise “exit sub” ;o)

     

    I hope this makes sense.

     

    Cheers,

    Markus

     

    ///////////////////////////////////////////////////////////////////////
    Markus Vilcinskas

    Technical Writer
    Microsoft Identity Integration Server
    mailto:markvi@microsoft.com.NO_SPAM

    This posting is provided "AS IS" with no warranties, and confers no rights.
    Use of included script samples are subject to the terms specified at
    http://www.microsoft.com/info/copyright.htm
    ///////////////////////////////////////////////////////////////////////

    Tuesday, August 01, 2006 5:08 PM
  • Because the objects in the telephone management connectorspace are disconnectors.....Provisioning code will never run on them...

    Provisioning code will only run if the object  was joined to a metaverse object and  made a change to that metaverse object...

    There has to be a metaverse object in the metaverse to run provisioning code...

    Since the telephone management is set to join, it does not create (project) a metaverse object,

     leaving your object as a disconnector if the join criteria is not made.

    If these accounts don't join up to the HR system, then they would not join to the metaverse object and would be marked as disconnectors..

    Since you are making the objects explicit disconnectors, then the objects will never be evaluated, so they will never have the opportunity to join to the metaverse...

     

    HTH,

     

    Joe

    Tuesday, August 01, 2006 5:23 PM
  • You are correct - any type of Disconnector is by definition not connected to an MVEntry. Whether or not this entry would have Projected a new MVEntry or joined to an existing one is moot at this point. And as you pointed out, without any logic surrounding the Provisioning process every MVEntry that is not connected to an object in your "new" MA will cause a Provision action to generate a new connector to the new MA.

    So far I have always found it necessary to encapsulate my Provisioning logic with a series of logic checks to verify that I am getting the correct data types into the proper MAs. I use a combination of methods including Markus' "dirty trick". I do so by first setting a variable in each MA Extension project to "name" the MA and then add that to a TransactionProperty whenever a sync occurs. I then do the following within the Provision sub:

    '\\\ Establish our object type now
    strObjectType = mventry.ObjectType.ToString

    '\\\ Check our global flag
    '\\\ [miis-config.xml] <Provisioning>TRUE</Provisioning>
    If (strProvisioning = "TRUE") Then...

    This allows me to add an additional switch to enable or disable provisioning outside of the Tools/Options/"Enable Provisioning Rules Extension". I then very typically control the provisioning based on object type like so (the Identity and Access Management Series has more examples of this):

    If strObjectType = "person" Then
    ProvisionToAD(mventry, mvPosition, strObjectType, boolEmail)

    I've also had reason to use a "collection" of object types in the configuration file to trigger using a RegEx like so:

    '\\\ [miis-config.xml] <ProvisionObjectTypes>person,group,contact</ProvisionObjectTypes>
    If Regex.IsMatch(strProvisionObjectTypes, strObjectType, RegexOptions.IgnoreCase) Then...


    You can use Utils.FindMVEntries to perform a metaverse search for specific items or object types (I do so to control enabling Entitlements based on job position for one client) or switch provisioning on based on an existing MV attribute:

    If (strProvisionVer3SSO = "TRUE") And boolSSOEnabled = True Then
    ProvisionToSSOUser(mventry)

    But as you can see, I always move all of the actual code to create the new connector into its own sub in order to keep the main Provision sub streamlined. It certainly makes the flow easier to follow, IMHO (and lots of inline documentation helps here as well!).

    The OCG MIIS Advanced Class details another more advanced solution called "MVRouter" where you can split this further into their own classes (DLL) if you have the need to maintain change control and ownership across multiple teams (each owning their own MAs provisioning code).

    Once you get into the coding you'll always want to create a logic structure where you can query how many connectors currently exist (always start by selecting the MA you're dealing with - this is now part of the MA specific provisioning sub):

    '\\\ Setup the MA object we will be provisioning to
    '\\\ [miis-config.xml] <ProvisionToMA>ADMA</ProvisionToMA>
    Dim ProvisionToMA As ConnectedMA = mventry.ConnectedMAs(strProvisionToMA)

    Dim intADConnectors As Integer ' Used to determine how many connectors we have in the target CS already

    '\\\ Verify all required attributes are present before proceeding...
    If mventry("displayName").IsPresent Then...

    '\\\ Read the number of connectors to the object currently
    intADConnectors = ProvisionToMA.Connectors.Count

    '\\\
    '\\\ C h e c k C o n n e c t o r s
    '\\\
    '\\\ If we have more than 0 connectors then we don't need to provision any additional
    '\\\ If we have 0 connectors, then we need to create one
    '\\\
    If intADConnectors = 0 Then...

    You can then alter the Provisioning behavior based on the status of an MV attribute, most commonly used in HR Provisioning scenarios where you need to take different actions based on the status of an identity:

    Select Case mventry("employeeStatus").Value.ToUpper
    '\\\
    '\\\ A C T I V E E m p l o y e e - N 0 C o n n e c t o r
    '\\\
    '\\\
    Case "A"


    Once you've exhausted the new connector permutations, you can deal with an existing connector:

    ElseIf intADConnectors = 1 Then

    Or multiple connectors:

    ElseIf intADConnectors > 1 Then

    The key here is that you can create logic in the Provisioning sub to not only control which MA gets provisioned to, but filter by applicable object types, objects of a certain status, etc...



    Tuesday, August 01, 2006 5:36 PM
  • Thank you all for responding. I think I have the basics now for provisioning to my MA, and you have all given me new areas to consider in my design.

    Evan

    Wednesday, August 02, 2006 8:00 PM
  • Hi Brad,
    I have configured 2 MAs to provision objects from Prod to Dev --- while running full sync from source MA, I am getting "stopped-extension-dll-exception" error. Please help to resolve the issue.
    Here is the event log 
    The management agent "SyncProdAD" failed on run profile "Full Sync" because of a problem with the initialize method on the extension object. The extension dll is "ProdSync_MVExtension.dll" 
    here is the XML file 
    ====================================================
    <?xml version="1.0" encoding="utf-8" ?>
    <config>
      <strProdDomainDN>DC=user,DC=ForA,DC=local</strProdDomainDN>
      <strDevDomainDN>OU=Corporate,DC=user,DC=ForB,DC=local</strDevDomainDN>
      <strSyncToMA>SyncDevAD</strSyncToMA>
      <strSyncFromMA>SyncProdAD</strSyncFromMA>
      <strProvisioning>true</strProvisioning>
      <strProvisionToMA>SyncDevAD</strProvisionToMA>
    </config>
    ==============================================================
    Here is the Rule Extension 
    ==============================================================
    Imports Microsoft.MetadirectoryServices
    Imports System.Xml
    Imports System.Text.RegularExpressions
    Public Class MVExtensionObject
        Implements IMVSynchronization
        Public Shared strProvisioning, strProvisionToMA As String
        Public Shared strSyncToMA, strSyncFromMA, strProdConfigDN, strDevConfigDN, strProdDomainDN, strDevDomainDN As String
        Public Shared boolSyncProdToDev As Boolean
        Public Sub Initialize() Implements IMvSynchronization.Initialize
            
            Const XML_CONFIG_FILE As String = "\\miis-config.xml"
            Dim xmlConfig As XmlDocument = New XmlDocument
            Dim extDir As String = Utils.ExtensionsDirectory
            Try
                xmlConfig.Load(extDir + XML_CONFIG_FILE)
                Dim xmlGeneralConfigurationRootNode As XmlNode = xmlConfig.SelectSingleNode("config")
                'strProdConfigDN = xmlGeneralConfigurationRootNode.SelectSingleNode("ProdConfigDN").InnerText
                strProdDomainDN = xmlGeneralConfigurationRootNode.SelectSingleNode("ProdDomainDN").InnerText
                'strDevConfigDN = xmlGeneralConfigurationRootNode.SelectSingleNode("DevConfigDN").InnerText
                strDevDomainDN = xmlGeneralConfigurationRootNode.SelectSingleNode("DevDomainDN").InnerText
                If xmlGeneralConfigurationRootNode.SelectSingleNode("SyncProdToDev").InnerText.ToUpper = "TRUE" Then boolSyncProdToDev = True
                strSyncToMA = xmlGeneralConfigurationRootNode.SelectSingleNode("SyncProdToMA").InnerText.ToUpper
                strSyncFromMA = xmlGeneralConfigurationRootNode.SelectSingleNode("SyncProdFromMA").InnerText.ToUpper
                strProvisioning = xmlGeneralConfigurationRootNode.SelectSingleNode("Provisioning").InnerText.ToUpper
                strProvisionToMA = xmlGeneralConfigurationRootNode.SelectSingleNode("ProvisionToMA").InnerText
            Catch nre As NullReferenceException
                '\\\ We have an XML tag that is not in the XML configuration file
                Throw nre
            Catch ex As Exception
                Throw ex
            End Try
        End Sub
        Public Sub Terminate() Implements IMVSynchronization.Terminate
            ' TODO: Add termination code here
        End Sub
        Public Sub Provision(ByVal mventry As MVEntry) Implements IMVSynchronization.Provision
            If strProvisioning = True Then
                '\\\ The provisioning flag is true so attempt to provision
                Dim strObjectType As String = mventry.ObjectType.ToString
                If boolSyncProdToDev = True Then
                    '\\\ We should start syncing objects that are in the production AD into the Test AD
                    SyncProdToDEV(mventry, strObjectType)
                End If
            End If
        End Sub
        Public Function ShouldDeleteFromMV(ByVal csentry As CSEntry, ByVal mventry As MVEntry) As Boolean Implements IMVSynchronization.ShouldDeleteFromMV
            ' TODO: Add MV deletion code here
            Throw New EntryPointNotImplementedException()
        End Function
        Public Function SyncProdToDEV(ByVal mventry As MVEntry, ByVal strObjectType As String) As Boolean
            '\\\ 10/21/05 bturner
            '\\\
            '\\\ S Y N C  P R O D  T O  D E V
            '\\\
            '\\\ Provision a new object into the Test Active Directory
            '\\\ Code should synch Users, Groups, OU's, and the gamut of Site and Subnet objects between Prod and Test
            '\\\
            '\\\ NOTE: You must import the DN of every object type into the MV in order for the sync to work
            '\\\        - For OU's, the OU attribute must be imported
            '\\\        - For all other objects, import the samAccountName to UID
            '\\\
            '\\\ Establish the required attributes to be present before continuing
            If mventry("dn").IsPresent = False Then
                '\\\ If we never picked up a DN to sync against
                Exit Function
            End If
            If strObjectType = "syncOrganizationalUnit" AndAlso mventry("ou").IsPresent = False Then
                '\\\ If we never picked up the OU name
                Exit Function
            End If
            '\\\ Setup the MA object we will be provisioning to
            '\\\ [miis-config.xml] <SyncProdToMA>SyncDevAD</SyncProdToMA>
            Dim ProvisionToMA As ConnectedMA = mventry.ConnectedMAs(strSyncToMA)
            Dim successful As Boolean = False                   ' Used to control our loop
            Dim intADConnectors As Integer                      ' Used to determine how many connectors we have in the target CS already
            '\\\ Loop until we either exit, throw an exception or (preferrably) we set successful = True
            Do
                Dim strPwd As String
                Dim objDN As ReferenceValue                         ' Used to hold the reference DN of our new object
                Try
                    '\\\ Read the number of connectors to the object currently
                    intADConnectors = ProvisionToMA.Connectors.Count
                    '\\\ Check the number of connectors to the object currently
                    If intADConnectors = 0 Then
                        '\\\ There are no connected objects in this CS to the current MV object
                        '\\\ In order to build a new ver3SSOSettings object we need to do the following tasks:
                        '\\\ 1) Modify the synch DN
                        '\\\ 2) Create a new connector object
                        '\\\ 3) Assign the configuration values to the connector
                        '\\\ 4) Commit the connector
                        '\\\ 5) Audit the event
                        '\\\
                        Dim csentry As CSEntry                              ' Create a csentry object to hold our new employee data
                        '\\\
                        '\\\ B U I L D  D N
                        '\\\
                        '\\\ Build a new DN relative to the destination CD
                        objDN = ReplaceProdDN(mventry("dn").StringValue, ProvisionToMA)
                        '\\\
                        '\\\ C R E A T E  C O N N E C T O R
                        '\\\
                        Select Case strObjectType
                            Case "syncOrganizationalUnit"
                                csentry = ProvisionToMA.Connectors.StartNewConnector("organizationalUnit")
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry("ou").Value = mventry("ou").Value
                            Case "syncPerson"
                                csentry = ProvisionToMA.Connectors.StartNewConnector("user")
                                '\\\
                                '\\\ S E T  P A S S W O R D
                                '\\\
                                strPwd = "!Passw0rd"
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry("unicodePwd").Value = strPwd
                                csentry("sAMAccountName").Value = mventry("sAMAccountName").Value
                                '\\\
                                '\\\ S E T  U S E R A C C O U N T C O N T R O L
                                '\\\
                                csentry("userAccountControl").IntegerValue = mventry("userAccountControl").IntegerValue
                                '\\\
                                '\\\ S E T  P W D L A S T S E T
                                '\\\
                                csentry("pwdLastSet").Value = 0
                            Case "syncContact"
                                csentry = ProvisionToMA.Connectors.StartNewConnector("contact")
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry("sAMAccountName").Value = mventry("sAMAccountName").Value
                                csentry("targetAddress").Value = mventry("targetAddress").Value
                            Case "syncGroup"
                                csentry = ProvisionToMA.Connectors.StartNewConnector("group")
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry("sAMAccountName").Value = mventry("sAMAccountName").Value
                                csentry("groupType").IntegerValue = mventry("groupType").IntegerValue
                            Case Else
                                '\\\ This is an object type we don't care about
                                Exit Function
                        End Select
                        '\\\
                        '\\\ A S S I G N  V A L U E S
                        '\\\
                        csentry.DN = objDN
                        '\\\
                        '\\\ C O M M I T  C O N N E C T O R
                        '\\\
                        csentry.CommitNewConnector()
                        successful = True
                    ElseIf intADConnectors = 1 Then
                        '\\\ There is already an object in the CS that is connected to this MV object
                        '\\\ If we want, we can "move" the object here by changing its DN
                        Dim csentry As CSEntry
                        '\\\ Grab the first connector by index (we should not have multiple connectors in a sync)
                        csentry = ProvisionToMA.Connectors.ByIndex(0)
                        '\\\ Build a new DN relative to the destination CD
                        objDN = ReplaceProdDN(mventry("dn").StringValue, ProvisionToMA)
                        '\\\ Filter by Metaverse object type
                        Select Case strObjectType
                            Case "syncOrganizationalUnit"
                                '\\\ We can't rename OU objects this way so ignore the rename
                                '\\\ NOTE: displayName and ou must be renamed via EAF
                            Case "syncGroup"
                                '\\\ We're a group object, prepare for a rename
                                '\\\ NOTE: sAMAccountName must be renamed via EAF
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry.RDN = "CN=" & mventry("cn").Value
                                csentry.DN = objDN
                            Case "syncPerson"
                                '\\\ We're a user object, prepare for a rename
                                '\\\ NOTE: sAMAccountName must be renamed via EAF
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry.RDN = "CN=" & mventry("cn").Value
                                csentry.DN = objDN
                            Case "syncContact"
                                '\\\ We're a contact object, prepare for a rename
                                '\\\ NOTE: sAMAccountName must be renamed via EAF
                                '\\\
                                '\\\ A S S I G N  V A L U E S
                                '\\\
                                csentry.RDN = "CN=" & mventry("cn").Value
                                csentry.DN = objDN
                            Case Else
                                '\\\ Can't rename the other objects due to the SystemFlags property
                        End Select
                        successful = True
                    End If
                Catch ex As ObjectAlreadyExistsException
                    '\\\ The object already exists, ignore it since it should be picked up on the next join
                    successful = True
                End Try
            Loop While Not successful
        End Function
        Public Function ReplaceProdDN(ByVal strProdObjDN As String, ByVal ProvisionToMA As ConnectedMA) As ReferenceValue
            '\\\ 4/7/06 bturner
            '\\\
            '\\\ Replace the Production OU DN tokens with ones compatible with the destination CD
            '\\\  Only submit Configuration or Domain partitions - do not pass Schema or App partitions
            '\\\
            '\\\ NOTE: Must be able to translate for:
            '\\\        - AD single domain forest to DEV single domain forest
            '\\\        - AD multi domain forest to DEV single domain forest
            '\\\        - AD multi domain/multi tree forest to DEV single domain forest
            '\\\
            '\\\ NOTE: This *should* work for multi domain to multi domain but it has not been tested
            '\\\    
            '\\\ First check to see what naming context we're dealing with
            Dim ConfigRegexObj As Regex = New Regex(strProdConfigDN, RegexOptions.IgnoreCase)
            If ConfigRegexObj.IsMatch(strProdObjDN) Then
                '\\\ We have the Config NC
                strProdObjDN = ConfigRegexObj.Replace(strProdObjDN, strDevConfigDN, RegexOptions.IgnoreCase)
            Else
                '\\\ Now we need to see if we have the right Domain NC
                Dim DomainRegexObj As Regex = New Regex(strProdDomainDN, RegexOptions.IgnoreCase)
                If DomainRegexObj.IsMatch(strProdObjDN) Then
                    '\\\ We have a Domain NC - since we read this from the config file we don't have to rebuild the string
                    strProdObjDN = DomainRegexObj.Replace(strProdObjDN, strDevDomainDN, RegexOptions.IgnoreCase)
                End If
            End If
            ReplaceProdDN = ProvisionToMA.CreateDN(strProdObjDN)
        End Function
    End Class
    ===============================================================================

    Thanks, Sunil Gupta Sunilgupta@sunilgupta.com
    Monday, November 28, 2011 11:16 AM