32

I am trying to find a solution to gracefully shutdown any guest VMs running under VirtualBox Windows when the host computer is shut down or restarted.

It seems that the safest option would be to trigger the "save state" command when the host starts shutting down, but it is not clear whether the host will wait long enough for the VMs to finish saving state and power off.

Does anyone have a robust solution for this (seemingly basic) issue?

2
  • Install the guest additions? Does that not provide the functionality required? Commented Aug 19, 2015 at 23:31
  • 1
    @CanadianLuke It does not. :) Commented Nov 6, 2015 at 11:09

7 Answers 7

14

Sorry I'm late to the party. There is an exact answer to this, though it requires some commandline-foo. See this thread post for more information: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

The command you are looking for is:

"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" setextradata "VM NAME" GUI/DefaultCloseAction Shutdown

This is what I use on multiple VMs, close the window and it starts a safe shutdown automatically. Shutdown Windows, and in its attempt to close everything, it will wait for these processes to complete.

5
  • 2
    Thanks! Since OP was looking for save state, the answer is SaveState instead of Shutdown.
    – wbkang
    Commented Feb 17, 2020 at 22:15
  • Thank you! Works for me Commented Oct 16, 2020 at 13:59
  • After using this command how can I save machine state manually? Commented Sep 16, 2023 at 10:44
  • This command doesn't work when you detach the gui. Instead it saves the machine state as usual. Commented Sep 16, 2023 at 11:29
  • @mustafacandan Unfortunately I'm not familiar with detaching the GUI. I think some other comments here talked about performing the requested operations while in detached mode. I also have not needed this feature since about after I answered it, so I'm not sure how much it has changed in that time. Commented Sep 18, 2023 at 18:00
7

I had a similar problem and solved it by running VirtualBox as a service:

https://github.com/onlyfang/VBoxVmService

With VBoxVMService you can chose how you want the machine to shutdown (Save state, power off) and startup. Since it's running as a service, Windows will automatically wait for it to shutdown, during the system shutdown process.

1
  • The setting up process is not so automatic on Windows 10. I have to refer to the trouble shooting to see what's wrong. However, after configured correctely, this software does exactly what I need. Thank you for you great work.
    – iuradz
    Commented May 9, 2017 at 6:25
3

Unfortunately that doesn't seem to be possible for VMs started via VirtualBox GUI. Even though the GUI might catch the host shutdown event and react, the VirtualBox service gets terminated: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

If you don't need a graphical console, VBoxHeadlessTray or VBoxVMService might be the way to go. Both support automatic save and resume on Windows host shutdown and restart.

VirtualBox 5.0 introduces a "detachable UI" start mode. This mode starts a headless VM with a separate UI process. Graphical performance suffers though and 3D acceleration isn't supported yet. But maybe this can be combined with VBoxHeadlessTray in the future (VBoxHeadlessTray doesn't support 5.0 yet.) Links to VBoxHeadlessTray GitHub repository and to the corresponding GitHub pull request for adding VirtualBox 5 support.

Edit: VBoxVmService also doesn't support the new detachable mode as of version 5.0. Only headless so far. I added a feature request for that.

2
  • As I am not allowed to port more than two links per post, here are the links to VBoxHeadlessTray and to the corresponding GitHub pull request for adding VirtualBox 5 support.
    – Leo B
    Commented Oct 31, 2015 at 10:00
  • I do not experience the issues outlined in the thread. See my answer on this topic. I can run Windows host shutdown and walk away. Shutdown blocks until all of my VMs are closed, and I've changed the default action to do a clean shutdown or a save state. Commented Apr 4, 2018 at 16:59
3

I have 3 batch scripts which I use instead of the startmenu power buttons.

do_shutdown.bat (shutdown pc with a 10 sec waiting period, not to give the vm's 10 sec time to savestate, but to allow me to cancel the shutdown within 10 seconds. The countdown starts after the vm's have been shut down)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /s /t 10

do_reboot.bat (reboots immediately after the vm's got shut down)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /r /t 0

do_cancel.bat (allows me to cancel the pc-shutdown within the 10 second waiting period. It then restarts the vm's again, since they got shut down with the do_shutdown.bat)

shutdown /a
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Minimal" --type headless
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Server" --type headless

Instead of savestate you can also use one of the following

poweroff        - pulls the plug
                  (probably not a good idea...)

acpipowerbutton - presses the power off button for a clean shutdown
                  ("The system is going down for power off NOW!" to all consoles)

acpisleepbutton - tells the os to go to sleep
                  (probably just as bad as poweroff)
2
  • 2
    Thanks, this is interesting. Unfortunately, there are other non-manual shutdown/reboot scenarios that I need to handle as well. For example, restarts scheduled by Windows Update, or low battery power off/shutdown events. Commented Nov 6, 2015 at 11:08
  • 2
    Oh, ok. There's also the Group Policy Editor with the "Scripts (Startup/Shutdown)" section lifehacker.com/… I'm using that one for a very short command on shutdown (one curl call), so I don't know how it behaves on scripts that take a while to complete.
    – Daniel F
    Commented Nov 6, 2015 at 13:07
2

I had a similar question and found this page. I don't want to run VirtualBox as a service, because I have a lot of VMs for testing, and usually pick different ones to run in the VirtualBox UI. When I shutdown my computer, it is annoying to manually save the state of each VM. Using scripts to save all running VMs seems to be a practical solution in this case. To make the answer of Daniel F more general, I wrote these scripts that automatically save the state of all running VMs without naming them explicitly.

saveRunningVMs.bat for Windows:

set VBoxManageEXE="%ProgramFiles%\Oracle\VirtualBox\VBoxManage.exe"
set ListRunningVMS=%VboxManageEXE% list runningvms
for /f tokens^=2^,4^ delims^=^" %%p in ('%ListRunningVMS%') do %VBoxManageEXE% controlvm %%p savestate

echo all vms saved, you can shutdown now.

rem shutdown /s /t 10

saveRunningVMs.sh for Linux:

#!/bin/bash
vboxmanage list runningvms | while read line; do
  #echo "VBoxManage controlvm $uuid savestate;"
  echo $line
  if [[ $line =~ \{(.*)\} ]]
  then
    vboxmanage controlvm ${BASH_REMATCH[1]} savestate
  fi
done
1

I created a python script that would suspend all the running VirtualBox VMs, and then set the system up to run the script on logout as a scheduled task.

I don't know how reliable this method is exactly. As others have noted there are limits to how long the system will wait for a Winlogon event 7002 (the logout event log event) task to complete. But I personally haven't had any problem with it giving usable save states even with multiple running VMs across 4+ GB of overall VM RAM.

Here are the steps to set it up:

  1. Download and install Python 2.7.x from python.org
  2. Create the python script file somewhere on your system using Notepad or any other plain text editor (see below)
  3. Open Task Scheduler
  4. Choose Action -> Create a Basic Task... and use the wizard to create a task with the following settings
    • A name of your choice
    • Start the task when a specific event is logged
    • Log: System
    • Source: Winlogon
    • Event ID: 7002
    • Start a Program
    • Next to Program/Script, enter the full path to your python.exe, for instance c:\Python27\python.exe
    • Next to Add arguments, enter the full path where you put the python script file, for instance I put mine in a subfolder of my documents folder, so this is C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Choose Finish.

Now VirtualBox VMs should be suspended on logout/restart/shutdown.

The python script to do the shutdown is below:

# A script to suspend all running VirtualBox VMs

import os

import subprocess

import sys


class VM(object):
    def __init__(self, name, uuid):
        self.name = name
        self.uuid = uuid

    def __repr__(self):
        return "VM(%r,%r)" % (self.name, self.uuid)


class VBoxRunner(object):
    def __init__(self):
        program_files = os.environ["ProgramW6432"]
        vbox_dir = os.path.join(program_files, "Oracle", "VirtualBox")
        self.vboxmanage_filename = os.path.join(vbox_dir, "VBoxManage.exe")

    def vbox_run(self, *args):
        subprocess.check_call([self.vboxmanage_filename] + list(args))

    def vbox_run_output(self, *args):
        return subprocess.check_output([self.vboxmanage_filename] + list(args))

    def list(self, running=True):
        if running:
            list_cmd = "runningvms"
        else:
            list_cmd = "vms"

        return [self.parse_vm_list_entry(x) for x in self.vbox_run_output("list", list_cmd).strip().split("\n")]

    def suspend_all(self):
        success = True
        stopped_some_vms = False
        vms = self.list(running=True)
        for vm in vms:
            if vm is None:
                continue
            # noinspection PyBroadException
            try:
                self.suspend_vm(vm)
            except:
                success = False
            else:
                stopped_some_vms = True
        if not stopped_some_vms:
            self.message("No running vms")
        return success

    @staticmethod
    def parse_vm_list_entry(x):
        """:type x: str"""
        if not x.startswith('"'):
            return None
        end_pos = x.find('"', 1)
        if end_pos == -1:
            return None
        name = x[1:end_pos]
        assert x[end_pos + 1: end_pos + 3] == " {"
        assert x.endswith("}")
        uuid = x[end_pos + 2:]

        return VM(name, uuid)

    @staticmethod
    def message(msg):
        print >>sys.stderr, msg

    def suspend_vm(self, vm):
        assert isinstance(vm, VM)
        self.vbox_run("controlvm", vm.uuid, "savestate")


def main():
    vr = VBoxRunner()
    success = vr.suspend_all()
    if not success:
        sys.exit(1)


if __name__ == "__main__":
    main()
1
  • 1
    Others' suggestion of using a batch script you can run manually that does the savestates and then does the shut down is great if that fits your use case. But what I really want this for is Windows Update automatic reboots, after a VM I've been working with has been hard powered off overnight by Windows Update restarts for the past two days in a row...
    – rakslice
    Commented Jun 4, 2018 at 3:59
0

I had trouble with a lot of the solutions offered, the scripts offered as solutions here work, but for some reason most of the time after restarting the host I received the "last shutdown was unexpected" message on the guests. Startup was reliable, and the shutdown scripts generally worked when executed manually, but when executed automatically most of the time the guests didn't shutdown gracefully, i tried a number of different ways and put in pauses/timeouts etc, but no dice

In the end i did end up using VBoxVmService, but one thing that tripped me up that wasn't mentioned here is that I found I needed to start the service with the credentials that I intended to login and administer the virtual machines with, otherwise when I opened virtual box they appeared stopped, even though they were running, and trying to edit them failed.

I wrote this up in more detail here https://www.roamempire.com.au/post/virtualbox-auto-startup-and-shutdown

2
  • 1
    You should post full solution content, not just a link to the 'more detailed' content. Commented Jul 4, 2020 at 14:53
  • Case in point - the website link doesn't work anymore. :( Commented Jan 14, 2022 at 22:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .