So you had this Windows Domain Controller also running DNS on the network for years and years. Uninstalling the Domain Controller role is not a problem since computers will start using another DC on the network. But what about the DNS role? You might have a bunch of servers and clients using it, but how do you know? Many clients run DHCP but all those devices configured with a static IP configuration like servers, clients, printers, switches, routers and other network devices.

Ok, you could just switch it off and wait for hell to break loose… But here are a few ways to do it more professionally.

Is there a firewall?

Sometimes you have a firewall in front of the datacenter and I suspect it can log successful traffic. If you can get hold of this logfile you can easily check which hosts that access the DNS-server on UDP/TCP port 53.

Turn on DNS debugging

The Windows DNS server Properties has a Debugging tab where you can log all traffic to it. Just selecting Incoming and Queries/Transfers help to minimize what is logged.

Then you can use nslookup manually against the server and do a lookup and make sure it’s logged. My experience is that it will take some time (up to a few minutes…) before the actual query is logged in the logfile so be patience. The file gets humongous so I suggest some neat Notepad++ macros, grep and Excel 2010 (I tend to like Data -> Filter -> Advanced -> Unique records only) to filter out what’s important.

VBScript to check remote host DNS settings

Sure, most of the hard-to-find hosts that use the DNS are probably not computers in your Active Directory, but maybe this script is useful to check a computer remotely? If you supply a remote computer name as an argument it will give you the settings of that server. If you don’t supply an argument, it will get the local host config.

If WScript.Arguments.Count < 1 Then
 strComputer = "."
Else
 strComputer = Wscript.Arguments(0)
End If

Set objWMIService = GetObject("winmgmts:" _
 & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colAdapters = objWMIService.ExecQuery _
 ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

n = 1
WScript.Echo

For Each objAdapter in colAdapters
 WScript.Echo "Host name  : " & objAdapter.DNSHostName
 WScript.Echo "Description: " & objAdapter.Description

 If Not IsNull(objAdapter.IPAddress) Then
 For i = 0 To UBound(objAdapter.IPAddress)
 WScript.Echo "IP address : " & objAdapter.IPAddress(i)
 Next
 End If

 If Not IsNull(objAdapter.DNSServerSearchOrder) Then
 For i = 0 To UBound(objAdapter.DNSServerSearchOrder)
 WScript.Echo "DNS        : " & objAdapter.DNSServerSearchOrder(i)
 Next
 End If

 n = n + 1

Next

Now manually getting this from each server is not very effective. Sure you could run the script like this:

cscript GetDNS-settings.vbs COMPUTER1
cscript GetDNS-settings.vbs COMPUTER2
cscript GetDNS-settings.vbs COMPUTER3
etc

but wouldn’t it better that you get a textfile with all the computernames and run this script against this list? Sure, no problem! It will take the first the filename in the first argument and scan all those servers.

INPUT_FILE_NAME = Wscript.Arguments(0)
Const FOR_READING = 1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(INPUT_FILE_NAME, FOR_READING)

Do Until objFile.AtEndOfStream
   strComputer = objFile.ReadLine
   Set objWMIService = GetObject("winmgmts:" _
       & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

   Set colAdapters = objWMIService.ExecQuery _
       ("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")

   n = 1
   WScript.Echo

   For Each objAdapter in colAdapters
      WScript.Echo "Host name  : " & objAdapter.DNSHostName
      WScript.Echo "Description: " & objAdapter.Description

      If Not IsNull(objAdapter.IPAddress) Then
         For i = 0 To UBound(objAdapter.IPAddress)
            WScript.Echo "IP address : " & objAdapter.IPAddress(i)
         Next
      End If

      If Not IsNull(objAdapter.DNSServerSearchOrder) Then
         For i = 0 To UBound(objAdapter.DNSServerSearchOrder)
            WScript.Echo "DNS        : " & objAdapter.DNSServerSearchOrder(i)
         Next
      End If

      n = n + 1

   Next
Loop

Either create this textfile manually or build another script that gets all computernames from Active Directory:

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"

Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = _
    "Select Name, Location from 'LDAP://DC=lab,DC=com' " _
        & "Where objectClass='computer'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst

Do Until objRecordSet.EOF
    Wscript.Echo objRecordSet.Fields("Name").Value
    objRecordSet.MoveNext
Loop

Or you could get all computers in an OU:

Set OU = GetObject("LDAP://OU=Computers,OU=Site,DC=lab,DC=com")
For Each oComputers In OU
If oComputers.Class = "computer" Then
	Wscript.echo oComputers.cn
End If
Next
Wscript.Quit

If you have any other ideas how to find these misconfigured hosts – please comment.