This came up recently at a customer site. I was looking for the script that fixes this (remembering that the site the fix belongs to is attached to an article that has nothing to do with the issue, but it still works great).
What I ran into was a TON of really horrible advice out there on the forums. Please please please – if you get this error don’t follow any of the advice you read unless the article mentions running a script that is lovingly called “fixfsmo.vbs”
What you’re probably seeing in LDP or ADSIEdit in the CN=infrastructure,DC=DomainDNSZones,DC=MyDomainName,DC=Whatever (that or ForestDNSZones) is an entry for FSMO that points to a retired or missing DC. Sorta’ like this:
cn=ntds settings\0adel:f655f307-02gb-4923-b7be-fc5e2042b4c8,cn={MyOldDCName}\0adel:88c9073f-6964-4ab3-98f0-d30dcd12a908,cn=servers,cn={SiteName},cn=sites,cn=configuration,dc={MyDomainName},dc={Whatever}
What has happened is the DC who held the FSMO Role Holder for your DomainDNSZones or your ForestDNSZones (or both) application partition isn’t there anymore. Someone deleted it, decommissioned it, basically it failed somewhere along the line but the DC owned one or more of your AD Integrated DNS Zones. The deleted DC can be seen in the mess above after cn=___ and in most cases this means someone had to do metadata cleanup and forcibly removed the server from AD.
So you might be asking, “uh, Chris? Aren’t there just 5 FSMO role holders?” Well, see for yourself:
Without getting into a huge discussion about naming contexts or application partitions – just know that if your domain uses application partitions (likely) each of these will have a FSMO. Like your other FSMO role holders you may need to seize the role. Sadly, you can’t do this with NTDSUTIL. You can SEE them (see below) but you can’t do anything with them:
In the list of options above, note that there isn’t a Seize or Transfer option for the application partitions. You can select them or view them:
But that’s it. There is a way to change the owner when you’re in this state however, keep reading.
So again, without going into a lot of depth on naming contexts and Application Partitions (I actually have another post that deals with this which will be published early next month dealing with DNS and App Partitions) we will move on for now. The bottom line is, you have a partition in your Active Directory database with no owner. We need to fix this, and we can’t use NTDSUTIL to get there.
The NORMAL way to go about changing FSMO role holders for the applications partitions is to use an editor like ADSIEdit or LDP. As shown in the first image above, you see that this region is editable. BUT as you’ve probably already noticed, this will error out “The role owner attribute could not be read” because there’s nobody to talk to (the value owner is gone).
So you need to force this change to happen. This is described in KB949257, unfortunately this article’s title is talking about issues doing an adprep /rodcprep – and a lot of people miss it or skip over it when in actuality it has exactly the script you need.
What you need to do is go to the DC you want to hold the role (I usually use the PDCE, but not for any particular reason). Now create a new file and call it fixfsmo.vbs:
Then dump this text into it:
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
And run the script from an elevated command prompt. You should now be able (through NTDSUTIL as shown above or through ADSIEdit) be able to see that the owner has changed to a valid DC.
For clarification, you should only run this script if the DC that is listed is no longer available and you can’t change it manually through ADSIEdit.
HTH!
Coo. This clears a few things up. I always thought if you had a partition in AD, you'd have to have an owner listed somewhere. Are these NDNC's?
Yes. Non-domain naming context. Also, might be good to clarify that there is a difference between a FSMO role and a fSMORoleOwner attribute. I don't want to confuse the two but I don't want to get into a bloated description in a comment field. It may be a good idea to expand on these concepts a bit more in another blog article in a few weeks.
is it Ok if I modify the script by deleting the following two lines, so its contents will run without the IF condition:
1) if (InStr(objInfra.fsmoroleowner, "\0ADEL:") > 0) then
2) End if
The above is a pair of IF statement which is embedded in another IF statement.
Thanks,
Ben
Somehow my previous comment was lost:
Because I have accidently "cleared" the fSMORoleOwner (which was point to a non-existed DC) and now it becomes to <Not Set>. The script seems to be not help because the embedded IF statement will not run (not effect).
Try copying and pasting the code from the kb article instead. (link above) and make sure and run that from the DC you want to take the role.
Thanks for your quick response Chris.
The script from MSKB is actually the same as yours, it does nothing when I run it on DC, because the current setting in fSMORoleOwner is <Not Set>. The IF statement I quoted in my earlier post has excluded to run because "if (InStr(objInfra.fsmoroleowner, "\0ADEL:") > 0)" is not ture (due to fSMORoleOwner is <Not Set>). So my concern is if I take away "IF ... End IF" two lines and let its content to run (set a new DC), would have any other side affect (unexpected consequance)? Thanks again! Ben
It looks the same but for some odd reason it is different. I had a customer prove it to me the other day and I've been meaning to update it after I figure it out... Anyway, that's neither here nor there. I get what you're saying now and no I can't imagine a way that could have any strange results. I've modified the script before for similar reasons... Let me ask you this, can you change the setting manually now? It may be as simple as that. Get the fsmo role owner value from another application partition and copy/paste.
Although the current fSMORoleOwner in ForestDnsZones is <Not Set>, but I still cannot set a new value (error message "...cannot be read"). I have run the script against DomainDnsZones, it was successful because the DomainDnsZones fSMORoleOwner had the value (although it had a wrong DC - a non existed DC); because I have "accidently" cleared ForestDnsZones fSMORoleOwner attribute and it has non-value ( <Not Set> ), hance, the embedded IF...End IF statement will not run. I would take the IF...end IF away (keep the inside content) and "force" it to run (un-conditional), but has raised my concern as mentioned previously due to overlook something? Thanks Chris.
My concern actually comes from the last sentance in your article:
"For clarification, you should only run this script if the DC that is listed is no longer available and you can’t change it manually through ADSIEdit."
Because my wrong DC is no longer listed in fSMORoleOwner attribute (value has been cleared to <Not Set>). Thanks. Ben
As I got the error when trying to set the attribute value on the domain controllers (schema master - where I run ADSIedit from) yesterday. However, I was able to set/save the value by connecting to the partition on the DC that actually is the infrastructure master later yesterday. Now today, my first thing is to check whether the value (fSMORoleOwner attribute) set on IM role DC yesterday has been replicated to all other DCs, especially onto the Schema Master role DC on which neither was I able to save the new value, nor by running the script to correct it (due to the value was <Not Set>, then the embedded IF condition content doesn’t execute). So all are good now, I even can see a new node named CN=OpsMgrLatencyMonitors has been created underneath both ForestDnsZones and DomainDnsZones. Thanks Chris for your hints. Ben
Hey, glad it all worked out :)
Hi, I'm having an issue with several similarities.
Originaly I had a W2K3 as DC which was the FSMO. Later I add a new W2K8R2 as a DC, and transfer to it the FSMO. Since then I added other 4 W2K8R2 as DC in different sites.
Now Im trying unsuccesfuly to remove the old W2K3 gracefuly with DCPROMO.
I'm getting a lots of issues same as in this note. The difference is that in my case the FSMO owner for the "DomainDNSzones" and "ForesDNSzones" is the old W2K3.
Is there a way to transfer (and not to sieze) this ownership since both DC exisit and funcition?
If there is not, should I seize the ownership with the VBS modified to skip the "IF"?
Could be this related to not running an "adprep /rodcprep" (I'm not planing to have any RODC?
Thanks in advance
Hi Chris, when i run it i get the following error: \fixfsmo.vbs(20, 5) (null): Name translation: Could not find the name or insufficient right to see name. any ideas? TIA
@ANC I got the same error when I used the script incorrectly. This worked for me. cscript fixfsmo.vbs dc=forestdnszones,dc=mydomain,dc=org then for domain zone: cscript fixfsmo.vbs dc=domaindnszones,dc=mydomain,dc=org I commented out the IF statement at the bottom as I had cleared the fsmoroleower value manually.