How to determine the fsmo role holder (fsmoRoleOwner attribute)

This article describes how to find the servers that hold the Flexible Single Master Operation (FSMO) roles in a forest.

Active Directory defines five FSMO roles:

Per-forest roles, one per forest:

  • Schema master
  • Domain naming master

Per-domain roles, one per domain:

  • RID master
  • PDC master
  • Infrastructure master

 

To determine the master for a partition, query the fSMORoleOwner attribute on the corresponding object under the naming context root in question:

Schema Master:
LDAP://cn=Schema,cn=Configuration,dc=contoso,dc=com

Domain Naming Master:
LDAP://cn=Partitions,cn=Configuration,dc=contoso,dc=com

PDC Role Owner:
LDAP://dc=concorp,dc=contoso,dc=com

Infrastructure Master:
LDAP://cn=Infrastructure, dc=concorp,dc=contoso,dc=com

RID Master:
LDAP://cn=RID Manager$,cn=System, dc=concorp,dc=contoso,dc=com

You can use tools such as ldifde to perform queries to get FSMO role holders:

ldifde -f Infrafsmo.ldf -d "CN=Infrastructure,DC=concorp,DC=contoso,DC=com" -l fSMORoleOwner

This query returns the infrastructure master role owner for the DC=concorp,DC=contoso,DC=com partition to the Infrafsmo.ldf file.

The information in the attribute is stored as a DN, representing the NTDS Settings object of the DC that is the role owner. Example:

CN=NTDS Settings,CN=DC1,CN=Servers,CN=SITE1,CN=Sites,CN=Configuration,DC=contoso,DC=com

The following c# code returns the PDC role owner:

static void Main(string[] args)
{
  DirectoryEntry DomDn = new DirectoryEntry("LDAP://dc=concorp,dc=contoso,dc=com");
  DirectoryEntry PDCfsmo = new DirectoryEntry("LDAP://" + DomDn.Properties["fsmoRoleOwner"].Value.ToString());

  Console.WriteLine (PDCfsmo.Parent.Properties["dnsHostName"].Value.ToString());

  PDCfsmo.Close();
  DomDn.Close();
}

Same as previoulsy, the following VBscript code returns the PDC role owner:

Set objDomDn = GetObject("LDAP://dc=concorp,dc=contoso,dc=com")
strfsmoRoleOwner = objDomDn.Get("fsmoRoleOwner")

Set objPDCfsmo = GetObject("LDAP://" &  strfsmoRoleOwner)
Set objPDCfsmoParent = GetObject(objPDCfsmo.Parent)
 
Wscript.Echo  objPDCfsmoParent.Get("dnsHostName")

How to Get all Group Policy links applied to an OU (gPLink attribute)

In GPO terms, domains, OUs, and sites are called Scopes of Management (SOMs).
SOM container object, such as OU has an attribute called gPLink that lists all of the GPOs applied to the object.
This attribute contains a list of GPO distinguished names and a Boolean to indicate whether the GPO DN is enforced. It looks like this :

 
[<GPO DN_1>;<GPLinkOptions_1>][<GPO DN_2>;<GPLinkOptions_2>]... [<GPODN_n>;<GPLinkOptions_n>]

Ex: 
[LDAP://cn={8BE35F55-E3DF-4D1C-8C3A-39F81F451D86},cn=policies,cn=system,DC=ad,DC=foo,DC=local;2]
[LDAP://cn={946584E4-F1CD-458E-8366-8A549FF2E4B2},cn=policies,cn=system,DC=ad,DC=foo,DC=local;0]
[LDAP://cn={92845926-AE1B-49C4-A33A-92441D29DDB7},cn=policies,cn=system,DC=ad,DC=foo,DC=local;1]

GPLinkOptions meaning:
0: The GPO Link is not ignored and is not an enforced GPO. This is the default value
1: The GPO Link MUST be ignored.
2: The GPO Link is an enforced GPO.

The order in which GPO paths appear in this attribute specifies the link order for the associated GPOs. In the GPMC console, you will see :
GPO DN_n
..
GPO DN_2
GPO DN_1

The “GPO DN_n” will have precedence over “GPO DN_n-1” .. “GPO DN_2”, “GPO DN_1”

GetGPO("LDAP://OU=sales,OU=people,DC=ad,DC=foo,DC=local")

Function GetGPO (objldap)

 Set objContainer = GetObject (objldap)
 strGpLink = objContainer.Get("gPLink")
	
 If Len(strGpLink) > 0 Then
		
   arrGpLinkItems = Split(strGpLink,"]")
   For each el in arrGpLinkItems
	WScript.Echo Mid(el,2, Len(el)-3)
	Set objgpo = GetObject (Mid(el,2, Len(el)-3))
	WScript.Echo objgpo.DisplayName
   Next
	
 End If	     
End Function