WakeUp-Machines – A PowerShell script for Wake On LAN


 

These days, I give a lot of presentations and demos on Windows Server 2012. Of course, many involve Hyper-V related demos. Although I run most demos from PowerShell, since now I can, I modify a lot in my demo environment. And since I frequently use my environment I need to be able to prepare my start my environment, prepare it, run the demos, revert to the state it was in when I started and finally shut down my environment.

At least the start, preparation (including tests), reverting and shutting down are all done using PowerShell scripts. Sometimes I have only 15 minutes to connect my machines to power and network. In that time, I don’t have time to manually start everything and use a document to follow what needs to be done. And what about some basic tests to verify everything is working correctly?

Think about it: starting the machines, waiting until they are alive, connecting through RDP to some of them and some virtual machines, starting VMconnect sessions, starting Hyper-V Manager, Server Manager, PowerShell console, configuring networks, etc, etc. Quite easy to forget some steps and hit issues during demos.

I normally don’t connect my presentation machine to the external monitor (large screen, beamer, etc.) until the environment is ready. But to show the power of automation, I did show a technical audience once how I start my environment (up to the point when it is ready). People were obviously impressed with the amount of automation I used.

Last month I presented at a large Microsoft event and got some questions from colleagues as well on how I started my machines without touching them. The script used Wake On LAN, something most machines support these days and which is on most of them on by default. I simply connect my machines to my switch and turn them on from my presentation machine.

In this post, I share my script for others to use. The script follows some PowerShell best practices:

· The name of the script is in the Verb-Noun form.

· The script is documented with comment based help.

The only thing you need to get it to work is the Wake On LAN tool. Other than that, you should be able to use it right away, once you have created the CSV file with machine names.

So how does it work?

The script uses a CSV file with machines you want to wake up. It starts with the first and works its way down the list. Not only does it wake the machines, it also sends echo requests to verify IP connectivity. It continues to send requests (number configurable) and then goes on to the next machine with wake up. I have developed a progress bar which displays progress on the wake up, the echo request and remaining phase of sending/receiving echo requests/replies.

    

WakeUp-Machines
  1. #######################################################
  2. ##
  3. ## WakeUp-Machines.ps1, v1.0, 2012
  4. ##
  5. ## Created by Matthijs ten Seldam, Microsoft
  6. ##
  7. #######################################################
  8.  
  9. <#
  10. .SYNOPSIS
  11. Starts a list of physical machines by using Wake On LAN.
  12.  
  13. .DESCRIPTION
  14. WakeUp-Machines starts a list of servers using a Wake On LAN tool. It then sends echo requests to verify that the machine has TCP/IP connectivity. It waits for a specified amount of echo replies before starting the next machine in the list.
  15.  
  16. .PARAMETER Machines
  17. The name of the file containing the machines to wake.
  18.  
  19. .PARAMETER Interface
  20. The IP address of the interface to use to wake up the machines.
  21.  
  22. .PARAMETER Subnet
  23. The subnet mask of the interface to use to wake up the machines.
  24.  
  25. .EXAMPLE
  26. WakeUp-Machines machines.csv 192.168.0.1 255.255.255.0
  27.  
  28. .EXAMPLE
  29. WakeUp-Machines c:\tools\machines.csv 192.168.0.1 255.255.255.0
  30.  
  31. .INPUTS
  32. None
  33.  
  34. .OUTPUTS
  35. None
  36.  
  37. .NOTES
  38. Make sure the Wake On LAN command line tool is available in the same location as the script!
  39.  
  40. The CSV file with machines must be outlined using Name, MAC Address and IP Address with the first line being Name,MacAddress,IpAddress.
  41. See below for an example of a properly formatted CSV file.
  42.  
  43. Name,MacAddress,IpAddress
  44. Host1,A0DEF169BE02,192.168.0.11
  45. Host3,AC1708486CA2,192.168.0.12
  46. Host2,FDDEF15D5401,192.168.0.13
  47.  
  48. .LINK
  49. http://blogs.technet.com/matthts
  50. #>
  51.  
  52.  
  53. param(
  54.     [Parameter(Mandatory=$true, HelpMessage="Provide the path to the CSV file containing the machines to wake.")]
  55.     [string] $Machines,
  56.     [Parameter(Mandatory=$true, HelpMessage="Provide the IP address of the interface to use for Wake On LAN.")]
  57.     [string] $Interface,
  58.     [Parameter(Mandatory=$true, HelpMessage="Provide the subnet mask of the interface to use for Wake On LAN.")]
  59.     [string] $Subnet
  60.     )
  61.  
  62.  
  63. ## Predefined variables
  64. $WolCmd=".\wolcmd.exe"
  65. $TimeOut = 30
  66. $Replies = 10
  67.  
  68. clear;Write-Host
  69.  
  70. ## Verify if WOL tool exists
  71. try
  72. {
  73.     Get-ChildItem $WolCmd | Out-Null
  74. }
  75. Catch
  76. {
  77.     Write-Host "$WolCmd file not found!";Write-Host
  78.     exit
  79. }
  80.  
  81. ## Read CSV file with machine names
  82. try
  83. {
  84.     $File=Import-Csv $Machines
  85. }
  86. Catch
  87. {
  88.     Write-Host "$Machines file not found!";Write-Host
  89.     exit
  90. }
  91.  
  92.  
  93. $i=1
  94. foreach($Machine in $File)
  95. {
  96.     $Name=$Machine.Name
  97.     $MAC=$Machine.MacAddress
  98.     $IP=$Machine.IpAddress
  99.  
  100.     ## Send magic packet to wake machine
  101.     Write-Progress -ID 1 -Activity "Waking up machine $Name" -PercentComplete ($i*100/$file.Count)
  102.     Invoke-Expression "$WolCmd $MAC $Interface $Subnet" | Out-Null
  103.  
  104.     $j=1
  105.     ## Go into loop until machine replies to echo
  106.     $Ping = New-Object System.Net.NetworkInformation.Ping
  107.     do
  108.     {
  109.         $Echo = $Ping.Send($IP)
  110.         Write-Progress -ID 2 -ParentID 1 -Activity "Waiting for $Name to respond to echo" -PercentComplete ($j*100/$TimeOut)
  111.         sleep 1
  112.         
  113.         if ($j -eq $TimeOut)
  114.         {
  115.             Write-Host "Time out expired, aborting.";Write-Host
  116.             exit
  117.         }
  118.         $j++
  119.     }
  120.     while ($Echo.Status.ToString() -ne "Success" )
  121.  
  122.     ## Machine is alive, keep sending for $Replies amount
  123.     for ($k = 1; $k -le $Replies; $k++)
  124.     {
  125.        Write-Progress -ID 2 -ParentID 1 -Activity "Waiting for $Name to respond to echo" -PercentComplete (100)
  126.        Write-Progress -Id 3 -ParentId 2 -Activity "Receiving echo reply"  -PercentComplete ($k*100/$Replies)
  127.        sleep 1
  128.     }
  129.     $i++
  130.     Write-Progress -Id 3 -Completed $true
  131.     $Ping=$null
  132. }

   

You can download the script, tool and sample machine.csv here.

 

#######################################################

Update, June 3rd 2012

I have updated my script to be able to do without the wolcmd tool. As pointed out in the comments, it is possible to do this from within PowerShell. So I did some research in MSDN and rewrote my script.

The switches have changed as well. You can now provide the time out, repeat and number of magic packets to send. Run Get-Help .\WakeUp-Machines.ps1 to get additional help (-detailed, –examples, –full all supported).

  

WakeUp-Machines
  1. #######################################################
  2. ##
  3. ## WakeUp-Machines.ps1, v1.1, 2012
  4. ##
  5. ## Created by Matthijs ten Seldam, Microsoft
  6. ##
  7. #######################################################
  8.  
  9. <#
  10. .SYNOPSIS
  11. Starts a list of physical machines by using Wake On LAN.
  12.  
  13. .DESCRIPTION
  14. WakeUp-Machines starts a list of servers using Wake On LAN magic packets. It then sends echo requests to verify that the machine has TCP/IP connectivity. It waits for a specified amount of echo replies before starting the next machine in the list.
  15.  
  16. .PARAMETER Machines
  17. The name of the file containing the machines to wake.
  18.  
  19. .PARAMETER TimeOut
  20. The number of seconds to wait for an echo reply before continuing with the next machine.
  21.  
  22. .PARAMETER Repeat
  23. The number of echo requests to send before continuing with the next machine.
  24.  
  25. .EXAMPLE
  26. WakeUp-Machines machines.csv
  27.  
  28. .EXAMPLE
  29. WakeUp-Machines c:\tools\machines.csv
  30.  
  31. .INPUTS
  32. None
  33.  
  34. .OUTPUTS
  35. None
  36.  
  37. .NOTES
  38. Make sure the MAC addresses supplied don't contain "-" or ".".
  39.  
  40. The CSV file with machines must be outlined using Name, MAC Address and IP Address with the first line being Name,MacAddress,IpAddress.
  41. See below for an example of a properly formatted CSV file.
  42.  
  43. Name,MacAddress,IpAddress
  44. Host1,A0DEF169BE02,192.168.0.11
  45. Host3,AC1708486CA2,192.168.0.12
  46. Host2,FDDEF15D5401,192.168.0.13
  47.  
  48. .LINK
  49. http://blogs.technet.com/matthts
  50. #>
  51.  
  52.  
  53. param(
  54.     [Parameter(Mandatory=$true, HelpMessage="Path to the CSV file containing the machines to wake.")]
  55.     [string] $Machines,
  56.     [Parameter(Mandatory=$false, HelpMessage="Number of unsuccesful echo requests before continuing.")]
  57.     [int] $TimeOut=30,
  58.     [Parameter(Mandatory=$false, HelpMessage="Number of successful echo requests before continuing.")]
  59.     [int] $Repeat=10,
  60.     [Parameter(Mandatory=$false, HelpMessage="Number of magic packets to send to the broadcast address.")]
  61.     [int] $Packets=2
  62.     )
  63.  
  64.  
  65. Set-StrictMode -Version Latest
  66.  
  67. clear;Write-Host
  68.  
  69. ## Read CSV file with machine names
  70. try
  71. {
  72.     $File=Import-Csv $Machines
  73. }
  74. Catch
  75. {
  76.     Write-Host "$Machines file not found!";Write-Host
  77.     exit
  78. }
  79.  
  80. function Send-Packet([string]$MacAddress, [int]$Packets)
  81. {
  82.     <#
  83.     .SYNOPSIS
  84.     Sends a number of magic packets using UDP broadcast.
  85.  
  86.     .DESCRIPTION
  87.     Send-Packet sends a specified number of magic packets to a MAC address in order to wake up the machine.  
  88.  
  89.     .PARAMETER MacAddress
  90.     The MAC address of the machine to wake up.
  91.  
  92.     .PARAMETER
  93.     The number of packets to send.
  94.     #>
  95.  
  96.     try
  97.     {
  98.         $Broadcast = ([System.Net.IPAddress]::Broadcast)
  99.  
  100.         ## Create UDP client instance
  101.         $UdpClient = New-Object Net.Sockets.UdpClient
  102.  
  103.         ## Create IP endpoints for each port
  104.         $IPEndPoint1 = New-Object Net.IPEndPoint $Broadcast, 0
  105.         $IPEndPoint2 = New-Object Net.IPEndPoint $Broadcast, 7
  106.         $IPEndPoint3 = New-Object Net.IPEndPoint $Broadcast, 9
  107.  
  108.         ## Construct physical address instance for the MAC address of the machine (string to byte array)
  109.         $MAC = [Net.NetworkInformation.PhysicalAddress]::Parse($MacAddress)
  110.  
  111.         ## Construct the Magic Packet frame
  112.         $Frame = [byte[]]@(255,255,255, 255,255,255);
  113.         $Frame += ($MAC.GetAddressBytes()*16)
  114.  
  115.         ## Broadcast UDP packets to the IP endpoints of the machine
  116.         for($i = 0; $i -lt $Packets; $i++) {
  117.             $UdpClient.Send($Frame, $Frame.Length, $IPEndPoint1) | Out-Null
  118.             $UdpClient.Send($Frame, $Frame.Length, $IPEndPoint2) | Out-Null
  119.             $UdpClient.Send($Frame, $Frame.Length, $IPEndPoint3) | Out-Null
  120.             sleep 1;
  121.         }
  122.     }
  123.     catch
  124.     {
  125.         $Error | Write-Error;
  126.     }
  127. }
  128.  
  129. $i=1
  130. foreach($Machine in $File)
  131. {
  132.     $Name=$Machine.Name
  133.     $MacAddress=$Machine.MacAddress
  134.     $IPAddress=$Machine.IpAddress
  135.  
  136.     ## Send magic packet to wake machine
  137.     Write-Progress -ID 1 -Activity "Waking up machine $Name" -PercentComplete ($i*100/$file.Count)
  138.     Send-Packet $MacAddress $Packets
  139.  
  140.     $j=1
  141.     ## Go into loop until machine replies to echo
  142.     $Ping = New-Object System.Net.NetworkInformation.Ping
  143.     do
  144.     {
  145.         $Echo = $Ping.Send($IPAddress)
  146.         Write-Progress -ID 2 -ParentID 1 -Activity "Waiting for $Name to respond to echo" -PercentComplete ($j*100/$TimeOut)
  147.         sleep 1
  148.         
  149.         if ($j -eq $TimeOut)
  150.         {
  151.             Write-Host "Time out expired, aborting.";Write-Host
  152.             exit
  153.         }
  154.         $j++
  155.     }
  156.     while ($Echo.Status.ToString() -ne "Success" )
  157.  
  158.     ## Machine is alive, keep sending for $Replies amount
  159.     for ($k = 1; $k -le $Repeat; $k++)
  160.     {
  161.        Write-Progress -ID 2 -ParentID 1 -Activity "Waiting for $Name to respond to echo" -PercentComplete (100)
  162.        Write-Progress -Id 3 -ParentId 2 -Activity "Receiving echo reply"  -PercentComplete ($k*100/$Repeat)
  163.        sleep 1
  164.     }
  165.     $i++
  166.     Write-Progress -Id 3 -Completed $true
  167.     $Ping=$null
  168. }

    

 
Comments (34)

  1. Anonymous says:

    I guess as a side note, this functionality is not available in Powershell version 2. I just installed the management framwork 4 and it worked. That being said, I am not sure about version 3.

  2. Anonymous says:

    @Dan

    The Wake On LAN will work on both because it only sends a magic packet to specific MAC addresses. The script uses IP-addresses only to wait for a response and then continue.

    @Ryan

    I would need more info as to what you want to achieve. Windows supports autologon, you can logon through a remote PowerShell session or invoke remote PowerShell scripts. is that what you are looking for?

  3. Anonymous says:

    great post, thanks

  4. Anonymous says:

    great post, thanks

  5. Anonymous says:

    Hi there,

    Another script for Wake On LAN (WOL). Supports both IPv4 and IPv6. Can be enhanced with a lot of other features such as reading files and user input. Works on my home network, but not tested on a more complex environment. If you test it, please share feedback. Thanks.

    <# —- For security reason, the code is fully commented —-

    # Consider also possibility to read / parse an external file, or a user interface to collect addresses

    # Consider possibility to read from ARP tables, DHCP routing tables, DNS lists, Domain Controller, etc.

    <#

    $szMACAddress = [string]"AA-BB-CC-DD-EE-FF"

    $szMACAddress = [string]"AA:BB:CC:DD:EE:FF"

    $szMACAddress = [string]"AA BB CC DD EE FF"

    $szMACAddress = [string]"AABBCCDDEEFF"

    #>

    <# —- For security reason, the code is fully commented —-

    $szMACAddress = [string]"AA-BB-CC-DD-EE-FF"

    # The "Magic Packet" starts with six pairs of 0xFF values

    [Byte[]]$szPacket = [Byte[]] (,0xFF * 6)

    # MAC addresses are defined by six pairs of hexadecimal values that could be separated by a dash (-),

    # a column (:), or a space ( ); the address could be also twelve hexadecimal values without separator

    if([Regex]::IsMatch($szMACAddress, '[A-Fa-f0-9]{2}p{Pd}[A-Fa-f0-9]{2}p{Pd}[A-Fa-f0-9]{2}p{Pd}[A-Fa-f0-9]{2}p{Pd}[A-Fa-f0-9]{2}p{Pd}[A-Fa-f0-9]{2}'))

    {

       # MAC address has the form 'xx-xx-xx-xx-xx-xx'

       $szPacket += (($szMACAddress.split('-') | foreach {[byte] ('0x' + $_)}) * 16)

    }

    elseif([Regex]::IsMatch($szMACAddress, '[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}:[A-Fa-f0-9]{2}'))

    {

       # MAC address has the form 'xx:xx:xx:xx:xx:xx'

       $szPacket += (($szMACAddress.split(':') | foreach {[byte] ('0x' + $_)}) * 16)

    }

    elseif([Regex]::IsMatch($szMACAddress, '[A-Fa-f0-9]{2} [A-Fa-f0-9]{2} [A-Fa-f0-9]{2} [A-Fa-f0-9]{2} [A-Fa-f0-9]{2} [A-Fa-f0-9]{2}'))

    {

       # MAC address has the form 'xx xx xx xx xx xx'

       $szPacket += (($szMACAddress.split(' ') | foreach {[byte] ('0x' + $_)}) * 16)

    }

    elseif([Regex]::IsMatch($szMACAddress, '[A-Fa-f0-9]{12}'))

    {

       # MAC address has no separator between pairs of hexadecimal values

       $szPacket += for ($j = 0; $j -le 15; $j++) { for ($i = 0; $i -le ($szMACAddress.Length -1); $i += 2) {[byte] ('0x' + $szMACAddress[$i] + $szMACAddress[$i+1])}}

    }

    else

    {

       # MAC address format is not recognized

       Throw "ERROR: MAC Address is not recognized !"

    }

      —- For security reason, the code is fully commented —-

    #>

    (1 / 2)

  6. Anonymous says:

    I have rewritten my script to send the magic packets from code. So an external tool is no longer needed.

  7. Anonymous says:

    ( 2 / 2 )

    <# —- For security reason, the code is fully commented —-

    # Verify if we support IPv6 or IPv4

    if([System.Net.Sockets.Socket]::OSSupportsIPv6)

    {

       Write-Output "Your system supports IPv6"

       # Create a new communication channel using the UDP protocol

       $netUDPClient = New-Object System.Net.Sockets.UdpClient([System.Net.Sockets.AddressFamily]::InterNetworkV6)

       # Connect to the network using port 9 (this is the standard for WOL) on the multicast "All routers" address

       # To send to multicast address "All hosts", use address "FF02::1" instead

       $netUDPClient.Connect([System.Net.IPAddress]::Parse("FF02::2"), 9)

    }

    elseif([System.Net.Sockets.Socket]::OSSupportsIPv4)

    {

       Write-Output "Your system supports IPv4"

       # Create a new communication channel using the UDP protocol

       $netUDPClient = New-Object System.Net.Sockets.UdpClient([System.Net.Sockets.AddressFamily]::InterNetwork)

       # Connect to the network using port 9 (this is the standard for WOL) on the broadcast address

       $netUDPClient.Connect(([System.Net.IPAddress]::Broadcast),9)    

    }

    else

    {

       Throw "ERROR: Neither IPv4, nor IPv6 are supported !"

    }

    # Send the magic packet to the network

    [void]$netUDPClient.Send($szPacket, $szPacket.Length)

    # Release managed and unmanaged resources

    [void]$netUDPClient.Dispose()

    # Remove used variables

    Remove-Variable netUDPClient, szPacket, szMACAddress

      —- For security reason, the code is fully commented —-

    #>

    Cheers,

    Didier

  8. guest says:

    But there's script which doesn't require exe tool, why not use that approach?

  9. Dan says:

    Is there a solution where Wake On Lan will work, on PCs, which have dynamic ip addresses, rather than static ip addresses?

  10. Nick Borgers says:

    Very nice, thanks for doing this with Windows resources instead of going to a separate binary.

  11. Ryan says:

    This is very useful to me as I manage a lab of computers.  It's great this can be done without the wolcmd tool as well.

    Something that would take this a step further for me would be the ability to have each remote computer login to a local account from a PowerShell script.  Is this possible?  If so, how would I go about doing that?

  12. Dave says:

    I've tried both incarnations of your script and both fail with an error message:

    . : Property 'Count' cannot be found on this object. Make sure that it exists.

    At C:tempWakeUp-Machines.ps1:137 char:93

    +     Write-Progress -ID 1 -Activity "Waking up machine $Name" -PercentComplete ($i*100/$file. <<<< Count)

       + CategoryInfo          : InvalidOperation: (.:OperatorToken) [], RuntimeException

       + FullyQualifiedErrorId : PropertyNotFoundStrict

    In spite of the error the script does wake up a machine.  What am I missing?

  13. Ryan says:

    Matthijs,

    Please allow me to more specific about what I want.  I want the machines to login to the desktop so that the computer becomes available to lab users that aren't given any login credentials.  I don't want to use auto login because I want to be able to control when the machines become available to the lab users.  Thanks for your help.

  14. Ryan says:

    Dave,

    I'm betting that you only have one machine in your csv.  That's how I was able to re-create your problem anyways.

    If this is the case, the problem is line 72 (in the second incarnation).  The Import-Csv command will only return an array if you have multiple machines in your list.  If you only have one machine in your list it returns a scalar, which doesn't have a Count property.

    One way to fix this is to force the file variable to be an array like so:

    $File = @(Import-Csv $Machines)

    I hope this helps.

  15. Ryan says:

    Dan,

    I too have a dynamic IP envirnment.  I looked up System.Net.NetworkInformation.Ping.Send(string) and it looks like it will take either a host name or an IP address.  I plan on giving it a host name.  You may want to do the same.  Then there is no longer any reason to have an IP address column in the CSV.

  16. Dave says:

    Ryan,

    That fix resolved my issue.  Thanks!

  17. Matthijs says:

    Guys,

    the IP address is not necessary at all for waking the machines. I use it to verify whether the specific machine has its IP-stack loaded, so basically if the wake up has succeeded. Indeed, if you only want to wake machines and are not interested in the result, you can do without.

  18. Caroline says:

    Hello,

    I am totally new to all this scripting business.

    I would like to automate this script, ie run it without any input from me. So far, I have found a batch script that will run it without having to input the csv filename but I can't get it to automate so that I don't need to type in text to send as the wake up call. How can I do this?

    regards,

    Caroline

  19. Debbie says:

    Trying to find a way to WOL via a specific port.  We have an issue at some of our locations with the default port.  Want to use one we know is open.  

  20. VasekB says:

    msdn.microsoft.com/…/system.net.networkinformation.physicaladdress.parse.aspx

    ## Construct physical address instance for the MAC address of the machine (string to byte array)

    $MAC =[Net.NetworkInformation.PhysicalAddress]::Parse(($MacAddress -replace ':','-').ToUpper() )

  21. Shaun says:

    Instead of using a csv file to load all the mahine names manually, can you just use MAC FF:FF:FF:FF:FF:FF and the broadcast ip 192.168.1.255 and wake up all the computers on the whole network at the same time?

    The broadcast MAC is referenced on this page: en.wikipedia.org/…/Broadcast_traffic

  22. Keila says:

    For some reason, I can’t get the script to work.. It’s reading my MAC address right (I did a Write-Host) but the machine won’t wake up. I’ve used a wake on LAN utility to wake this machine before… but I can’t get this script to do it. What could I be
    doing wrong? It’s not spitting out any errors. Below is my csv file contents… Name,MacAddress,IpAddress Cloud3,001E4FB9CB14,192.168.168.138 Cloud1,0026B98026F8,192.168.168.198

  23. Gary says:

    Does this PS script work on Powershell 1.0 or is there a minimum version?

  24. Gary says:

    Great script – I am looking to schedule the script to do a morning ‘wake’ of all site machines which I’ve managed to achieve. Would you mind sharing how you might go about adding in success and error logs?
    Thanks,
    Gary

  25. Tom says:

    Caroline,

    Using the wolcmd.exe utility, here is a section of the script that includes changes that I had to make to make this fully automated. Just replace the part that starts with ##Predefined variables.

    ## Predefined variables
    $WolCmd="C:Scriptswolcmd.exe"
    $TimeOut = 30
    $Replies = 10

    [tag:These] replace the parameters specified in the original script

    #[tag:Location] of your .csv file
    $Machines = "C:Scriptswol_chicago.csv"

    #[tag:Interface] of the system from where your WoL packet is being sent
    $Interface = "192.168.0.1"

    #[tag:Subnet] mask of destination PC that you are trying to wake up
    $Subnet = "255.255.255.224"

    clear;Write-Host

    ## Verify if WOL tool exists
    try
    {
    Get-ChildItem $WolCmd | Out-Null
    }
    Catch
    {
    Write-Host "$WolCmd file not found!";Write-Host
    exit
    }

    ## Read CSV file with machine names
    try
    {
    $File=Import-Csv $Machines
    }
    Catch
    {
    Write-Host "$Machines file not found!";Write-Host
    exit
    }

    $i=1
    foreach($Machine in $File)
    {
    $Name=$Machine.Name
    $MAC=$Machine.MacAddress
    $IP=$Machine.IpAddress

    ## Send magic packet to wake machine (Made changes here next to Invoke-Expression)
    Write-Progress -ID 1 -Activity "Waking up machine $Name" -PercentComplete ($i*100/$file.Count)
    Invoke-Expression "$WolCmd $MAC $IP $Subnet" | Out-Null

    $j=1
    ## Go into loop until machine replies to echo
    $Ping = New-Object System.Net.NetworkInformation.Ping
    do
    {
    $Echo = $Ping.Send($IP)
    Write-Progress -ID 2 -ParentID 1 -Activity "Waiting for $Name to respond to echo" -PercentComplete ($j*100/$TimeOut)
    sleep 1

    if ($j -eq $TimeOut)
    {
    Write-Host "Time out expired, aborting.";Write-Host
    exit
    }
    $j++
    }
    while ($Echo.Status.ToString() -ne "Success" )

    ## Machine is alive, keep sending for $Replies amount
    for ($k = 1; $k -le $Replies; $k++)
    {
    Write-Progress -ID 2 -ParentID 1 -Activity "Waiting for $Name to respond to echo" -PercentComplete (100)
    Write-Progress -Id 3 -ParentId 2 -Activity "Receiving echo reply" -PercentComplete ($k*100/$Replies)
    sleep 1
    }
    $i++
    Write-Progress -Id 3 -Completed $true
    $Ping=$null
    }

  26. Broccauley says:

    For some reason the standard 255.255.255.255 broadcast address was not working on my set-up, but would work if I sent the magic packet to just the broadcast address for my local subnet at 192.168.1.255.

    To get this to work in your second v1.1 script I changed:
    $Broadcast = ([System.Net.IPAddress]::Broadcast)

    to read:
    $Broadcast = ([System.Net.IPAddress]::Parse("192.168.1.255"))

  27. Milan Bozic says:

    Easier approach would be to use existing PowerShell cmdlets with correct arguments. PowerShell script should look something like this:

    $cred = Get-Credential administrator

    $nic= gwmi win32_networkadapter -filter "netenabled = ‘true’" -cn dc1 -cred $cred

    $nicPower = gwmi MSPower_DeviceWakeEnable -Namespace rootwmi -cn -cred $cred |

    where {$_.instancename -match [regex]::escape($nic.PNPDeviceID) }

    $nicPower.Enable = $true

    $nicPower.psbase.Put()

    (gwmi win32_operatingsystem -CN -cred $cred).reboot()

    Last line can be omitted if you do not want to reboot that machine immediately. For the detailed code description, please check this link:
    http://blogs.technet.com/b/heyscriptingguy/archive/2011/08/11/configure-a-network-adapter-to-wake-a-computer-via-powershell.aspx

  28. Troy T says:

    Notice that as this script goes through the CSV list, if it comes across a machine that it does not get a response from (because the machine is powered off or the user has their laptop out of the office), it times out and exits the scipt. How do you get
    the script to continue to read from the CSV even if a machine does not respond? Can’t for the life of me figure it out.

  29. Flemming Thomadsen says:

    I have the same issue as Troy T that the script exit when a computer is not reachable over the network..hope that someone has a solution for that

  30. Kerry says:

    I’m new to powershell. I used to have a similar VBS script but can’t for the life of me find the darn thing. Anyway, sorry to flog a two year old post but maybe someone can still hlep.
    When I try to run the cmdlet I get "The term ‘wakeup-machines’ is not recognized as the name of a cmdlet"
    I’m running a powershell window in the directory where the cmdlet resides… Any thoughts?

  31. Lelethu says:

    Hi Matthijs
    Great script I must say how can I actually get the script to start all the machines on the CSV file without putting in the parameters when I run the script.

  32. Hans Eikelenboom says:

    Great script but I have the same issue as Flemming and troy is there a solution

  33. Jonathon says:

    Matthijs … I hope you don’t mind, I used your script and modified it a little. I modified the script to import the DHCPServer module for PS. It then gets a collection of lease objects from the DHCP server, and uses that data to iterate over every machine
    using "Send-Packet". I also changed it slightly to send all Wake On LAN packets, and then go back and ping test all of them.

    Here is the final/current version

    http://hastebin.com/odoqefawew.parser3