Nearly 50 different settings can be configured on a Microsoft DNS Server. They range from scavenging and logging settings to settings that customize the name server's behavior, such as how zone transfers are sent to secondaries and whether to round-robin responses that include multiple A records. A name server is represented by an instance of the MicrosoftDNS_Server class. Table 14-1[2] contains all the property methods defined in the MicrosoftDNS_Server class.
[2] For the latest list of supported properties and methods for any of the DNS Provider classes, check out the MSDN documentation: http://msdn.microsoft.com/library/en-us/dns/dns/microsoftdns_server.asp. If that link becomes out of date, you should be able to find the documentation by going to http://msdn.microsoft.com/ and searching on MicrosoftDNS_Server.
Property name |
Property description |
---|---|
AddressAnswerLimit |
Maximum number of records to return for address requests (i.e., A records). This value can be a number between 5 and 28. The default value is 0, which does not limit the number of records that can be returned. |
AllowUpdate |
Determines whether dynamic updates are allowed. The value of this property can be any sum of the following values:
The default value is 0. |
AutoCacheUpdate |
Boolean that indicates whether the name server dynamically attempts to update its root hints (also known as cache) file. The default value is TRUE, which means the server auto-updates its root hints. |
AutoConfigFileZones |
Indicates whether the name server attempts to automatically update any zone it knows about that has an A, NS, or SOA record when the name of the server changes. The value for this property can be one of the following:
The default value is 1. |
BindSecondaries |
Boolean that if TRUE causes the name server to send zone transfers in a less efficient (but more interoperable) format to non-Microsoft DNS Servers. The default value is TRUE. |
BootMethod |
Determines where the server reads its zone information. The value for this property can be one of the following:
The default value is 3. |
DefaultAgingState |
Boolean that indicates whether aging is enabled for AD-integrated zones. The default value is FALSE (not enabled). |
DefaultNoRefreshInterval |
For AD-integrated zones, the default no-refresh interval in hours. The default value is 168 (one week). |
DefaultRefreshInterval |
For AD-integrated zones, the default refresh interval in hours. The default value is 168 (one week). |
DisableAutoReverseZones |
Boolean that determines whether the name server automatically creates reverse zones for 0.in-addr.arpa, 127.in-addr.arpa, and 255.in-addr.arpa. The default value is FALSE (the reverse zones are created). |
DisjointNets |
Boolean that indicates whether the default port binding for a socket used to send queries to remote name servers can be overridden. |
DsAvailable |
Boolean that indicates whether Active Directory is available on the server. |
DsPollingInterval |
For AD-integrated zones, the interval in minutes to poll Active Directory for updates. The default value is 5 minutes. |
DsTombstoneInterval |
For AD-integrated zones, the length of time in seconds for which tombstoned (i.e., deleted) records should remain in Active Directory. In 99.99% of deployments the default of 604800 (one week) should not need changing. |
EdnsCacheTimeout |
Length of time, in seconds, that the Extension Mechanisms for DNS (EDNS0) version information about a remote name server is cached. (You can find more information on EDNS0 in RFC 2671.) Valid values range from 3600 (one hour) to 15724800 (182 days). The default value is 604800 (one week). |
EnableDirectoryPartitionSupport |
Boolean that indicates whether application partition support has been enabled. Valid only for domain controllers in a forest at the Windows Server 2003 functional level. |
EnableDnsSec |
Flag indicating whether DNSSEC resource records are returned if queried. The value of this property can be one of the following:
The default is 1. |
EnableEDnsProbes |
When TRUE, the name server probes other DNS servers to determine if they support EDNSO. The default is 1 (TRUE). |
EventLogLevel |
Determines the type of events (i.e., errors or warnings) that are logged to the DNS Event Log. The value of this property can be one of the following:
The default value is 4. |
ForwardDelegations |
Determines whether queries for data in delegated subzones are sent to forwarders or follow the delegation. The value of this property can be one of the following:
The default value is 0. |
Forwarders |
Array of IP addresses the server forwards queries to. |
ForwardingTimeout |
Time in seconds to wait for a response from a forwarded query. The default value is 5 seconds. |
IsSlave |
Boolean that indicates how the name server responds when forwarded queries do not receive a response. If FALSE, the server attempts to resolve the query and if TRUE the server returns a failure. The default value is FALSE. |
ListenAddresses |
Array of addresses the name server can receive queries on. |
LocalNetPriority |
If TRUE, the name server orders records that have a similar IP address to it at the top of the response. If FALSE, then no priority is given based on IP address. This is called "netmask ordering" in the DNS console. The default value is TRUE. |
LogFileMaxSize |
Maximum size in bytes of the DNS debug log. The default value is 500000000. |
LogFilePath |
Filename and path to the DNS debug log. The default is %SystemRoot%\system32\dns\dns.log. |
LogIPFilterList |
Array of IP addresses used to filter entries written to the DNS debug log |
LogLevel |
Determines which events should be written to the debug log. The value of this property can be the sum of any of the following values:
|
LooseWildcarding |
Boolean that indicates whether the server supports wildcards. The default value is FALSE (do not use loose wildcarding). |
MaxCacheTTL |
Maximum time-to-live value, in seconds, to accept for records from a remote name server. The default value is 86400 (one day). |
MaxNegativeCacheTTL |
Maximum time-to-live value, in seconds, to accept from a remote name server for a negative response (e.g., one that indicates that a particular domain name doesn't exist). The default value is 86400 (one day). |
Name |
Domain name or IP address of server |
NameCheckFlag |
Indicates the set of eligible characters to be used in domain names. The value for this property can be one of the following:
The default value is 2. |
NoRecursion |
Boolean indicating whether the name server processes recursive queries. The default value is FALSE, which means the name server performs recursive resolution. |
RecursionRetry |
Time in seconds before retrying a recursive look up. The default value is 3 seconds. |
RecursionTimeout |
Time in seconds before the name server gives up on processing a recursive query. The default value is 15 seconds. |
RoundRobin |
Boolean that indicates whether the name server round-robins addresses in responses that return multiple A records. The default value is TRUE. |
RpcProtocol |
Protocol to run administrative RPC over. The value of this property can be any sum of the following:
The default value is all protocols. |
ScavengingInterval |
Interval in hours between scavenging runs. The default value is 168 hours (one week). |
SecureResponses |
Boolean that indicates whether the name server exclusively caches records of names in the same subtree as the server that provided them. If FALSE, all records are cached, but if TRUE, records are cached only if the name server that responded to the forwarded query is in the same subtree as the returned record. The default value is TRUE. This setting is called "Secure cache against pollution" in the DNS console. |
SendPort |
Port number from which the name server sends UDP queries to other name servers. The default value is 0, which means a port number is randomly selected. |
ServerAddresses |
Array of IP addresses for the server. |
StrictFileParsing |
Boolean that indicates whether the name server parses zone files strictly, which means that if bad data is encountered, the zone fails to load. The default value is FALSE, which means the server continues to load the zone. |
UpdateOptions |
Flag that restricts the type of records that can be updated via DDNS. Used in conjunction with AllowUpdate. The value of this property can be any sum of the following values:
The default value is 0. |
Version |
Name server version. |
WriteAuthorityNS |
Boolean that indicates whether the server includes NS and SOA records in the authority section of all successful authoritative responses. The default is FALSE, which means it writes NS records in the Authority section for referrals only, per RFC 2181. |
XfrConnectTimeout |
Number of seconds the name server waits for a successful TCP connection to a remote name server when attempting a zone transfer. The default value is 30 seconds. |
The MicrosoftDNS_Server class also provides a few methods to initiate certain actions on the name server. Two of the most useful are StartService and StopService, which allow you to start and stop the DNS Server service. Table 14-2 lists MicrosoftDNS_Server methods.
Method name |
Method description |
---|---|
GetDistinguishedName |
For AD-integrated zones, gets the DN of the zone. |
StartScavenging |
Start the scavenging process for zones that have scavenging enabled. |
StartService |
Start the DNS service. |
StopService |
Stop the DNS service. |
The first step to programmatically managing your name server's configuration is to see what settings you currently have in place and determine whether any need to be modified. With WMI, it's really easy to list all properties for a name server. The following example shows how to do it:
strServer = "terminator.movie.edu" ' Instantiate a WMI object for the target server set objDNS = GetObject("winmgmts:\\" & strServer & "\root\MicrosoftDNS") ' Get an instance of the MicrosoftDNS_Server class set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""") ' Iterate over each property using Properties_ Wscript.Echo objDNSServer.Properties_.Item("Name") & ":" for each objProp in objDNSServer.Properties_ if IsNull(objProp.Value) then Wscript.Echo " " & objProp.Name & " : NULL" else if objProp.IsArray = TRUE then For I = LBound(objProp.Value) to UBound(objProp.Value) wscript.echo " " & objProp.Name & " : " & objProp.Value(I) next else wscript.echo " " & objProp.Name & " : " & objProp.Value end if end if next
After getting a WMI object for the DNS Provider (root\MicrosoftDNS), we get a MicrosoftDNS_Server object by looking for the "." instance. Since there can be only one instance of MicrosoftDNS_Server running on any given computer, we do not need to worry about multiple objects. After getting a MicrosoftDNS_Server object, we iterate through all the properties of the object and print each one out. Note that we have added special checks for values that contain arrays in order to print each element of the array. In that case, we use Lbound and Ubound to iterate over all the values for the array.
Now that we can see what values have been set on our name server, we can change some of them. We simply need to set the property method (e.g., EventLogLevel) to the correct value. This example shows how to do it:
strServer = "terminator.movie.edu" on error resume next set objDNS = GetObject("winMgmts:\\" & strServer & "\root\MicrosoftDNS") set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""") Wscript.Echo objDNSServer.Name & ":" ' See Table 14-1 for an explanation of each of these settings objDNSServer.EventLogLevel = 4 objDNSServer.LooseWildcarding = TRUE objDNSServer.MaxCacheTTL = 900 objDNSServer.MaxNegativeCacheTTL = 60 objDNSServer.AllowUpdate = 3 objDNSServer.Put_ if Err then Wscript.Echo " Error occurred: " & Err.Description else WScript.Echo " Change successful" end if
Note that we had to call Put_ at the end. If we hadn't, none of the changes would have been committed. This is similar to ADSI's SetInfo method, which must be called after modifying an object's property cache to make the change actually take effect.
Some changes you make to a DNS Server require the service to be restarted for the changes to take effect. We can utilize the StopService and StartService methods as shown in the following example to do this:
strServer = "terminator.movie.edu" on error resume next set objDNS = GetObject("winMgmts:\\" & strServer & "\root\MicrosoftDNS") set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""") objDNSServer.StopService if Err Then WScript.Echo "StopService failed: " & Err.Description Wscript.Quit end if objDNSServer.StartService if Err Then WScript.Echo "StartService failed: " & Err.Description Wscript.Quit end if WScript.Echo "Restart successful"
Building on the examples we've used so far in this chapter, we can now write a robust script to check name server configurations. Such a script can be very important, especially in large environments with many name servers. Unless you have a script that routinely checks the configuration on all of your name servers, it's very likely that those servers will not have an identical configuration. If they don't have identical configurations, then when problems pop up, you may end up spending a lot of time troubleshooting because of the discrepancies between the name servers.
To perform the configuration checking, we store each setting in a VBScript Dictionary object. For those accustomed to other languages such as Perl, a Dictionary object is the VBScript analog to a hash or associative array. Another option would be to store the settings in a text file and read them into a Dictionary object when the script starts up. The following example shows the configuration check code:
option explicit on error resume next Dim arrServers Dim strUsername, strPassword Dim dicDNSConfig ' Array of DNS servers to check arrServers = Array("terminator.movie.edu","fx.movie.edu") ' User and password that can modify the config on the DNS servers strUsername = "dnsadmin" strPassword = "dnspwd" ' This dictionary object will contain the key value pairs for all the settings ' that you want to check and configure on the DNS servers Set dicDNSConfig = CreateObject("Scripting.Dictionary") dicDNSConfig.Add "AllowUpdate", 1 dicDNSConfig.Add "LooseWildCarding", TRUE dicDNSConfig.Add "MaxCacheTTL", 900 dicDNSConfig.Add "MaxNegativeCacheTTL", 60 dicDNSConfig.Add "EventLogLevel", 0 dicDNSConfig.Add "StrictFileParsing", TRUE dicDNSConfig.Add "DisableAutoReverseZones", TRUE Dim arrDNSConfigKeys arrDNSConfigKeys = dicDNSConfig.keys Dim objLocator Set objLocator = CreateObject("WbemScripting.SWbemLocator") Dim x, y, boolRestart For x = LBound(arrServers) to UBound(arrServers) boolRestart = False WScript.echo arrServers(x) Dim objDNS, objDNSServer Set objDNS = objLocator.ConnectServer(arrServers(x), "root\MicrosoftDNS", _ strUserName, strPassword) set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""") for y = 0 To dicDNSConfig.Count - 1 Dim strKey strKey = arrDNSConfigKeys(y) WScript.Echo " Checking " & strKey if dicDNSConfig.Item(strKey) <> objDNSServer.Properties_.Item(strKey) then objDNSServer.Properties_.Item(strKey).value = dicDNSConfig(strKey) objDNSServer.Put_ boolRestart = TRUE if Err Then WScript.Echo " Error setting " & strKey & " : " & Err.Description Wscript.Quit else WScript.Echo " " & strKey & " updated" end if end if Next if boolRestart then objDNSServer.StopService if Err Then WScript.Echo "StopService failed: " & Err.Description Wscript.Quit end if objDNSServer.StartService if Err Then WScript.Echo "StartService failed: " & Err.Description Wscript.Quit end if WScript.Echo "Restarted" end if WScript.Echo "" next
Besides the use of the Dictionary object, most of the script is a combination of the other three examples shown so far in this chapter. We added a server array so that you can check multiple servers at once. For each server, the script simply checks each key in the Dictionary object to see if its value matches the key on the name server. If not, it modifies the server and commits the change via Put_. After it's done looping through all the settings, it restarts the DNS Server service if a change has been made to its configuration. It then proceeds to the next server.
One enhancement that would make the process even more automated would be to dynamically query the list of name servers instead of hard-coding them in an array. You would need to look up the NS records for one or more zones that your name servers are authoritative for. As long as an NS record is added for each new name server, the script would automatically discover new name servers on subsequent runs. Later in the chapter, we show how to query name servers with the DNS Provider.
If you've ever wanted a programmatic way to access the output of the dnscmd /statistics command, now you have one. The MicrosoftDNS_Statistic class provides complete access to all the performance metrics you can get using dnscmd or Performance Monitor. And it's easy too! Check out this script, which prints out all of the statistics:
strServer = "terminator.movie.edu " set objDNS = GetObject("winMgmts:\\" & strServer & "\root\MicrosoftDNS") set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""") set objStats = objDNS.ExecQuery("Select * from MicrosoftDNS_Statistic ") for each objStat in objStats WScript.Echo " " & objStat.Name & " : " & objStat.Value next
And if you want to access only a subset of the metrics (for example, all of the entries that start with "Records") you only need to modify the WQL query slightly:
set objStats = objDNS.ExecQuery("Select * from MicrosoftDNS_Statistic " & _ where Name like 'Records%' ")