81 objReg.SetStringValue HKLM, strTimeServerReg, "type", "NTP" strCurrentServer = "" objReg.GetStringValue HKLM, strTimeServerReg, "ntpserver", strCurrentServer WScript.Echo "New Value: " & strCurrentServer ' Restart Time Service set objService = GetObject("winmgmts://" & strPDC & _ "/root/cimv2:Win32_Service='W32Time'") WScript.Echo "Stopping " & objService.Name objService.StopService( ) Wscript.Sleep 2000 ' Sleep for 2 seconds to give service time to stop WScript.Echo "Starting " & objService.Name objService.StartService( ) 3.13.3 Discussion You need to set a reliable time source on the PDC Emulator FSMO for only the forest root domain. All other domain controllers sync their time either from that server or from a PDC (or designated time server) within their own domain. The list of external time servers is stored in the registry under the W32Time Service registry key in the following location: HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Parameters\ntpserver. If you want a domain controller, such as the PDC, to use an external time source, you have to set the ntpserver registry value along with the type value. The default value for type on a domain controller is Nt5DS, which means that the domain controller will use the Active Directory domain hierarchy to find a time source. You can override this behavior and have a domain controller contact a non-DC time source by setting type to NTP. In the CLI example, the /setsntp switch automatically sets the type value to NTP. In the VBScript solution, I had to set it in the code. After setting the time server, the W32Time service should be restarted for the change to take effect. You can check that the server was set properly by running the following command: > net time /querysntp Since the PDC Emulator is the time source for the other domain controllers, you should also make sure that it is advertising the time service, which you can do with the following command: > nltest /server:<DomainControllerName> /dsgetdc:<DomainDNSName> /TIMESERV 3.13.4 See Also MS KB 216734 (How to Configure an Authoritative Time Server in Windows 2000), MS KB 223184 (Registry Entries for the W32Time Service), MS KB 224799 (Basic Operation of the Windows Time Service), MSDN: StdRegProv, and MSDN: Win32_Service 82 Recipe 3.14 Finding the Number of Logon Attempts Made Against a Domain Controller 3.14.1 Problem You want to find the number of logon requests a domain controller has processed. 3.14.2 Solution The following query returns the number of logon requests processed: > nltest /server:<DomainControllerName> /LOGON_QUERY 3.14.3 Discussion The nltest /LOGON_QUERY command is a wrapper around the I_NetLogonControl2 method, and can be useful to determine how many logon requests are being processed by a server. Viewing the results of the command over a period of time and comparing them against a server in the same domain can also tell you if one server is being used significantly more or less than the others. 3.14.4 See Also MSDN: I_NetLogonControl2 Recipe 3.15 Enabling the /3GB Switch to Increase the LSASS Cache 3.15.1 Problem You are using more than 1 GB of memory on your domain controllers and want to enable the /3GB switch so that the LSASS process can use more memory. 3.15.2 Solution Edit the boot.ini file on the domain controller to contain the /3GB switch: [boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)partition(2)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(2)\WINDOWS="Windows Server 2003" /3GB Restart the computer. 83 On Windows Server 2003, you can edit the boot.ini file by opening the System applet in the Control Panel. Click the Startup and Recovery tab and click the Edit button. On Windows 2000, it is not so easy. You need to open an Explorer window, select Tools Folder Options, and click the view tab. Uncheck "Hide protected operating system files (Recommended)," and check "Show hidden files and folders." Now browse to the root of your operating system partition (e.g., C:) and edit the boot.ini file with a text editor. 3.15.3 Discussion When computers are referred to as 32 or 64-bit computers that means they support memory addresses that are 32 or 64 bits long. This is the total available memory (virtual and real) that can be processed by the system. Since the days of Windows NT, Microsoft has split memory allocation in half by giving applications up to 2 GB and the Windows kernel 2 GB of memory to use (32 bits of address space = 2 ^32 = 4 GB). In many cases, administrators would rather allocate more memory to applications than to the kernel. For this reason, Microsoft developed the /3GB switch to allow applications to use up to 3 GB of memory, leaving the kernel with 1 GB. The /3GB switch is supported only on Windows 2000 Advanced Server, Windows 2000 Datacenter Server, Windows Server 2003 Enterprise Edition, and Windows Server 2003 Data Center Edition, and should be used only if the computer has more than 1 GB of physical memory. For a good description of how LSASS uses memory, see MS KB 308356. 3.15.4 See Also MS KB 99743 (Purpose of the BOOT.INI File in Windows 2000 or Windows NT), MS KB 291988 (A Description of the 4 GB RAM Tuning Feature and the Physical Address Extension Switch), and MS KB 308356 (Memory Usage By the Lsass.exe Process on Windows 2000- Based Domain Controllers) Recipe 3.16 Cleaning Up Distributed Link Tracking Objects 3.16.1 Problem You want to make sure the Distributed Link Tracking (DLT) service is disabled and all DLT objects are removed from Active Directory. The Distributed Link Tracking Server service is used to track links to files on NTFS partitions. If a file that has a shortcut to it is renamed or moved, Windows uses the DLT service to find the file when the shortcut is opened. Most organizations are unaware this service even exists, but yet it can populate thousands of objects in Active Directory. Unless you are actively using the functionality of the DLT service, it is recommended that you disable it. 84 3.16.2 Solution If you upgrade a Windows 2000 domain controller to Windows Server 2003, the DLT Server service is stopped and set to disabled. A new install of Windows Server 2003 also has the service stopped and set to disabled. But the DLT Server service on Windows 2000 domain controllers is enabled by default. Unless you need it, you should stop the service and disable it on all of your domain controllers. Next, you'll need to remove any DLT objects (linkTrackVolEntry and linkTrackOMTEntry) from Active Directory. Since there can be hundreds of thousands of DLT objects, you will probably want to stagger the deletion of those objects. The script in MS KB 315229 (dltpurge.vbs) can delete DLT objects over a period of time instead of all at once. Here is an example of running the dltpurge.vbs script against the dc1 domain controller in the rallencorp.com domain: > cscript dltpurge.vbs -s dc1 -d dc=rallencorp,dc=com 3.16.3 Discussion DLT consists of a client and server service. The server service runs on domain controllers and the client service can run on any Windows 2000 or later machine. The server service stores data in Active Directory in the form of linkTrackVolEntry and linkTrackOMTEntry objects, which are used to track the names and locations of files on NTFS partitions. The cn=ObjectMoveTable,cn=FileLinks,cn=System,<DomainDN> container stores linkTrackOMTEntry objects that contain information about files that have been moved on computers in the domain. The cn=VolumeTable,cn=FileLinks,cn=System,<DomainDN> container stores linkTrackVolEntry objects that represent NTFS volumes on computers in the domain. Over time, the number of DLT objects can grow substantially. Even though those objects do not take up much space, if you are not actively taking advantage of this service, you should consider disabling it and removing all DLT objects from Active Directory. If you remove a lot of DLT objects, you should determine how much space you can reclaim on the disk of the domain controllers by performing an offline defrag. See Recipe 16.12 for more information. 3.16.4 See Also MS KB 232122 (Performing Offline Defragmentation of the Active Directory Database), MS KB 312403 (Distributed Link Tracking on Windows-Based Domain Controllers), and MS KB 315229 (Text Version of Dltpurge.vbs for Microsoft Knowledge Base Article Q312403) Recipe 3.17 Enabling and Disabling the Global Catalog 3.17.1 Problem You want to enable or disable the global catalog on a particular server. 85 3.17.2 Solution 3.17.2.1 Using a graphical user interface 1. Open the Active Directory Sites and Services snap-in. 2. Browse to the nTDSDSA object (NTDS Settings) underneath the server object for the domain controller you want to enable or disable the global catalog for. 3. Right-click on NTDS Settings and select Properties. 4. Under the General tab, check (to enable) or uncheck (to disable) the box beside Global Catalog. 5. Click OK. 3.17.2.2 Using a command-line interface In the following command, <ServerObjectDN> should be the server object DN, not the DN of the nTDSDSA object. > dsmod server "<ServerObjectDN>" -isgc yes|no For example, the following command will enable the global catalog on dc1 in the Raleigh site: > dsmod server[RETURN] "cn=DC1,cn=servers,cn=Raleigh,cn=sites,cn=configuration,dc=rallencorp,dc=com" -isgc[RETURN] yes 3.17.2.3 Using VBScript ' This code enables or disables the GC for the specified DC ' SCRIPT CONFIGURATION strDC = "<DomainControllerName>" ' e.g. dc01.rallencorp.com strGCEnable = 1 ' 1 = enable, 0 = disable ' END CONFIGURATION set objRootDSE = GetObject("LDAP://" & strDC & "/RootDSE") objNTDS = GetObject("LDAP://" & strDC & "/" & _ objRootDSE.Get("dSServiceName")) objNTDS.Put "options", strGCEnable objNTDS.SetInfo 3.17.3 Discussion The first domain controller promoted into a forest is by default also made a global catalog server. If you want additional servers to have the global catalog, you have to enable it. The global catalog on a domain controller becomes enabled when the low-order bit on the options attribute on the nTDSDSA object under the server object for the domain controller is set to 1. The DN of this object for dc1 in the Default-First-Site-Name site looks like this: cn=NTDSSettings,cn=DC1,cn=Default-First-Site- Name,cn=Sites,cn=Configuration,dc=rallencorp,dc=com. 86 After enabling the global catalog, it can take some time before the domain controller can start serving as a global catalog server. The length of time is based on the amount of data that needs to replicate and the type of connectivity between the domain controller's replication partners. After replication is complete, you should see Event 1119 in the Directory Services log stating the server is advertising itself as a global catalog. At that point you should also be able to perform LDAP queries against port 3268 on that server. See Recipe 3.18 for more information on how to determine if global catalog promotion is complete. 3.17.4 See Also Recipe 3.18 for determining if global catalog promotion is complete, and MS KB 313994 (HOW TO: Create or Move a Global Catalog in Windows 2000) Recipe 3.18 Determining if Global Catalog Promotion Is Complete 3.18.1 Problem You want to determine if a domain controller is a global catalog server. After you initially enable the global catalog on a domain controller, it can take some time for all of the read-only naming contexts to replicate to it, depending on how large your forest is. 3.18.2 Solution Query the isGlobalCatalogReady attribute on the RootDSE for the domain controller. A TRUE value means the server is a global catalog and a FALSE value indicates it is not. For more information on how to query the RootDSE, see Recipe 4.1. 3.18.3 Discussion Once a server has completed initial replication of the global catalog, the isGlobalCatalogReady attribute in the RootDSE will be marked TRUE. Another way to determine if a domain controller has been at least flagged to become a global catalog is by checking if the options attribute on the nTDSDSA object for the server has been set to 1. Note that this does not necessarily mean the server is accepting requests as a global catalog. An additional query to the RootDSE as described in the Solution, or directly to port 3268 (the global catalog port) could confirm it. 3.18.4 See Also Recipe 4.1 for viewing the RootDSE 87 Recipe 3.19 Finding the Global Catalog Servers in a Forest 3.19.1 Problem You want a list of the global catalog servers in a forest. 3.19.2 Solution 3.19.2.1 Using a graphical user interface 1. Open LDP and from the menu select Connection Connect. 2. For Server, enter the name of a DC. 3. For Port, enter 389. 4. Click OK. 5. From the menu select Connection Bind. 6. Enter credentials of a domain user. 7. Click OK. 8. From the menu select Browse Search. 9. For BaseDN, type the DN of the Sites container (e.g., cn=sites,cn=configuration,dc=rallencorp, dc=com). 10. For Scope, select Subtree. 11. For Filter, enter (&(objectcategory=ntdsdsa)(options=1)). 12. Click Run. 3.19.2.2 Using a command-line interface > dsquery server -forest -isgc 3.19.2.3 Using VBScript ' This code prints the global catalog servers for the specified forest. ' SCRIPT CONFIGURATION strForestName = "<ForestDNSName>" ' e.g. rallencorp.com ' END CONFIGURATION set objRootDSE = GetObject("LDAP://" & strForestName & "/" & "RootDSE") strADsPath = "<LDAP://" & objRootDSE.Get("configurationNamingContext") & ">;" strFilter = "(&(objectcategory=ntdsdsa)(options=1));" strAttrs = "distinguishedname;" strScope = "SubTree" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strADsPath & strFilter & strAttrs & strScope) objRS.MoveFirst while not objRS.EOF set objNTDS = GetObject("LDAP://" & objRS.Fields(0).Value) set objServer = GetObject( objNTDS.Parent ) Wscript.Echo objServer.Get("dNSHostName") 88 objRS.MoveNext wend 3.19.3 Discussion To find the global catalog servers in a forest, you need to query for NTDS Settings objects that have the low-order bit of the options attribute equal to 1 under the sites container in the Configuration Naming Context. That attribute determines if a domain controller should be a global catalog server, but it does not necessarily mean it is a global catalog server yet. See Recipe 3.18 for more information on how to tell if a server marked as a global catalog is ready to accept requests as one. Another option for locating global catalogs is DNS, which is described in Recipe 3.21. 3.19.4 See Also Recipe 3.18 for determining if global catalog promotion is complete Recipe 3.20 Finding the Domain Controllers or Global Catalog Servers in a Site 3.20.1 Problem You want a list of the domain controllers or global catalog servers in a specific site. 3.20.2 Solution 3.20.2.1 Using a graphical user interface 1. Open the Active Directory Sites and Services snap-in. 2. In the right pane, expand the site that contains the domain controller. 3. For the list of domain controllers, expand the Servers container. 4. To find the global catalog servers, expand each domain controller, right-click on NTDS Settings , and select Properties. 5. Global catalog servers will have the box checked beside Global Catalog. 3.20.2.2 Using a command-line interface The following query finds all domain controllers in specified site. > dsquery server -site <SiteName> To find only the global catalog servers in a site, use the same command with the -isgc option. > dsquery server -site <SiteName> -isgc 89 3.20.2.3 Using VBScript ' This code prints the domain controllers in a site and then ' prints the global catalog servers in the site ' SCRIPT CONFIGURATION strSite = "<SiteName>" ' e.g. Default-First-Site-Name strForest = "<ForestDNSName>" ' e.g. rallencorp.com ' END CONFIGURATION set objRootDSE = GetObject("LDAP://" & strForest & "/RootDSE") strADsPath = "<LDAP://cn=servers,cn=" & strSite & ",cn=sites," & _ objRootDSE.Get("configurationNamingContext") & ">;" strFilter = "(objectcategory=ntdsdsa);" strAttrs = "distinguishedName;" strScope = "SubTree" WScript.Echo "Domain controllers in " & strSite & ":" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strADsPath & strFilter & strAttrs & strScope) objRS.MoveFirst while not objRS.EOF Set objNTDS = GetObject("LDAP://" & objRS.Fields(0).Value) Set objServer = GetObject( objNTDS.Parent ) Wscript.Echo " " & objServer.Get("dNSHostName") objRS.MoveNext wend ' Global Catalog filter strFilter = "(&(objectcategory=ntdsdsa)(options=1));" WScript.Echo "" WScript.Echo "Global Catalogs in " & strSite & ":" set objRS = objConn.Execute(strADsPath & strFilter & strAttrs & strScope) objRS.MoveFirst while not objRS.EOF set objNTDS = GetObject("LDAP://" & objRS.Fields(0).Value) set objServer = GetObject( objNTDS.Parent ) Wscript.Echo " " & objServer.Get("dNSHostName") objRS.MoveNext wend 3.20.3 Discussion Each domain controller has a server object within the Servers container for the site it is a member of (e.g., cn=DC1,cn=Servers,cn=MySite, cn=site, cn=configuration, dc=rallencorp, dc=com). Since other types of servers can have server objects in a site's Servers container, domain controllers are differentiated by the nTDSDSA object that is a child of the server object (e.g., cn=NTDSSettings,cn=DC1,cn=Servers,cn=MySite, cn=site, cn=confiugration, dc=rallencorp, dc=com). Querying for this nTDSDSA objects will return a list of domain controllers in the site. Locating global catalog servers consists of the same query, except where the low-order bit of the options attribute of the nTDSDSA object is equal to 1. 90 Recipe 3.21 Finding Domain Controllers and Global Catalogs via DNS 3.21.1 Problem You want to find domain controllers or global catalogs using DNS lookups. 3.21.2 Solution Domain controllers and global catalog servers are represented in DNS as SRV records. You can query SRV records using nslookup by setting the type=SRV, such as the following: > nslookup Default Server: dns01.rallencorp.com Address: 10.1.2.3 > set type=SRV You then need to issue the following query to retrieve all domain controllers for the specified domain. > _ldap._tcp.<DomainDNSName> You can issue a similar query to retrieve global catalogs, but since they are forest-wide, the query is based on the forest name. > _gc._tcp.<ForestDNSName> You can even find the domain controllers or global catalogs that are in a particular site or that cover a particular site by querying the following: > _ldap._tcp.<SiteName>._sites.<DomainDNSName> > _gc._tcp.<SiteName>._sites.<ForestDNSName> See Recipe 11.18 for more information on site coverage. 3.21.3 Discussion One of the benefits of Active Directory over its predecessor Windows NT is that it relies on DNS for name resolution. Active Directory uses DNS to locate servers that serve a particular function, such as a domain controller for a domain, global catalog server, PDC Emulator, KDC. It also uses the site topology information stored in Active Directory to populate site-specific records for domain controllers. The DC locator process relies on this information in DNS to direct clients to the most optimal server when logging in. Reliance on DNS makes it easy to troubleshoot problems related to . switch is supported only on Windows 2000 Advanced Server, Windows 2000 Datacenter Server, Windows Server 2003 Enterprise Edition, and Windows Server 2003 Data Center Edition, and should be used. dsquery server -forest -isgc 3.19.2.3 Using VBScript ' This code prints the global catalog servers for the specified forest. ' SCRIPT CONFIGURATION strForestName = "<ForestDNSName>". controller to Windows Server 2003, the DLT Server service is stopped and set to disabled. A new install of Windows Server 2003 also has the service stopped and set to disabled. But the DLT Server