Modifying DNS settings with a batch file

I have this batch file that checks to see if a Windows device is at work or off-site.  If at work, it uses our internal DNS, and if off-site, it uses a public DNS.  The only problem is, I'm using a ping to determine if the devices is on-site or off-site, which takes a few seconds to fail.  This would work okay if it did not have to go thru multiple NICs (3 on my devices - Bluetooth, Ethernet NIC and wireless NIC).

This batch file is set off every time a network change event happens (connection to wifi for example).  Is there a way that I could do this faster?  I'm thinking maybe I can first check if the NIC has an IP (or someway to know the nic is active), and if so, then next test if it's on-site, and finally change the DNS appropriately.  

I'm thinking the ping test is the safest way to determine if on-site or off-site because we have wireless IP addresses that are 10.x.x.x and I know some hotels and businesses use that range.  Here is currently what I have:
REM If INTERNAL_IP_Check IP is available, it will set network cards to use local DNS. 
REM If INTERNAL_IP_Check IP is unreachable, it will set to public DNS
set INTERNAL_IP_Check="172.16.10.1"

REM --- set DNS Servers 
set DNS_SERVER1="8.8.8.8"
set DNS_SERVER2="8.8.4.4"
set DNS_SERVER_ALT="172.16.10.34"

for /f "skip=2 tokens=3*" %%i in ('netsh interface show interface') do ( 
ping -n 3 %INTERNAL_IP_Check% | find "TTL=" >nul
if errorlevel 1 (
netsh interface ip add dns "%%j" %DNS_SERVER1% validate=no
netsh interface ip add dns "%%j" %DNS_SERVER2%  validate=no  
) else (
netsh interface ip add dns "%%j" %DNS_SERVER_ALT% validate=no
)
)
ipconfig /flushdns >nul 2>&1

Open in new window

BrianAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Performing the ping for each interface is unnecessary - a single run is sufficient.
REM If INTERNAL_IP_Check IP is available, it will set network cards to use local DNS. 
REM If INTERNAL_IP_Check IP is unreachable, it will set to public DNS
set INTERNAL_IP_Check="172.16.10.1"

REM --- set DNS Servers 
set DNS_SERVER1="8.8.8.8"
set DNS_SERVER2="8.8.4.4"
set DNS_SERVER_ALT="172.16.10.34"

set ispublic=
ping -n 3 %INTERNAL_IP_Check% | find "TTL=" >nul || set ispublic=y

for /f "skip=2 tokens=3*" %%i in ('netsh interface show interface') do ( 
  if defined ispublic  (
    netsh interface ip add dns "%%j" %DNS_SERVER1% validate=no
    netsh interface ip add dns "%%j" %DNS_SERVER2%  validate=no  
  ) else (
    netsh interface ip add dns "%%j" %DNS_SERVER_ALT% validate=no
  )
)
ipconfig /flushdns >nul 2>&1

Open in new window

You could add some reliability by using a single ping, then check arp -a results for a specific MAC address to identify the answer comes from the expected device.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BrianAuthor Commented:
Qlemo, this is great!  The batch file runs much faster now.  The only issue I have is that it changes the DNS servers on NICs that are not active.  I tried adding these lines...

set hasIP=
netsh interface ip show address "%%j" | findstr "IP Address" >nul || set hasIP=y
  if defined hasIP (

But it does not seem to work.  Maybe because the "netsh interface ip show address" command returns multiple lines?  I also tried "find" instead of "findstr", but neither work.  Here is the code I have:
REM If INTERNAL_IP_Check IP is available, it will set network cards to use local DNS. 
REM If INTERNAL_IP_Check IP is unreachable, it will set to public DNS
set INTERNAL_IP_Check="172.16.10.1"

REM --- set DNS Servers 
set DNS_SERVER1="8.8.8.8"
set DNS_SERVER2="8.8.4.4"
set DNS_SERVER_LOCAL="172.16.10.34"

set isoffsite=
ping -n 2 %INTERNAL_IP_Check% | find "TTL=" >nul || set isoffsite=y

for /f "skip=2 tokens=3*" %%i in ('netsh interface show interface') do ( 
set hasIP=
netsh interface ip show address "%%j" | findstr "IP Address" >nul || set hasIP=y
  if defined hasIP (
		if defined isoffsite  (
			netsh interface ip add dns "%%j" %DNS_SERVER1% validate=no
			netsh interface ip add dns "%%j" %DNS_SERVER2%  validate=no  
		) else (
			::netsh int ip set dns "%%j" dhcp >nul 2>&1
			netsh interface ip add dns "%%j" %DNS_SERVER_LOCAL% validate=no
		)
	)
)
ipconfig /flushdns >nul 2>&1

Open in new window

0
BrianAuthor Commented:
I think maybe I have it.  I should have used "&&" (meaning successful) instead of "||" (for unsuccessful).
0
BrianAuthor Commented:
Qlemo, thank you so much for your help! I'm also going to replace the ping with arp -a as you suggested.  I think the gateway for each vlan will be the mac address of our core switch, so arp -a will work well.  Using arp -a will be fast, and as you have stated, more reliable.  Thank you for your help... you are brilliant!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Batch

From novice to tech pro — start learning today.