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.