Wake-on-LAN и Powershell

У администраторов, часто бывают ситуации, когда надо включить компьютер, а физического доступа к нему нет. Например чтобы проводить в не рабочее время обновления системы или провести очередную проверку на наличие вирусов.

Сначала немного о Wake-on-LAN:

Wake-on-LAN — технология позволяющая включить компьютер, с помощью сетевой карты.
Для того, что бы это удалось сетевая карта данного компьютера должна получить «Magic packet».
На практике для этого компьютер должен удовлетворять следующим требованиям:
Блок питания должен соответствовать стандарту ATX 2.01
Материнская плата должна поддерживать Wake-on-LAN
Сетевая плата должна поддерживать Wake-on-LAN, если сетевая плата внешняя и не соответствует стандарту PCI 2.2 то необходим специальный трёхжильный кабель, для соединения разъёмов Wake-on-LAN на материнской плате и на сетевой карте.
Так же соответствующие настройки должны быть включены, как в биосе материнской платы, так и в драйверах сетевой карты.

На практике все современные компьютеры поддерживают эти технологии. Поэтому вопрос может возникнуть о включении Wake-on-LAN для этого рекомендую почитать инструкцию к материнской плате.

Так же следует учесть, что сетевая карта должна «слушать» сеть в ожидании «Magic packet». Для этого интерфейс ACPI не должен переходить в состояние G3, то есть в механическое выключение системы. Это может произойти при сбое питания компьютера.
Например:
Выключение компьютера из «розетки».
Аварийное выключение (зажатие кнопки питания на 10 секунд).
Выключение компьютера с блоком питания AT.

Что же такое Magic packet?

Это 6 байт забитых «0xFF» — называемые цепочкой синхронизации.
И дальше 96 байт, в которых mac адрес включаемого компьютера повторяется 16 раз.
Всё это можно упаковать в UDP или IPX пакет. Обычно используется UDP.

Следовательно, если компьютер с которого отсылается «Magic packet» и компьютер который мы хотим включить по Wake-on-LAN находится в одной подсети. То нам надо  знать mac адрес сетевой карты включаемого компьютера.
Если нам надо разбудить компьютер в другой подсети, то нам так же надо знать ip адрес который может переслать broadcast в подсеть с включаемым компьютером. В качестве такого ip может выступать ip самого включаемого компьютера, тогда UDP пакет уйдёт к нужному компьютеру. Однако у меня этот вариант не сработал из за частой очистки ARM таблицы на маршрутизаторах. Это выглядело так, что через некоторое время компьютер переставал включаться.

И так все технические моменты решены и нам надо сформировать «Magic packet».

Сформировать «Magic packet» можно следующим скриптом на Powershell:

Разберём данный скрипт:

Здесь мы в переменную заносим мак адрес включаемого компьютера. Разделителем указываем «-»

 

Указываем ip адрес который сможет доставить наш пакет до сетевого интерфейса нашего компьютера если компьютеры находятся в одной подсети, то это может быть ip адрес broadcast настроенный на сетевой карте текущего компьютера ([System.Net.IPAddress]::Broadcast). Если же компьютеры находятся в разных подсетях, то указываем либо ip адрес компьютера который надо включить, либо ip адрес через который можно переслать broadcast в другую подсеть.

 

Указываем порт(группу портов) по которому будет пересылаться пакет, в нашем варианте пакеты будут отсылаться через порт 0, порт 7 и порт 9.

 

Создаём цепочку синхронизации «Magic packet»

 

Преобразовываем mac адрес в тип [byte], если вы хотите изменить разделитель в mac адресе, например на ‘:’, то следует изменить ‘-‘ на ‘:’ то есть данная строчка будет выглядеть следующим образом:

 

Формируем пакет данных, где в начале идёт цепочка синхронизации, а потом 16 раз повторяется мак адрес.

 

Запускаем конструктор класса UdpClient

 

Для каждого из портов, устанавливаем соединение с ip $BroadcastProxy и портом $port, дале отправляем данные из $packet количеством байт $packet.Length. Сообщение с результатом функции .Send не показываются (отсылаются в Out-Null).

 

Закрываем соединение.

Комментарии:

Комментарии 4

  • Спасибо, работает.

  • Если же компьютеры находятся в разных подсетях, то указываем либо ip адрес компьютера который надо включить, либо ip адрес через который можно переслать broadcast в другую подсеть.

    Каким образом прописывать конкретный ip? Просто присвоить переменной значение ip-адреса? Пытался, не помогает

  • Добрый день. А как добавить несколько mac адресов, чтобы включить сразу несколько ПК?

    • Можно завернуть в функцию. Но к сожалению под рукой нет винды писал в блокноте:
      function Up-Computer {param (    [Parameter(Mandatory,ValueFromPipeline)]$Mac='01-2C-34-4C-1C-12'    $BroadcastProxy=[System.Net.IPAddress]::Broadcast    $Ports = 0,7,9    )     $synchronization = [byte[]](,0xFF * 6)    $bmac = $Mac -Split '-' | ForEach-Object { [byte]('0x' + $_) }    $packet = $synchronization + $bmac * 16     $UdpClient = New-Object System.Net.Sockets.UdpClient     ForEach ($port in $Ports) {$UdpClient.Connect($BroadcastProxy, $port)        $UdpClient.Send($packet, $packet.Length) | Out-Null}    $UdpClient.Close()}@('01-2C-34-4C-1C-12','01-2C-34-4C-1C-12','01-2C-34-4C-1C-12')|Up-Computer
      что то типо того.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *