Смена DNS серверов через пакетный файл

28-12-2012 @ 21:08

На работе сегодня пришлось помогать админам удаленных офисов. Не знаю почему наши «серверасты» отказались выполнить смену DNS серверов путем настроек политик безопасности, ибо машины все в домене, но факт остался фактом: они решили обойтись «меньшей кровью» — сделали рассылку в которой говорилось, что, мол, «ребята, вбиваем 4 новых сервера ручками». Подозреваю, что «серверасты» элементарно не знали про возможности domain logon и bat в сочетании друг с другом. Ну да Бог с ними.
Разумеется ходить по рабочим местам, рестартить машину под админом, ручками вбивать всё это дело, снова рестартить под пользователем… Долго. Особенно, когда сроки сжаты, а рабочих мест много.
В итоге, я решил прибегнуть, в очередной раз, к bat-никам. Для смены DNS серверов даже оказалась приятная утилита, входящая в состав Windows с версии NT. Network shell или же netsh. Далее будет описание использования этой утилиты, а также проблемы, с которыми я столкнулся их решения.


Для использования netsh необходимо как минимум знать имя подключения по локальной сети.
То есть batch-код должен был быть таким:

netsh interface ip set dns name=”НАЗВАНИЕ ПОДКЛЮЧЕНИЯ ПО ЛОКАЛЬНОЙ СЕТИ 13” static 172.168.23.10 primary

В данном коде утилита netsh ставит первичный (primary) DNS сервер равным 172.168.23.10.

Первая проблема с которой я столкнулся — разные названия подключений. Где-то есть «Подключение по локальной сети», а где-то с добавлением цифр в конце. Было и вовсе «рандомное» название, типа «Рабочая сеть». Хотелось сделать нечто универсальное, без лишнего ввода дополнительной информации. Сначала я, конечно, рассказал, что в конечный батник необходимо ввести это название, дабы все сработало. Но пришлось вводить его аж 4 раза.
Вторая проблема появилась когда была выполнена попытка запуска не из под админа. Скрипт не сработал.
Тогда я прибегнул к решению runas:

runas /profile /user:domain\username “c:\changedns.bat”

Выяснилось, что русские названия в конечном changedns.bat не воспринимались. Смена кодировки тоже результатов не дала.

Тогда я просто решил выделить название сетевого подключения в переменную и автоматом ее подставлять. Код для этого вышел следующий:

for /f "tokens=2 delims==" %%a in ('wmic path Win32_networkadapter where 
^"NetConnectionStatus^=2^" get NetConnectionID /value') do set lanname=%%a

Что этот код делает: если подключение по локальной сети называется «Подключение по локальной сети 4»,
то значение переменной %lanname% будет равно этому названию. Всё вроде просто.

Ну а дальше создал changedns.bat с таким листингом:

for /f "tokens=2 delims==" %%a in ('wmic path Win32_networkadapter where 
^"NetConnectionStatus^=2^" get NetConnectionID /value') do set lanname=%%a
 
netsh interface ip set dns name="%lanname%" static 172.168.23.10 primary
netsh interface ip add dns name="%lanname%" 172.168.23.11 2
netsh interface ip add dns name="%lanname%" 172.168.23.12 3
netsh interface ip add dns name="%lanname%" 172.168.23.13 4

В последних строчках этого кода netsh добавляет вторичный, троичный (?) и т.д. dns сервера.

Админам же, чтобы запустить его и автоматом сменить DNS, необходимо было выполнить следующее:

runas /profile /user:domain\username “c:\changedns.bat”

Согласитесь, гораздо быстрее запустить runas и ввести пароль, затем дождаться завершение выполнения пакетного файла, нежели чем вбивать всё это дело руками.
Если у Вас есть вопросы по написанному тексту — задавайте. Постараюсь объяснить. 🙂