Active Directory could not transfer the remaining data in directory partition

Just recently I was asked by a client to migrate their Active Directory 2008 R2 servers to Windows Server 2016. All was going well until I needed to demote the old domain controllers and ran DCPROMO.  I was presented with the error Active Directory could not transfer the remaining data in directory partition.  Then below it stated The directory service is missing mandatory configuration information, and is unable to determine the ownership of floating single-master operation roles.  Before starting with the fix I would just note that every step here is important.  Missing some of the details and skipping over things (you may think you know) will slow you down in the long run.

There seemed to be a lot of information and advice about this online unfortunately a lot of it was not very helpful and we had enough knowledge in the team to filter out what we needed from various sources.  I next took a look in the event log and saw event ID 2091 and event ID 2022 logged.  Event ID 2091 gives you the most information and should tell you the source of your problem.

As you can see in the above event log where it says CN=D this is the name of an old server that incidentally predated anyone in the existing IT team.  Somehow this old server was still hanging on to ownership of the Infrastructure master FSMO role.  The reason that we didn’t think this would be an issue is that all of the FSMO roles had already been transferred to another server and NTDSUTIL had confirmed this.  Therefore to resolve the issue we needed to:

a) Take ownership of the role.
b) Assign the role to the domain controller we wanted it to be on.

The fix in the end was fairly simple and involved a few steps which initially had us concerned but ultimately they were harmless and resolved the issue in a few minutes.

Locating the correct settings

The correct setting for the Infrastructure master FSMO role holder can be found by doing the following from the domain controller that you are trying to demote.

1. The correct setting can be found by going to start>run and typing adsiedit.msc

2. Then right click on ASDI Edit and click Connect to.

3.  Select the radio button to Select a well known Naming Context.  Then select the Default naming context and click OK.

4. Click on DC=YOURDOMAIN,DC=Local.

5. Find CN=Infrastructure which should be separate entry at the bottom, then double click on it.

6. Double click on the fSMORoleOwner attribute and copy the contents.

7. Click Cancel and Cancel again.

Change the incorrect setting

Again the below should be done from the domain controller that you are trying to demote.

1. Go to start>run and type adsiedit.msc

2. Then right click on ASDI Edit and click Connect to.

3. It is important that you perform the next few steps accurately or you will see the wrong setting (there is more than one Infrastructure record!).  Click ‘Select or type a Distinguished Name or Naming Context’.

4. In the box type:

DC=DomainDNSZones,DC=Domain,DC=Local

where DC=Domain,DC=Local is the distinguished name for your domain.  Then click OK.

5. Click on DC=YOURDOMAIN,DC=Local.

6. Find CN=Infrastructure which should be separate entry at the bottom, then double click on it.

7. Then find the attribute fSMORoleOwner and double click on it.  Paste the contents from the correct entry that you just copied above.

8. Then click OK and OK again.

9. Repeat steps 1-8 but instead of connecting to DC=DomainDNSZones,DC=Domain,DC=Local connect to:

DC=ForestDNSZones,DC=Domain,DC=Local

Problems changing the attribute

For some users the above fix works without issue but if like us you may have received the following: Operation failed.  Error code 0x20ae. The role owner attribute could not be read.

Some articles stated that by simply changing the domain controller to the role owner (and running the above)  and not the one being demoted solved this problem.  We still had the same issue though and had to complete a few more steps.

Our problem seemed a bit deeper rooted than most of the articles we had read and we had to run a Microsoft script call fixfsmo.vbs before we could make the changes to adsiedit.  Please note:  We ran the script originally just on the DC=DomainDNSZones,DC=Domain,DC=Local however this also needs to be run on the DC=ForestDNSZones,DC=Domain,DC=Local in order to work.   The script is available from Microsoft here.  It doesn’t require any modifications to run and is run as below.

1. Login to the current FSMO role holder and open an elevated command window.

2. Run the script using the following command:

cscript fixfsmo.vbs DC=DomainDNSZones,DC=Domain,DC=Local

3. Then run the script again using this command:

cscript fixfsmo.vbs DC=ForestDNSZones,DC=Domain,DC=Local

4. Once this is complete you should be able to make the adsiedit changes mentioned earlier without any problems.

The contents of the script are as follows:

'-------fixfsmo.vbs------------------
const ADS_NAME_INITTYPE_GC = 3
const ADS_NAME_TYPE_1779 = 1
const ADS_NAME_TYPE_CANONICAL = 2

set inArgs = WScript.Arguments

if (inArgs.Count = 1) then
    ' Assume the command line argument is the NDNC (in DN form) to use.
    NdncDN = inArgs(0)
Else
    Wscript.StdOut.Write "usage: cscript fixfsmo.vbs NdncDN"
End if

if (NdncDN <> "") then

    ' Convert the DN form of the NDNC into DNS dotted form.
    Set objTranslator = CreateObject("NameTranslate")
    objTranslator.Init ADS_NAME_INITTYPE_GC, ""
    objTranslator.Set ADS_NAME_TYPE_1779, NdncDN
    strDomainDNS = objTranslator.Get(ADS_NAME_TYPE_CANONICAL)
    strDomainDNS = Left(strDomainDNS, len(strDomainDNS)-1)
     
    Wscript.Echo "DNS name: " & strDomainDNS

    ' Find a domain controller that hosts this NDNC and that is online.
    set objRootDSE = GetObject("LDAP://" & strDomainDNS & "/RootDSE")
    strDnsHostName = objRootDSE.Get("dnsHostName")
    strDsServiceName = objRootDSE.Get("dsServiceName")
    Wscript.Echo "Using DC " & strDnsHostName

    ' Get the current infrastructure fsmo.
    strInfraDN = "CN=Infrastructure," & NdncDN
    set objInfra = GetObject("LDAP://" & strInfraDN)
    Wscript.Echo "infra fsmo is " & objInfra.fsmoroleowner

    ' If the current fsmo holder is deleted, set the fsmo holder to this domain controller.

    if (InStr(objInfra.fsmoroleowner, "\0ADEL:") > 0) then

        ' Set the fsmo holder to this domain controller.
        objInfra.Put "fSMORoleOwner",  strDsServiceName
        objInfra.SetInfo

        ' Read the fsmo holder back.
        set objInfra = GetObject("LDAP://" & strInfraDN)
        Wscript.Echo "infra fsmo changed to:" & objInfra.fsmoroleowner

    End if

End if

 

Leave a Reply

Your email address will not be published. Required fields are marked *