Wake On Lan Magic Packet script

There are a bunch of these to be found on the Web (see the additional notes on Origins below) although sadly some of them are either incorrect or of very dubious style.  Here’s my take on the theme in PowerShell (naturally:-)

I use this a lot – especially these days with spiralling electricity costs – to wake suspended machines and servers.

Wake on Lan uses a “Magic Packet” that consists of six bytes of 0xFF (the physical layer broadcast address), followed by 16 copies of the 6-byte (48-bit) MAC address (see http://en.wikipedia.org/wiki/Wake-on-LAN).   This packet is sent via UDP to the LAN Broadcast address (255.255.255.255) on arbitrary Port 4000 – although the layer 3 baggage is actually largely irrelevant.  Construction of this packet in PowerShell is a breeze thanks to the array semantics in the language (“$Packet = [Byte[]](,0xFF*6)+($Mac*16)” – neat).

This script has a table of saved MAC addresses to allow aliases to be specified on the command line (the real addresses have been obfuscated here) and uses a regex to validate the resulting MAC address string.  It would be possible to use DNS and the ARP Cache to resolve MAC addresses but the ARP cache will only be populated with a valid entry for any given target adapter for a relative short period of time after the last use of the address (10 minutes or less depending on usage); ARP cannot be used to dynamically resolve the address of a suspended adapter.

Here’s the script:

WakeOnLan.ps1
  1. # Send Wake-on-Lan Magic Packet to specified Mac address
  2. [CmdletBinding()]
  3. Param ($MacString=$(Throw 'Mac address is required'))
  4.  
  5. $Table=@{
  6.     Hyperion  ='00-00-00-00-00-44';
  7.     Nova      ='00-00-00-00-00-C8';
  8.     Desktop   ='00-00-00-00-00-1B';
  9.     Laptop    ='00-00-00-00-00-18';
  10.     Playroom  ='00-00-00-00-00-5C';
  11.     Betty     ='00-00-00-00-00-32';
  12.     gr8       ='00-00-00-00-00-D7'
  13. }
  14. If ($Table.ContainsKey($MacString)) {$MacString=$Table[$MacString]}
  15.  
  16. Write-Verbose "Using MAC string $MacString"
  17.  
  18. If ($MacString -NotMatch '^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$') {
  19.     Throw 'Mac address must be 6 hex bytes separated by : or -'
  20. }
  21.  
  22. # Split and convert to array of bytes
  23. $Mac=$MacString.Split('-:')|%{[Byte]"0x$_"}
  24.  
  25. # Packet is byte array; first six bytes are 0xFF, followed by 16 copies of the MAC address
  26. $Packet = [Byte[]](,0xFF*6)+($Mac*16)
  27. Write-Verbose "Broadcast packet: $([BitConverter]::ToString($Packet))"
  28.  
  29. $UdpClient=New-Object System.Net.Sockets.UdpClient
  30. $UdpClient.Connect(([System.Net.IPAddress]::Broadcast),4000)
  31. [Void]$UdpClient.Send($Packet,$Packet.Length)
  32. $UdpClient.Close()
  33. Write-Verbose "Wake-on-Lan Packet sent to $MacString"

 

Origins

I’ve been using this script for a long time and while writing this post I wondered where the idea had come from.  As is often the case it would appear that, at least for the correct entries (including those from the like of Brandon http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/51ef86e5-f3d4-459c-a08a-615c669aff2e and John Savill http://www.windowsitpro.com/article/networking/Q-How-can-I-easily-send-a-magic-packet-to-wake-a-machine-on-my-subnet-), MOW is involved(http://thepowershellguy.com/blogs/posh/archive/2007/04/01/powershell-wake-on-lan-script.aspx) – although in this particular case, his blog entry is not correct but the answer is provided in the blog comments by James Manning who used to have an MSDN blog and I imagine (used to?) work for Microsoft – although the blog hasn’t been updated since 2009.

Advertisements

6 thoughts on “Wake On Lan Magic Packet script”

  1. Great script.! The only problem i have is that the script is not taking over the values that i put in the Table section. So it only works when i execute the script with a MAC address value in Powershell

    Any idea why the Table function not working?

    Mac address is required
    At C:\WakeOnLan.ps1:line:3 char:30
    + Param ($MacString=$(Throw <<<< 'Mac address is required'))

    1. Hi, thanks! The idea of the table is to allow you to specify friendly aliases for MAC addresses you’ll use frequently – but you still have to specify either a MAC address or a name from the table on the command line (e.g. “PS C:\> WakeOnLan Server1”)

      The error message you show indicates that you haven’t specified any parameter. Do you want to have a single address (or a set of addresses) hard-coded in the table and use the same addresses all the time?

      Cheers,
      Chris

  2. Hi.. I appreciate this post, as a PS rookie this will help me manage my small home-business environment.. I must be doing something wrong, a simple cut and paste and changing the vales fo host names and mac address yields lot of systax erroros.. I have read this blog many times.. but I a m stumped..

    any help would be appreciated..

    1.# Send Wake-on-Lan Magic Packet to specified Mac address
    2.[CmdletBinding() ]
    3.Param ($MacString=$(Throw ‘Mac address is required’))
    4.
    5.$Table=@{
    6. Walkerspc =’xx-xx-xx-xx-xx-xx’;
    7. Calebspc =’xx-xx-xx-xx-xx-xx’
    13.}
    14.If ($Table.ContainsKey($MacString)) {$MacString=$Table[$MacString]}
    15.
    16.Write-Verbose “Using MAC string $MacString”
    17.
    18.If ($MacString -NotMatch ‘^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$’) {
    19. Throw ‘Mac address must be 6 hex bytes separated by : or -‘
    20.}
    21.
    22.# Split and convert to array of bytes
    23.$Mac=$MacString.Split(‘-:’)|%{[Byte]”0x$_”}
    24.
    25.# Packet is byte array; first six bytes are 0xFF, followed by 16 copies of the MAC address
    26.$Packet = [Byte[]](,0xFF*6)+($Mac*16)
    27.Write-Verbose “Broadcast packet: $([BitConverter]::ToString($Packet))”
    28.
    29.$UdpClient=New-Object System.Net.Sockets.UdpClient
    30.$UdpClient.Connect(([System.Net.IPAddress]::Broadcast),4000)
    31.[Void]$UdpClient.Send($Packet,$Packet.Length)
    32.$UdpClient.Close()
    33.Write-Verbose “Wake-on-Lan Packet sent to $MacString”

    1. Hi Tom, I can’t see anything obviously wrong with your changes. Try “wakeonlan walkerspc -verbose” to verify the MAC address you’re using. Otherwise, post the error message output and I’ll see if I can spot the problems. Regards, Chris.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s