none
MIM 2016 - AD user replication from one domain to another RRS feed

  • Question

  • I am trying to setup MIM to replicate users (Inc Passwords) from one domain to another with no success. 

    I basically want to spin up another forest/domain and replicate users from one OU in the source domain to an OU in the destination domain. 

    I have followed every article I can find but can't seem to find one that covers this end to end, so was wondering if someone could point me in the right direction for this. 

    So far I have my two AD management agents & my FIM service management agent configured following this article: 

    https://docs.microsoft.com/en-us/microsoft-identity-manager/install-mim-sync-ad-service 

    but no user objects appear in my destination domain. They look to be getting picked up by the source and added to the FIM  management agent database but not in the destination domain. 

    Can someone help me out here please? As I'm about to start pulling my hair out. 

    Thanks, 

    Rob

    Tuesday, June 27, 2017 1:42 PM

All replies

  • Hi Rob,

    This is the most basic MIM Task which has been around ever since the Days of MIIS 2003 (Great-Grandfather of MIM).

    For this all you need is the Sync Engine.

    1- Replicating users, simply create 2 AD MAs for each Forest.  One will be Project, and the other Provision.

    Provisioning should be done in MVExtension Code, here is an example. https://technet.microsoft.com/en-us/library/hh859471(v=ws.10).aspx.

    You will have to provide the AD Required attributes, so you will need to change the UPN to match the target Domain, so if source was CN=ROB, DC=Source, DC=COM now you have CN=ROB,DC=Target, DC=COM.

    You will create the run profiles, which will have one step for each domain within the forest. 

    2- Password Synchronization is done as a separate task. Initially when you provision the users, you simply set any password.  Password Changes will be picked by PCNS and synched across.  Need to follow this. https://technet.microsoft.com/en-us/library/cc720589(v=ws.10).aspx

    I hope this helps you get a head start.


    Nosh Mernacaj, Identity Management Specialist

    Tuesday, June 27, 2017 2:34 PM
  • Well this is confusing! 

    So it looks like all I'm missing is the MVExtension Code bit & that link isn't working. Is there a standard bit of code to use or do you have to write your own? 

    Can you also just confirm that: 

    source Domain attribute flow is Import & destination Domain is Export? (All the tutorials say this but it reads like it should be the other way around?)

    The Join and Projection rules:

    I currently have one Join: SamAccount.. To AccountName & Projection to Person. 

    If its been around since the start I can't believe its not better documented.. 

    Thanks, 

    Rob

    Tuesday, June 27, 2017 3:09 PM
  • Rob,

    It is simple when you have dealt with, but it is not a plug and play, unfortunately.

    Yes, you need to create your own code, but there are tons of samples out there and it is well documented.

    Trouble is that you need to understand the dynamics of this product.

    Also, since FIM 2010, MS has tried to move away from the code and you can very well do this in FIM Portal, Codeless Provisioning, but again some expertise is required.

    1. Create the MVExtenxion

    https://technet.microsoft.com/en-us/library/hh859471(v=ws.10).aspx 

    2. Coding the provisioning. Complements of http://www.wapshere.com/missmiis/code-snippets 

    Imports Microsoft.MetadirectoryServices

    Public Class MVExtensionObject
    Implements IMVSynchronization

    Const ADS_UF_NORMAL_ACCOUNT As Integer = &H200
    Const ADS_UF_DISABLED_ACCOUNT As Integer = &H202
    Const OU_NAME_AD As String = "OU=Staff,DC=frogsinc,DC=ch"
    Const OU_NAME_OPENLDAP As String = "ou=People,dc=my-domain,dc=com"
    Const MA_NAME_AD As String = "AD"
    Const MA_NAME_OPENLDAP As String = "openLDAP"
    Const MA_NAME_STAFFWEBSITES As String = "StaffWebsites"
    Const INITIAL_PASSWORD As String = "Passw0rd"

    Public Sub Initialize() Implements IMVSynchronization.Initialize
      ' TODO: Add initialization code here
    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
      Dim rdn As String
      Dim ADMA As ConnectedMA
      Dim StaffWebsitesMA As ConnectedMA
      Dim openLDAPMA As ConnectedMA
      Dim numConnectors As Integer
      Dim myConnector As CSEntry
      Dim csentry As CSEntry
      Dim dn As ReferenceValue

      ' Ensure that the cn attribute is present.
      If Not mventry("cn").IsPresent Then
        Throw New UnexpectedDataException("cn attribute is not present.")
        Exit Sub
      End If

      ' ** AD **
      ' Determine the container and relative distinguished name
      ' of the new connector space entry.
      rdn = "CN=" & mventry("cn").Value
      ADMA = mventry.ConnectedMAs(MA_NAME_AD)
      dn = ADMA.EscapeDNComponent(rdn).Concat(OU_NAME_AD)

      numConnectors = ADMA.Connectors.Count

      ' If there is no connector present, create a new connector.
      If 0 = numConnectors Then
        csentry = ADMA.Connectors.StartNewConnector("user")
        csentry.DN = dn
        csentry("UnicodePwd").Values.Add(INITIAL_PASSWORD)
        csentry("userAccountControl").IntegerValue = ADS_UF_NORMAL_ACCOUNT
        csentry.CommitNewConnector()

      ElseIf 1 = numConnectors Then
        ' Check if the connector has a different DN and rename if necessary.
        ' Get the connector.
        myConnector = ADMA.Connectors.ByIndex(0)
        If myConnector.DN.ToString.ToLower <> dn.ToString.ToLower Then
          myConnector.DN = dn
        End If

      Else
        Throw New UnexpectedDataException("multiple connectors:" + numConnectors.ToString)
      End If

      ' ** openLDAP **
      ' Determine the container and relative distinguished name
      ' of the new connector space entry.
      rdn = "CN=" & mventry("uid").Value
      openLDAPMA = mventry.ConnectedMAs(MA_NAME_OPENLDAP)
      dn = openLDAPMA.EscapeDNComponent(rdn).Concat(OU_NAME_OPENLDAP)

      numConnectors = openLDAPMA.Connectors.Count

      ' If there is no connector present, create a new connector.
      If 0 = numConnectors Then
        csentry = openLDAPMA.Connectors.StartNewConnector("inetOrgPerson")
        csentry.DN = dn
        csentry("cn").Value = mventry("uid").Value
        csentry("userPassword").Values.Add(INITIAL_PASSWORD)
        csentry.CommitNewConnector()

      ElseIf 1 = numConnectors Then
        ' Check if the connector has a different DN and rename if necessary.
        ' Get the connector.
        myConnector = openLDAPMA.Connectors.ByIndex(0)
        If myConnector.DN.ToString.ToLower <> dn.ToString.ToLower Then
          myConnector.DN = dn
        End If

      Else
        Throw New UnexpectedDataException("multiple connectors:" + numConnectors.ToString)
      End If

      ' ** StaffWebsites **
      StaffWebsitesMA = mventry.ConnectedMAs(MA_NAME_STAFFWEBSITES)
      Dim csWebsite As CSEntry
      numConnectors = StaffWebsitesMA.Connectors.Count
      If mventry("website").Value.ToLower = "yes" AndAlso numConnectors = 0 Then
        csWebsite = StaffWebsitesMA.Connectors.StartNewConnector("website")
        csWebsite("alias").Value = mventry("uid").Value
        csWebsite.CommitNewConnector()
      ElseIf mventry("website").Value.ToLower = "no" AndAlso numConnectors = 1 Then
        StaffWebsitesMA.Connectors.ByIndex(0).Deprovision()
      ElseIf mventry("website").Value.ToLower = "yes" AndAlso numConnectors = 1 Then
        csWebsite = StaffWebsitesMA.Connectors.ByIndex(0)
        If csWebsite("alias").Value.ToLower <> mventry("uid").Value.ToLower Then
          csWebsite("alias").Value = mventry("uid").Value
        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

    End Class

    3. Codeless provisioning

    https://technet.microsoft.com/en-us/library/ff608273(WS.10).aspx 


    Nosh Mernacaj, Identity Management Specialist

    • Proposed as answer by Nosh Mernacaj Wednesday, June 28, 2017 5:23 PM
    Tuesday, June 27, 2017 3:30 PM
  • Thanks for the info but after another day I'm still no further to this. 

    I'm just getting errors like: 

    The management agent "ForestB" failed on run profile "Full" because the extension "MVExtensionRC.dll" does not contain a class implementing the required (IMVSynchronization or IMASynchronization) interface in the assembly.

    Am I missing a trick here? Is there a simpler way to achieve what I want? 

    I've looked at installing the portal on Sharepoint to do the code less replication buts another can of worms as well with me having not used SP before and the lack of tutorials around this product for what I'm trying to do is horrendous.

    Rob 

    Wednesday, June 28, 2017 5:04 PM
  • I am not aware of any other way.

    You may try to debug in Visual Studio. Do that adding "miisserver.exe" server to Debugger.


    Nosh Mernacaj, Identity Management Specialist

    Wednesday, June 28, 2017 5:23 PM
  • P.S: Rob, I hear your frustration, but it is not the lack of documentation the issue. The issue is that the product is a complex product and a mere document will not suffice.  This is a niche product where people that know it, have spent many years working with it.  Any identity product, will be the same because it touches almost everything in your environment.

    Replicating Forests, can also be done in powershell.


    Nosh Mernacaj, Identity Management Specialist

    Wednesday, June 28, 2017 6:06 PM