Wake On LAN

by Jun 17, 2020

There is no need for external “Wake On LAN” tools. If you want to wake up a network machine, simply tell PowerShell the MAC address of the target machine. Here is a function that composes the magic packet and wakes the machine(s):

function Invoke-WakeOnLan
{
  param
  (
    # one or more MAC addresses
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    # MAC address must be a following this regex pattern
    [ValidatePattern('^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$')]
    [string[]]
    $MacAddress 
  )
 
  begin
  {
    # instantiate a UDP client
    $UDPclient = [System.Net.Sockets.UdpClient]::new()
  }
  process
  {
    foreach ($_ in $MacAddress)
    {
      try {
        $currentMacAddress = $_
        
        # get byte array from MAC address
        $mac = $currentMacAddress -split '[:-]' |
          # convert the hex number into byte
          ForEach-Object {
            [System.Convert]::ToByte($_, 16)
          }
 
        #region compose the "magic packet"
        
        # create a byte array with 102 bytes initialized to 255 each
        $packet = [byte[]](,0xFF * 102)
        
        # leave the first 6 bytes untouched, and
        # repeat the target MAC address bytes in bytes 7 through 102
        6..101 | ForEach-Object { 
          # $_ is indexing in the byte array,
          # $_ % 6 produces repeating indices between 0 and 5
          # (modulo operator)
          $packet[$_] = $mac[($_ % 6)]
        }
        
        #endregion
        
        # connect to port 400 on broadcast address
        $UDPclient.Connect(([System.Net.IPAddress]::Broadcast),4000)
        
        # send the magic packet to the broadcast address
        $null = $UDPclient.Send($packet, $packet.Length)
        Write-Verbose "Sent magic packet to $currentMacAddress..."
      }
      catch 
      {
        Write-Warning "Unable to send ${mac}: $_"
      }
    }
  }
  end
  {
    # release the UDP client and free its memory
    $UDPclient.Close()
    $UDPclient.Dispose()
  }
}

Once you ran the function, this is how you can wake up machines:

 
Invoke-WakeOnLan -MacAddress '24:EE:9A:54:1B:E5', '98:E7:43:B5:B2:2F' -Verbose 
 

To find out the MAC address of a target machine, run this line on the target machine or via remoting:

 
Get-CimInstance -Query 'Select * From Win32_NetworkAdapter Where NetConnectionStatus=2' | Select-Object -Property Name, Manufacturer, MacAddress 
 

More information can be found here: https://powershell.one/code/11.html.


Twitter This Tip! ReTweet this Tip!