PowerShell — Send-MagicPacket

Для того, чтобы разбудить компьютер по сети можно найти кучу разных скриптов на пошике. Почему я написал свой? Во-первых я не получал визуального удовлетворения от скрипта, а во-вторых я никак не мог понять почему я должен указывать мак-адрес в строго определенном формате, ведь формат отличается не только у разных вендоров, но и в разных оснастках винды.
Не нравится? Сделай сам!

Для начала добавим возможность конвейерной обработки и сделаем несколько алиасов, т.к. мак-адрес на выходе разных командлетов называется по-разному. Это будут «LinkLayerAddress»,»PhysicalAddress» и «ClientId».

[System.Net.IPAddress]::Broadcast — это 255.255.255.255

Дальше заменим все буквы от g до z и все не буквы и не цифры с помощью регулярки [g-z]|[^\w\d], это позволит нам вводить адрес в абсолютно любом формате.
В интернете можно увидеть такой способ создания массива байт

[Byte[]](,0xFF * 6)

Наверное кто-то когда-то написал и все копипастят.
Этот синтаксис допустим, но это не по повершелловски 🙂
В пошике для создания массива всегда используется @()

Применим это к данной ситуации:

@([byte][convert]::ToInt32('FF',16)) * 6

Ну или хотя бы так:

 @([Byte]0xFF) * 6

В результате получаем скрипт:

Function Send-MagicPacket {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][Alias("LinkLayerAddress","PhysicalAddress","ClientId")][string[]]$MacAddress,
[IPAddress]$Broadcast = [System.Net.IPAddress]::Broadcast,
[int32[]]$Ports = @(7..9)
)

	Process{
		foreach ($Mac in $MacAddress) {

			[string]$Mac = $Mac.ToUpper() -replace "[g-z]|[^\w\d]"
			if($Mac.Length -ne 12){Write-Error -Message 'Invalid PhysicalAddress format'; break}
			[string[]]$SplitMac = $Mac -split '([\w\d]{2})' -match '[\w\d]'
			[byte[]]$packet = @( [byte] [convert]::ToInt32('FF',16) ) * 6
			$packet += @( $SplitMac | % { [byte] [convert]::ToInt32($_,16)} ) * 16

			$UdpClient = New-Object System.Net.Sockets.UdpClient

			$Ports | % {
				$UdpClient.Connect($broadcast, $_)
				$UdpClient.Send($packet, $packet.Length) | out-null
			}

			$UdpClient.Close()

			[pscustomobject][ordered]@{
				'Mac' = $Mac
				'Port' = $Ports
			}
		}
	}
}

 

В PowerShell5 скрипт  Send-MagicPacket можно установить с помощью команды

Install-Script Send-MagicPacket -Force

Теперь мы можем например разбудить все хосты, имеющиеся в базе DHCP сервера

PS> Get-DhcpServerv4Lease -ComputerName DC01 -ScopeId 192.168.10.0 | Send-MagicPacket

Mac          Port
---          ----
00155D031609 {7, 8, 9}
D8CB8AC22385 {7, 8, 9}
00155D004200 {7, 8, 9}
90A2DA40E3BF {7, 8, 9}
F07950B496D4 {7, 8, 9}
F079506A3E5A {7, 8, 9}
80618FA91FE0 {7, 8, 9}
04C23E2E6D50 {7, 8, 9}
80C16E429722 {7, 8, 9}
1C659D3CB596 {7, 8, 9}


PS>

Или так:

PS> Send-MagicPacket F0:79:50:B4:96:D4,F0-79-50-6A-3E-5A,8061.8FA9.1FE0

Mac          Port
---          ----
F07950B496D4 {7, 8, 9}
F079506A3E5A {7, 8, 9}
80618FA91FE0 {7, 8, 9}


PS>
Реклама

PowerShell — Send-MagicPacket: 4 комментария

    • Благодарю за комент, но есть 2 момента:
      1. Навряд ли кто-нибудь додумается скормить в функцию мак с подчеркиваниями и, поскольку это PowerShell, скорее всего аргумент напишут вручную или передадут по конвейеру, таким образом удалять необходимо в основном точки, двоеточия и тире
      2. В моей функции это хотя бы есть, а у других требуется точное соответствие формату))

      Нравится

      Ответить

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

w

Connecting to %s