AD uses a multimaster concept, which simply means that changes and additions can be performed on each DC, assuming the correct permissions have been delegated.

That is also true for creating security principals like user-, group-, computer- and iNetOrgPerson objects. I mention "security principals" because those objects have SIDs and those SIDs MUST BE unique and available somewhere. To prevent conflicting issues between DCs concerning reusing RIDs, Microsoft created the RID Master FSMO within an AD domain which simply is responsible for the distribution of RID pools to DCs that ask for a RID pool. RID pools are requested and distributed in blocks of 500 RIDs (not 512). This value can be adjusted, but there is NO NEED to do that!

NOTE: One thing not to forget is that the RID Master FSMO needs outbound AD replication enabled (which is the default) to be able to distribute RID pools!!! This only applies for other DCs than the RID Master FSMO itself who request a new RID pool!!! Before the RID Master FSMO honors requests it must meet the initial inbound replication requirement!

 

The RID Master FSMO stored its information in the following object in AD:

  • CN=RID Manager$,CN=System,DC=<DOMAIN>,DC=<TLD>

 

When using LDP you can see the following attributes:

  • >> Dn: CN=RID Manager$,CN=System,DC=<DOMAIN>,DC=<TLD>
    • 2> objectClass: top; rIDManager;
    • 1> cn: RID Manager$;
    • 1> distinguishedName: CN=RID Manager$,CN=System,DC=<DOMAIN>,DC=<TLD>;
    • 1> instanceType: 0x4 = ( IT_WRITE );
    • 1> whenCreated: 12/11/2005 16:35:37 W. Europe Standard Time W. Europe Daylight Time;
    • 1> whenChanged: 12/11/2005 16:57:47 W. Europe Standard Time W. Europe Daylight Time;
    • 1> uSNCreated: 7325;
    • 1> uSNChanged: 12291;
    • 1> showInAdvancedViewOnly: TRUE;
    • 1> name: RID Manager$;
    • 1> objectGUID: 467fc132-227d-4f85-879f-0d43e83039c3;
    • 1> fSMORoleOwner: CN=NTDS Settings,CN=<DC>,CN=Servers,CN=<SITE>,CN=Sites,CN=Configuration,DC=<DOMAIN>,DC=<TLD>;
    • 1> rIDAvailablePool: 4611686014132422714;
    • 1> systemFlags: 0x8C000000 = ( FLAG_DISALLOW_DELETE | FLAG_DOMAIN_DISALLOW_RENAME | FLAG_DOMAIN_DISALLOW_MOVE );
    • 1> objectCategory: CN=RID-Manager,CN=Schema,CN=Configuration,DC=<DOMAIN>,DC=<TLD>;
    • 1> isCriticalSystemObject: TRUE;

 

That object stores two attributes that give interesting information to you:

  • fSMORoleOwner = the DN of the NTDS Settings object (the ID of a DC within an AD forest) that belongs to a DC in a certain AD domain
  • rIDAvailablePool = the pool of available RIDs within an AD domain stored as a large integer. From LDP you can use the pull down menu "Utilities" and select "Large Integer Converter" and convert that number to a high part and a low part. The high part is the highest RID number available (fixed value!) and the low part is the next lowest number available. You can also calculate it yourself by taking the value of rIDAvailablePool and substract the "high part * 2^32"
    • In this case:
      • rIDAvailablePool: 4611686014132422714
      • High-part: 1073741823
      • Low-Part: 2606
        (this means that the next DC will get a RID pool from 2606<->3105 - 500 RIDs - and the NEXT low-part will then be 3106)

 

DCs ask for a RID pool in the following occasions:

  • The current RID pool on a DC has been exhausted for 50% of its RIDs
  • The DC has been restored from a valid and supported backup tool/mrchanism (NOT FROM IMAGES!!!)
  • You manually kicked the operation attribute to request a new RID pool.

 

Each DC in its turn stores the RID pool information in the following object that is right beneath the computer account of the DC:

  • CN=RID Set,CN=<DC>,OU=Domain Controllers,DC=<DOMAIN>,DC=<TLD>

 

When using LDP you can see the following attributes:

  • >> Dn: CN=RID Set,CN=<DC>,OU=Domain Controllers,DC=<DOMAIN>,DC=<TLD>
    • 2> objectClass: top; rIDSet;
    • 1> cn: RID Set;
    • 1> distinguishedName: CN=RID Set,CN=<DC>,OU=Domain Controllers,DC=<DOMAIN>,DC=<TLD>;
    • 1> instanceType: 0x4 = ( IT_WRITE );
    • 1> whenCreated: 12/11/2005 17:02:49 W. Europe Standard Time W. Europe Daylight Time;
    • 1> whenChanged: 12/11/2005 16:57:48 W. Europe Standard Time W. Europe Daylight Time;
    • 1> uSNCreated: 12292;
    • 1> uSNChanged: 12292;
    • 1> showInAdvancedViewOnly: TRUE;
    • 1> name: RID Set;
    • 1> objectGUID: 85d8aaa9-fa0e-44b5-bdf8-6e2fe06e256d;
    • 1> rIDAllocationPool: 11188389808186;
    • 1> rIDPreviousAllocationPool: 9040906159686;
    • 1> rIDUsedPool: 0;
    • 1> rIDNextRID: 1906;
    • 1> objectCategory: CN=RID-Set,CN=Schema,CN=Configuration,DC=<DOMAIN>,DC=<TLD>;

 

That object stores several attributes that give interesting information to you:

  • rIDAllocationPool = a new RID pool is requested stored here when the "rIDPreviousAllocationPool" has been exhausted for 50% of its RIDs.
    • In this case:
      • rIDAllocationPool: 11188389808186
      • High-part: 2605
      • Low-Part: 2106
        (this means that the RID pool starts at 2106 and ends at 2605)
  • rIDPreviousAllocationPool = the CURRENT block of RIDs a DC uses when creating security principals. When this RID block is empty (exhausted for 100%) the block stored in the "rIDAllocationPool" attribute will be moved to this attribute. At that same moment the "rIDAllocationPool" attribute will remain "empty" until the "rIDPreviousAllocationPool" has been exhausted again for 50%
    • rIDAllocationPool: 9040906159686
      • High-part: 2105
      • Low-Part: 1606
        (this means that the RID pool starts at 1606 and ends at 2105)
  • rIDNextRID = the last used RID from the RID pool stored in the "rIDPreviousAllocationPool" attribute AND NOT the next rid to be used as imay look like!!! So the next security principal wil get the RID 1907 (according to the output shown above!)

 

A way to check the health of a DC when it concerns the RID Master FSMO and the allocation and distrbution of RID pools is to use DCDIAG.EXE from the Support Tools. This tools contains several tests and one of them is the "rIDManager Test"

By executing "DCDIAG /TEST:RIDMANAGER /V" (without the quotes) form the command line you will info like:

 

D:\>DCDIAG /TEST:RIDMANAGER /V

-----------------------------------PARTIAL OUTPUT-----------------------------------

Domain Controller Diagnosis

Performing initial setup:
   * Verifying that the local machine <DC>, is a DC.
   * Connecting to directory service on server <DC>.
   * Collecting site info.
   * Identifying all servers.
   * Identifying all NC cross-refs.
   * Found 3 DC(s). Testing 1 of them.
   Done gathering initial info.

Doing initial required tests

   Testing server: <SITE>\<DC>
      Starting test: Connectivity
         * Active Directory LDAP Services Check
         * Active Directory RPC Services Check
         ......................... <DC> passed test Connectivity

Doing primary tests

   Testing server: <SITE>\<DC>
      Test omitted by user request: Replications
      Test omitted by user request: Topology
      Test omitted by user request: CutoffServers
      Test omitted by user request: NCSecDesc
      Test omitted by user request: NetLogons
      Test omitted by user request: Advertising
      Test omitted by user request: KnowsOfRoleHolders
      Starting test: RidManager
         * Available RID Pool for the Domain is 2606 to 1073741823
         * <DC>.<DOMAIN>.<TLD> is the RID Master
         * DsBind with RID Master was successful
         * rIDAllocationPool is 2106 to 2605
         * rIDPreviousAllocationPool is 1606 to 2105
         * rIDNextRID: 1906
         ......................... <DC> passed test RidManager

(I mention partial output because it spits out all kinds information about tests that I omitted, which of course is not needed here)

-----------------------------------PARTIAL OUTPUT-----------------------------------

 

As you can see this shows:

  • The RID available pool within the domain
  • The DC that owns the RID Master FSMO role
  • If a bind was successful with the DC that owns the RID Master FSMO role
  • The second RID pool (rIDAllocationPool) a DC has
  • The first RID pool (rIDPreviousAllocationPool) a DC has
  • The next RID to be assigned when a security principal is created (rIDNextRID)


More information:

 

The following script (watch out for line breaks!) writes the operational attribute on the rootDSE, making the current RID pool that a DC has invalid and making it request a new RID pool from the RID Master FSMO. And of course this script is provided "AS-IS" and use it at your own risk within any environment.

-----------------------------------SCRIPT-----------------------------------

Option Explicit

Const HKLM = &H80000002

Dim WshShell
Dim strDC
Dim objWbemLocator, objWMISvc, objWMIReg
Dim strKeyPath, strValueName, strServerRole
Dim objROOT
Dim strDefaultNC
Dim objDomain
Dim strDomainSID

Set WshShell = Wscript.CreateObject("Wscript.Shell")

strDC = UCase(WshShell.ExpandEnvironmentStrings("%COMPUTERNAME%") & "." & WSHShell.RegRead ("HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Domain"))

Set objWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMISvc = objWbemLocator.ConnectServer(strDC, "root\default", "", "")
Set objWMIReg = objWMISvc.Get("StdRegProv")
strKeyPath = "SYSTEM\CurrentControlSet\Services\NTDS\Parameters"
strValueName = "Machine DN Name"
objWMIReg.GetStringValue HKLM,strKeyPath,strValueName,strServerRole
 
If strServerRole <> "" Then
 Set objROOT = GetObject("LDAP://" & strDC & "/RootDSE")
 strDefaultNC = objROOT.Get("defaultNamingContext")
 Set objDomain = GetObject("LDAP://" & strDC & "/" & strDefaultNC)
 strDomainSID = objDomain.objectSID
 objROOT.Put "invalidateRidPool", strDomainSID
 objROOT.SetInfo
 Wscript.Echo("The current RID pool has been invalidated!")
 Wscript.Echo("A new RID pool will be requested from the RID Master FSMO!")
Else
 Wscript.Echo(strDC & " is not a DC!")
End If

Set WshShell = Nothing
Set strDC = Nothing
Set objWbemLocator = Nothing
Set objWMISvc = Nothing
Set objWMIReg = Nothing
Set strKeyPath = Nothing
Set strValueName = Nothing
Set strServerRole = Nothing
Set objROOT = Nothing
Set strDefaultNC = Nothing
Set objDomain = Nothing
Set strDomainSID = Nothing

-----------------------------------SCRIPT-----------------------------------

 

Jorge

-------------------------------------------------------------------------------------------------
* This posting is provided "AS IS" with no warranties and confers no rights!
* Always test before implementing!
-------------------------------------------------------------------------------------------------