Get-DhcpClients

Перейдем от простых вещей, к настоящим ужасам🙂

Захотелось мне получить список сопоставлений IP и MAC адресов от DHCP сервера, причем не просто чтобы посмотреть, а чтобы дальше использовать в скриптах (например для добавления резервирований). Но текстовый вывод netsh не слишком то хорош для использования скриптами, а других способов я не нашел, так что я решил создавать объекты распарсив вывод netsh. Получилось вот такое🙂

ConsoleHorror

Такие ужасы я иногда создаю в самой консоли😉 Точнее начинается всё просто — сначала я просто выполняю команду netsh, затем пробую разобрать вывод с помощью регулярного выражения, затем создаю объекты с интересными мне свойствами, которые уже и идут на выход🙂

Хоть и выглядит это ужасно — тем не менее такие oneliner’ы очень удобны для интерактивного написания. Ну а затем можно добавить переносов строк и комментариев, и получится скрипт который вполне можно попробовать понять🙂

Function Get-DhcpClients (
$Server = "MyDhcpServer", # Сетевое имя DHCP сервера
$Scope = "192.168.1.0" # IP-адрес идентифицирующий Scope
)
{
    # Регулярное выражение для разбора вывода netsh
    $Pattern = "^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).+ ((?:..-){5}..).+-(\d\d\.\d\d\.\d{4} \d\d:\d\d:\d\d)"
    # Некоторые пояснения к выражению:
    #    ^        - Начало строки
    #    \d        - 1 цифра
    #    \d{1,3}    - от 1 до 3х цифр
    #    .        - 1 любой символ
    #    \.        - точка, просто точка.
    #    .+        - 1 или более любых символов
    #    (?:..-){5}    - последовательность из двух любых символов и тире, повторенная 5 раз.
    #    Все групы попадающие в круглые скобки помещаются в массив $Matches под индексами 1,2 и тд.
    
    # Маска для разбора даты и времени
    $LeasePattern = "dd.MM.yyyy HH:mm:ss"
    
    # Получаем список зарегистрированных клиентов от netsh
    netsh dhcp server \\$Server scope $Scope show clients |
    # Выбираем строки подпадающие под выражение (при этом помещая компоненты в $matches)
    where {$_ -match $Pattern} | 
    # С помощью командлета Select-Object и хэш-таблиц указываем пары Name и Expression для 
    # вычисления свойств объектов которые пойдут на выход
    select @{Name = "IP"; Expression = {$matches[1]}},
            @{N = "MAC"; E = {$matches[2]}},
            # Время окончания аренды разбираем с помощью функции .NET - ParseExact
            @{n="Lease"; e={[datetime]::parseexact($matches[3],$LeasePattern,$null)}}, 
            # DNS имя компьютера определяем утилитой nslookup.exe
            @{n="Name"; e={(nslookup.exe $matches[1])[3] -replace "^.+:\s+"}}    
}

Используя эту функцию необходимо указывать имя dhcp-сервера, и ip-адрес scope. Вот например отбор всех клиентов у которых dns имя начинаяется с srv:

$Clients = Get-DhcpClients -Server "MyDhcpServer" -Scope 192.168.1.0
$Clients | Where {$_.name -like "srv*"}

Или можно отобрать клиентов у которых аренда истекает в течении недели и вывести для них только dns имя и срок аренды:

$clients | where {$_.Lease -lt (get-date).adddays(7)} | format-table name, lease

комментария 4 to “Get-DhcpClients”

  1. Илья (sie) Says:

    Отличный пример!!!

    Из моего опыта: когда для целого домена делал преобразование ip в имя, то в случае отсутствия имени в DNS получалась пауза (таймаут) и VBS-скрипт работал из-за этого очень долго; пришлось превратить VBS-скрипт в многопоточный!!! А вот как избавится от последовательного nslookup.exe в этом примере мыслей нет😦

  2. Xaegr Says:

    Ну nslookup возвращает ошибку мгновенно, и соответственно получается просто пустое поле, без всяких задержек. Сейчас вспомнил про более правильный метод:
    [system.net.dns]::Resolve(«192.168.10.10»).HostName
    но он не позволяет задать таймаут. Правда на крайний случай, там же есть функции для распаралеливания запросов, но IMHO в данном случае это черезчур усложнит скрипт без надобности.

  3. Camelot Says:

    маньяк, что ещё сказать.🙂

  4. ParseExact « Zorion’s Weblog Says:

    […] Windows — zorion @ 3:36 пп Прочитал у Василия Гусева статью get-dhcpclients и очень мне захотелось самому распарсить какой-нибудь […]


Обсуждение закрыто.

%d такие блоггеры, как: