Delaying Hyper-V virtual machine startup: A PowerShell solution

One of the hard lessons that most virtualization admins learn sooner or later is that you can’t typically power up all of your virtual machines at the same time. A domain controller may need to be running before a mail server comes online. A database server may need to be running before an application server is brought up. There are any number of reasons why an admin may need to wait to start a VM until another VM is up and running. The problem is, however, that the Hyper-V Manager really doesn’t give you a good way of dealing with this challenge. So what’s an admin to do?

One option is to turn to PowerShell scripting. In fact, there is an undocumented Hyper-V cmdlet that can be used to delay the startup of a virtual machine.

The cmdlet is called Wait-VM. As I said, this cmdlet is completely undocumented. Microsoft maintains a web page with syntax and usage examples for each and every PowerShell cmdlet, but for some reason, this one was left out. I stumbled onto the cmdlet totally by accident while working on something unrelated.

So with that said, let’s take a look at the cmdlet’s syntax. Even though Microsoft does not provide online documentation for this cmdlet, it is still possible to get information on the cmdlet’s syntax by entering the Get-Help cmdlet, followed by the Wait-VM cmdlet. Here is the syntax as listed by Get-Help:

NAME
Wait-VM

SYNTAX
Wait-VM [-Name] <string[]> [-CimSession <CimSession[]>] [-ComputerName <string[]>] [-Credential <pscredential[]>]
[-AsJob] [-Passthru] [-For {Heartbeat | IPAddress | Reboot | MemoryOperations}] [-Delay <uint16>] [-Timeout <int>]
[<CommonParameters>]

Wait-VM [-VM] <VirtualMachine[]> [-AsJob] [-Passthru] [-For {Heartbeat | IPAddress | Reboot | MemoryOperations}]
[-Delay <uint16>] [-Timeout <int>] [<CommonParameters>]

ALIASES
None

REMARKS
Get-Help cannot find the Help files for this cmdlet on this computer. It is displaying only partial help.
— To download and install Help files for the module that includes this cmdlet, use Update-Help.

If you are not used to looking at the full syntax breakdown for PowerShell cmdlets, then this one might initially appear to be a bit on the complicated side. The good news, however, is that most of the parameters that are listed within the syntax above are optional. Using the Wait-VM cmdlet is actually quite simple.

The most basic way to use the Wait-VM cmdlet is to simply type Wait-VM, followed by the Name parameter, and the name of the VM that you want to wait on. In my testing, for example, I used a VM that was named DC. Here is what the command looked like:

Wait-VM -Name DC

Hyper-V VM startup
From what I was able to observe, it seems as though the command listed above caused my PowerShell script to pause and wait for the specified VM to start up. Keep in mind that this command does not actually start the VM. That has to be done separately. The command simply prevents the script from doing anything else until the VM is online.

Now I have to be completely honest with you and say that because the Wait-VM cmdlet is undocumented, I am not completely sure what the trigger is that causes the wait to end. By experimenting with the cmdlet, I can tell you for sure that the wait time is not based on a timer. Different virtual machines waited for different lengths of time. I can also tell you that the wait ended with the VM being most of the way through the boot process, but not yet displaying the login screen.

More control

If you would prefer to have a little bit more control over the wait, there are some parameters that you can use. One possible option is to add a delay to the wait. The Wait-VM cmdlet includes a Delay parameter that you can use to increase the wait time. Earlier, for example, I indicated that when I ran the Wait-VM cmdlet, specifying only the VM name, the wait ended before the VM had reached the login prompt. What I have found is that by adding a delay it is possible to extend the wait so as to make sure that the VM’s boot process is complete. In one of my tests, for example, I decided to add two minutes (120 seconds) to the wait. This caused the wait not to end until well after the login screen was displayed. Here is what the command looks like:

Wait-VM -Name DC -Delay 120

Hyper-V VM startup
Another thing that you can do is to specify what it is that you want PowerShell to wait for. If you look back at the Wait-VM cmdlet’s syntax, you will notice that you can specify a For parameter, along with what it is that you want to wait for. The options include waiting for the VM to produce a heartbeat, acquire an IP address, or for the VM to reboot. There is also a memory operations option, but I am not completely sure what that option actually does.

Using the For parameter is simple. Just specify the parameter, followed by what it is that you want to wait for. If you wanted to wait for the VM’s heartbeat, for example, the command would look like this:

Wait-VM -Name DC -For Heartbeat

Hyper-V VM startup
Delaying Hyper-V virtual machine startup: Two last bits of advice

I can think of about a billion different ways to use the Wait-VM cmdlet in various PowerShell scripts. The potential uses range from multitier application deployment to disaster recovery. Before you attempt to use this cmdlet in a production environment, however, there are two bits of advice that I would like to pass along.

First, spend a little bit of time in a lab environment getting used to the command before you try it in production. This is an undocumented cmdlet, so it might not behave exactly the way that you would expect.

Second, you might consider working the timeout parameter into your scripts. By specifying a timeout period, you can keep your script from hanging in the event that a VM fails to start.

Featured image: Shutterstock

Leave a Comment

Your email address will not be published.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top