Print Friendly
Отправить в сообщении

Смена ip адресов. Головная боль?

networkПредположим что у вас есть несколько задач имеющих под собою цель смены ip-адресов в некой абстрактной сети.

Что первое приходит в голову?

  • У нас есть новый DHCP (старый планируется на снос).
  • У нас есть новые DNS-серверы которые вы согласно плану уже развернули.
  • От Wins-ов мы старательно хотим избавиться, но они унаследованы и пока это не получается и мы обдумываем переход на GlobalNames.

Примечание: Естественно все это поднято в варианте Server Core на кластере Hyper-V, все это хозяйство уже бэкапится через DPM 2010 ну и т.д. и т.п…

Предположим что у вас есть список хостов, предположим что у вас даже есть схема сети и даже розетки пронумерованы и есть понимание что розетка номер 05-01-12 на кроссе уходит в кабинет такой то.

Если это так то вам несказанно повезло :)

Когда вы разобравшись в бумагах, понимаете что часть компьютеров имеют статические адреса, часть получают адреса динамически, что есть компьютеры в рабочей группе, а есть вообще непонятно что т.к. у них по хитрому умыслу разработчиков не прописано ни DNS-а ни шлюза. Одним словом зоопарк. Вы приходите в ужас от перспективы весело провести выходные и мысленно уже считаете сколько пива может понадобится что бы избавится от постэффектов :)

PowerShell в помощь. Да. Да. Именно его.

Для работы нам понадобится класс .NET - [System.Net.Dns]::GetHostAddresses() и немного терпения.

Разрешение имени в адрес происходит следующим образом.

[System.Net.DNS]::GetHostAddresses("yandex.ru")

Обратное преобразование выполняется так

[System.Net.DNS]::GetHostByAddress("77.88.21.3")

На практике это будет выглядеть примерно так.

$ServerName = "HOST_NAME"
[System.Net.Dns]::GetHostAddresses($ServerName)
# или обратное преобразование
$IP = "192.168.0.1"
[System.Net.Dns]::GetHostEntry($IP)

Но перебирать имена из имеющегося списка и адреса довольно скучно и очень хочется создать актуальный список адресов и использовать его для дальнейших исследований.

Список получен. Что дальше?

# берем данные из файла
$hosts = Get-Content servers.txt
# если файла нет то задаем список адресов
#hosts = "192.168.0.1","192.168.0.2","192.168.0.3"

# создадим пустой массив для результатов
$ResultList = @()

# в цикле разрешаем имена
foreach ($hostname in $hosts) {
$result = $null
$currentEAP = $ErrorActionPreference
$ErrorActionPreference = "silentlycontinue"

$result = [System.Net.Dns]::gethostentry($hostname)

$ErrorActionPreference = $currentEAP
If ($Result) {
$Resultlist += "$($Result.HostName) – $($Result.AddressList)"
} Else {
$Resultlist += "$IP – No HostNameFound"
}
}
# выводим результаты в файл
$resultlist | Out-File output.txt

Когда вы начинаете понимать что проще застрелиться чем понять что происходит вы натыкаетесь на мысть – «А не скачать ли мне nmap?»

Я же предлагаю не впадать в крайности и прибегнуть к помощи все того же PowerShell-а. Теперь проходим по диапазонам адресов.

$ErrorActionPreference = "SilentlyContinue"

# ЗАдаем диапазон для сканирования 1-254
1..254 | foreach -Process {
# создадим объект
$obj = New-Object PSObject;

$ping = get-WmiObject -Class Win32_PingStatus -Filter ("Address=’192.168.0." + $_ + "’");
$obj | Add-Member NoteProperty IPAddress($ping.Address);
$obj | Add-Member NoteProperty StatusCode($ping.StatusCode);

# если хост отвечает
if($ping.StatusCode -eq 0) {
$obj | Add-Member NoteProperty Status("Online");
$dns = [System.Net.Dns]::GetHostByAddress($ping.Address);

if($dns -ne $null) {
$obj | Add-Member NoteProperty ResolvedHostName($dns.HostName);
} else {
$obj | Add-Member NoteProperty ResolvedHostName("");
}
} else {
# если хост не отвесает то ставим ему статус offline
$obj | Add-Member NoteProperty ResolvedHostName("");
$obj | Add-Member NoteProperty Status("Offline");
}

# выводим результат на экран
Write-Output $obj
# или в файл
Add-content .\result.txt $obj;

# Чистим за собою
$dns = $null;
}

После найденных хостов которые используют статические адреса можно немного модифицировать код

$NICs = Get-WmiObject Win32_NetworkAdapterConfiguration | Where {$_.IPEnabled -eq "TRUE"}
foreach($NIC in $NICs) {
$NIC.EnableDHCP()
$NIC.SetDNSServerSearchOrder()
}

Вроде как все собрано, вроде как у нас есть понимание что мы хотим получить в итоге, но не хватает чего то для понимания полной картины…

Не гадайте. Я отвечу просто – не хватает списка настроек найденных хостов.

# задаем имя файла
$hostlist = "servers.txt"
# читаем из него список
$servers = Get-Content $hostlist
# вводим учетные данные под которыми будем получать настройки
$credential = Get-Credential

foreach ($server in $servers) {
$colItems = Get-WmiObject Win32_NetworkAdapterConfiguration -Namespace "root\CIMV2" -ComputerName $server -credential $credential -ErrorAction SilentlyContinue | where{$_.IPEnabled -eq "True"}
foreach($objItem in $colItems) {
$str = "$($server); $($objItem.DHCPEnabled); $($objItem.IPAddress); $($objItem.IPSubnet); $($objItem.DefaultIPGateway)"
Write-Host $str
Add-content .\result.txt $str
}
}

В этом скрипте стоит обратить внимание на $objItem.DHCPEnabled.

  • True – указывает на то что хост получает настройки с DHCP.
  • False – настройки прописаны руками.
В моем случае требовалось заменить адреса WINS-ов и DNS-а. Дописан проверку на True-False я добавил следующий код.
# задаем список DNS серверов
$DNSServers = "198.100.1.1″,"198.101.1.1″
$NIC.SetDNSServerSearchOrder($DNSServers)
# указываем шлюз по умолчанию
$NIC.SetGateways("192.168.0.1″)
# включаем регистрацию
$NIC.SetDynamicDNSRegistration("
TRUE")
# задаем новые WINS-ы
$NIC.SetWINSServer(“198.100.1.2″, "
198.101.1.2″)

Если требуется удалить все статические настройки то код меняется на следущий

$NIC.EnableDHCP()
$NIC.SetDNSServerSearchOrder()

Можно конечно помучится и прописать новую статику как показано ниже, но подумайте о том чтоит ли это делать…

$NIC.EnableStatic("192.168.1.42", "255.255.255.0")

В завершении, было бы неплохо перезагрузить тех кто не хочет это делать или ему просто необходима перезагрузка.

# список опций
# 0 – Log Off
# 4 – Forced Log Off
# 1 – Shutdown
# 5 – Forced Shutdown
# 2 – Reboot
# 6 – Forced Reboot
# 8 – Power Off
# 12 – Forced Power Off
#
# показываем только – 4, 5, 6 – force logoff of user, force shutdown, 6 force reboot
$computerName = read-host "Type the computername or ip address"
$command = read-host "Choose the following number:
4 – logoff user
5 – shutdown
6 – reboot"

(gwmi win32_OperatingSystem -ComputerName $computerName).Win32Shutdown($command)
Приглашаю присоединиться ко мне в следующих сервисах:
facebook Google Plus вКонтакте Twitter
Если Вам понравилась статья, то вы можете подписаться на RSS. А также бесплатно подписаться по E-mail и получать актуальную информацию в числе первых.
Получать обновления на email

Вы можете оставить комментарий.

Добавить комментарий

XHTML: Вы можете использовать тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>