Смена ip адресов. Головная боль?
Предположим что у вас есть несколько задач имеющих под собою цель смены 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($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-а. Теперь проходим по диапазонам адресов.
# ЗАдаем диапазон для сканирования 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;
}
После найденных хостов которые используют статические адреса можно немного модифицировать код
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 – настройки прописаны руками.
$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.SetDNSServerSearchOrder()
Можно конечно помучится и прописать новую статику как показано ниже, но подумайте о том чтоит ли это делать…
В завершении, было бы неплохо перезагрузить тех кто не хочет это делать или ему просто необходима перезагрузка.
# 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)
Похожие статьи
Вы можете оставить комментарий.

