27.2 Manipulating DNS Server Configuration

There are close to 50 different settings that can be configured on a Microsoft DNS server. They range from default scavenging and logging settings to settings that customize the DNS server behavior, such as how zone transfers will be sent to secondaries and whether to round-robin multiple A record responses.

The DNS provider is mapped to the root\MicrosoftDNS namespace. A DNS server is represented by an instance of a MicrosoftDNS_Server class, which is derived from the CIM_Service class. Table 27-1 contains all the property methods available in the MicrosoftDNS_Server class.

Table 27-1. MicrosoftDNS_Server class properties

Property name

Property description

AddressAnswerLimit

Max number of records to return for address requests (e.g., A records).

AllowUpdate

Determines whether DDNS updates are allowed.

AutoConfigFileZones

Indicates which standard primary zones that are authoritative for the name of the DNS server must be updated when the name server changes.

AutoCacheUpdate

Indicates whether the DNS server will dynamically attempt to update its root hints (also known as cache) file.

BindSecondaries

Determines the format zone transfers (AXFR) will be sent as to non-Microsoft DNS servers.

BootMethod

Determines where the server will read its zone information.

DefaultAgingState

For AD-integrated zones, the default scavenging interval in hours.

DefaultNoRefreshInterval

For AD-integrated zones, the default no-refresh interval in hours.

DefaultRefreshInterval

For AD-integrated zones, the default refresh interval in hours.

DisableAutoReverseZones

Determines whether the server automatically creates reverse zones.

DisjointsNets

Indicates whether the default port binding for a socket used to send queries to remote DNS servers can be overridden.

DsAvailable

Indicates whether Active Directory is available on the server.

DsPollingInterval

For AD-integrated zones, the interval in seconds to poll Active Directory for updates.

DsTombstoneInterval

For AD-integrated zones, the length of time in seconds that tombstoned records (i.e. deleted) should remain in Active Directory.

EdnsCacheTimeout

Length of time, in seconds, the cached EDNS version information is cached.

EnableDirectoryPartitionSupport

Flag indicating whether application partition support has been enabled.

EnableEDnsProbes

When TRUE, the DNS server always responds with OPT resource records according to RFC 2671, unless the remote server has indicated it does not support EDNS in a prior exchange. If FALSE, the DNS server responds to queries with OPTs only if OPTs are sent in the original query.

EnableDnsSec

Flag indicating whether DNSSEC resource records are returned if queried.

EventLogLevel

Determines the type of events (e.g., errors or warnings) that will be logged to the DNS Event Log.

Forwarders

List of IPs the server forwards queries to.

ForwardDelegations

Determines whether queries to delegated subzones are forwarded.

ForwardingTimeout

Time in seconds to wait for a response from a forwarded query.

IsSlave

Indicates whether the DNS server is a slave.

ListenAddresses

List of addresses the DNS server can receive queries on.

LocalNetPriority

If TRUE, records for IPs on the same net are given a higher priority.

LogFileMaxSize

Max size in bytes of the DNS server log.

LogFilePath

Filename and path to DNS server log.

LogIPFilterList

List of IPs used to filter entries written to the DNS server log.

LogLevel

Determines what events should be written to the system log.

LooseWildcarding

Indicates whether the server supports wildcarding (e.g., * MX records).

MaxCacheTTL

Max time in seconds to leave a recursive query in the local cache.

MaxNegativeCacheTTL

Max time in seconds to leave a recursive query that resulted in an error in the local cache.

Name

FQDN or IP of server.

NameCheckFlag

Indicates the set of eligible characters to be used in DNS names.

NoRecursion

Flag indicating whether the server will perform recursive lookups.

RecursionRetry

Time in seconds before retrying a recursive lookup.

RecursionTimeout

Time in seconds before the DNS server gives up recursive query.

RoundRobin

Flag indicating whether the server will round-robin addresses returned from a query that returns multiple A records.

RpcProtocol

Protocol to run administrative RPC over.

ScavengingInterval

Interval in hours between initiating scavenges.

SecureResponses

Indicates whether the DNS server exclusively saves records of names in the same subtree as the server that provided them.

SendPort

Port on which the DNS server sends UDP queries to other servers.

ServerAddresses

List of IP addresses for the server.

StrictFileParsing

Indicates whether the DNS server parses zone file strictly, which means if bad data is encountered, the zone will fail to load.

UpdateOptions

Flag that restricts the type of records that can be updated via DDNS.

Version

DNS server version

WriteAuthorityNS

Flag indicating whether the server includes NS and SOA records in the authority section on successful response.

XfrConnectTimeout

Number of seconds server waits for a successful TCP connection to a remote server when attempting a zone transfer.

The MicrosoftDNS_Server class also provides a few methods to initiate certain actions on the DNS server. Perhaps two of the most useful are StartService and StopService, which allow you to start and stop the DNS service. Table 27-2 contains the list of methods available to the MicrosoftDNS_Server class

Table 27-2. MicrosoftDNS_Server class 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.

27.2.1 Listing a DNS Server's Properties

The first step in programmatically managing your DNS server configuration is to see what settings you currently have and determine whether any need to be modified. With WMI, it is really easy to list all properties for the server. The following example shows how to do it:

Set objDNS = GetObject("winMgmts:root\MicrosoftDNS")
set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""")
   
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 only be 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 to print each element of the array. In that case, we use Lbound and Ubound to iterate over all the values for the array.

27.2.2 Configuring a DNS server

Now that we can see what values have been set on our DNS server, we may want to change some of them. To do so is very straightforward. We simply need to set the property method (e.g., EventLogLevel) to the correct value. This example shows how it can be done:

on error resume next
   
Set objDNS = GetObject("winMgmts:root\MicrosoftDNS")
set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""")
   
Wscript.Echo objDNSServer.Name & ":"
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 didn't, none of the changes would have been committed.

27.2.3 Restarting the DNS Service

After making changes to DNS settings, you typically will need to restart the DNS service for them to take effect. We can utilize the StopService and StartService methods as shown in the following example to do this:

on error resume next
   
Set objDNS = GetObject("winMgmts: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"

27.2.4 DNS Server Configuration Check Script

Building on the examples we've used so far in this chapter, we can now move forward with writing a robust DNS server configuration check script. A configuration check script can be very important, especially in large environments where you may have many DNS servers. Unless you have a script that routinely checks the configuration on all of your DNS servers, it is very likely that those servers will not have an identical configuration. If this is true, when problems pop up over time, you may end up spending considerably more time troubleshooting because of the discrepancies between the servers.

To accomplish the configuration checking, we will store each setting in a VBScript Dictionary object. For those coming from other languages such as Perl, a Dictionary object is the VBScript analog of a hash or associative array. It is not extremely flexible but works well in situations such as what we need. Another option would be to store the settings in a text file and read them into a Dictionary object when the script starts up. Example 27-1 contains the configuration check code.

Example 27-1. DNS Server configuration check script
option explicit
on error resume next
   
Dim arrServers
Dim strUsername, strPassword
Dim dicDNSConfig
   
` Array of DNS servers to check
arrServers = Array("dns1.mycorp.com","dns2.mycorp.com")
   
` 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. Then for each server, the script simply checks each key in the Dictionary object to see whether the value for it matches that on the DNS 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 service if a change has been made to its configuration. If a change has not been made, it proceeds to the next server.

One enhancement that would make the process even more automated would be to dynamically query the list of DNS servers instead of hardcoding them in an array. You simply would need to query the NS record for one or more zones that your DNS servers are authoritative for. As long as an NS record is added for each new name server, the script would automatically pick it up in subsequent runs. Later in the chapter, we will show how to query DNS with the DNS provider.



    Part II: Designing an Active Directory Infrastructure
    Part III: Scripting Active Directory with ADSI, ADO, and WMI