Skip to content

Instantly share code, notes, and snippets.

@JohnLBevan
Created December 21, 2017 18:27
Show Gist options
  • Select an option

  • Save JohnLBevan/28d7cd8b7ae764b851e35e8d0c3f3f89 to your computer and use it in GitHub Desktop.

Select an option

Save JohnLBevan/28d7cd8b7ae764b851e35e8d0c3f3f89 to your computer and use it in GitHub Desktop.
Initiate a wake on lan for a machine (or multiple machines).
function Start-Computer { #broadcasts a magic packet hoping to invoke the target machine's wake on lan function. NB: uses target computer's mac address rather than name / requires WOL to be enabled, and the device's network card to be listenning to broadcasts on the local subnet
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[ValidateScript({$_ -match '^(?:[^a-fA-F0-9]*[a-fA-F0-9][^a-fA-F0-9]*){12}$'})] #i.e. 12 hex digits (6 pairs) optionaly separated by any non-hex character/string. NB: this does mean 01:01 cannot be written as 1:1, for example.
[string]$MacAddress
,
[Parameter()]
[ValidateSet('IPv4','IPv6')]
[string]$IPVersion = 'IPv4'
,
[Parameter()]
[int]$WolPort = 9 #some people use port 7, but that would cause lots of back chat if the echo service is enabled. https://en.wikipedia.org/wiki/Discard_Protocol
)
Begin {
[int]$MacRepitions = 16
[string]$MatchRegex = '^(?:[^a-fA-F0-9]*([a-fA-F0-9])[^a-fA-F0-9]*([a-fA-F0-9])[^a-fA-F0-9]*){6}$'
[Byte[]]$MagicPacketStart = [Byte[]](0xFF) * 6 #The magic packet is a broadcast frame containing anywhere within its payload 6 bytes of all 255 (FF FF FF FF FF FF in hexadecimal), followed by sixteen repetitions of the target computer's 48-bit MAC address, for a total of 102 bytes. https://en.wikipedia.org/wiki/Wake-on-LAN
[System.Net.Sockets.AddressFamily]$addressFamily = [System.Net.Sockets.AddressFamily]::InterNetwork
[System.Net.IPAddress]$broadcastAddress = [System.Net.IPAddress]::Broadcast
switch ($IPVersion) {
'IPv4' {
if (![System.Net.Sockets.Socket]::OSSupportsIPv4) {
throw [System.NotSupportedException]::new('This system does not support IPv4')
}
break;
}
'IPv6' {
if ([System.Net.Sockets.Socket]::OSSupportsIPv6) {
$addressFamily = [System.Net.Sockets.AddressFamily]::InterNetworkV6
$broadcastAddress = [System.Net.IPAddress]::Parse('FF02::2') # http://ipv6friday.org/blog/2011/12/ipv6-multicast/ i.e. all routers -> Long form: FF02:0:0:0:0:0:0:2
} else {
throw [System.NotSupportedException]::new('This system does not support IPv6')
}
break;
}
}
[System.Net.Sockets.UdpClient]$client = [System.Net.Sockets.UdpClient]::new($addressFamily)
$client.EnableBroadcast = $true
$client.Connect($broadcastAddress, $WolPort) #i.e. connect/broadcast to all machines on given (by default discard protocol/machine management) port
}
Process {
$matched = [Regex]::Matches($MacAddress, $MatchRegex)
[Byte[]]$macAddressInBytes = (0..5 | ForEach-Object {'0x{0}{1}' -f $matched.Groups[1].Captures[$_].Value,$matched.Groups[2].Captures[$_].Value}) #will always exceed since we validated above
[Byte[]]$magicPacket = $MagicPacketStart + ($macAddressInBytes * $MacRepitions)
$client.Send($magicPacket, $magicPacket.Length) | Out-Null #consider $client.SendAsync for better performance if sending many packets
}
End {
$client.Dispose()
}
}
#Example Usage:
#Start-Computer -MacAddress '12:34:56:78:90:AB'
#
# To get the current computer's mac address using PowerShell, use: (Get-WmiObject win32_networkadapterconfiguration | select description, macaddress; Get-CimInstance win32_networkadapterconfiguration | select description, macaddress ) | sort -unique
#
#todo: wrap in module
#todo: create help text
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment