Advanced VirtualBox: Auto start virtual machine on Windows

I've always considered myself to be an advanced computer user, but I'm not a Windows person, at least not when I'm coding. So when I got a Windows 10 laptop as a daily work machine, I'm beyond disappointed. Luckily, there's always a way around -- VirtualBox it is. The laptop I got was powerful enough that I was able to allocate 16GB of memory as well as 3 cores of the host machine to the virtual machine.

Once I had my vm setup, I always use Windows Terminal and SSH into the machine for development. One day, it occurs to me I can (and should) automate all of this.

Problem

Automatically start the selected VirtualBox virtual machine in headless mode (this can save a bit of resources), wait for the machine to boot, and then SSH into the VM using Windows Terminal with selected port forwarding on the host and virtual machine.

Solution

This is not something that can be achieved in one go, therefore I'm going to breakdown by components:

  • Virtual machine -- Assuming Systemd based Linux distro
    • We need to disable the graphical login interface for the VM. To achieve this, we can do systemctl set-default multi-user.target . If we need to revert back to graphical login, we can do systemctl set-default graphical.target. The multi-user.target and graphical.target are equivalent to what was traditionally known as run levels in SystemV.
    • We also need to setup the necessary SSH access from the Windows 10 host machine to the virtual machine. I won't cover that here. Only thing to keep in mind is to open the necessary ports.
  • Host machine -- need to setup batch script, Windows Terminal profile and Window startup
    • Batch script
      • What we need to achieve in the batch script is start the machine and wait for it to boot. Fortunately, virtualbox installation comes with something that can achieve this, it is called VBoxmanage.exe and is in the VirtualBox installation folder
      • To start the virtual machine, the command will be "C:\Program Files\VirtualBox\VboxManage.exe" startvm [VM name] --type headless. Change the command with your VM name, the --type headless means that no GUI of the virtual machine will be started at all.
      • Next step is to wait for the machine to start up, the command for this will be "C:\Program Files\VirtualBox\VboxManage.exe" wait "[VM name]" "/VirtualBox/GuestInfo/OS/NoLoggedInUsers"
      • Last step for the batch script will be wt, which represents windows terminal.
      • To put it together, the batch script will be
        1
        2
        3
        4
        @echo off
        "C:\Program Files\VirtualBox\VboxManage.exe" startvm [VM name] --type headless
        "C:\Program Files\VirtualBox\VboxManage.exe" wait "[VM name]" "/VirtualBox/GuestInfo/OS/NoLoggedInUsers"
        wt
    • Windows terminal profile
      • Create a profile in Windows terminal, this can be done from either the UI or the json setting file.
      • Here, I will present the profile I use personally:
        1
        2
        3
        4
        5
        6
        7
        {
        "bellStyle": "visual",
        "colorScheme": "Tango Dark",
        "commandline": "ssh -R 5432:localhost:5432 -L 8080:[::1]:8080 -L 3000:[::1]:3000 -t username@vm_ip_address "exec zsh -l"",
        "name": "VM",
        "scrollbarState": "hidden"
        }
      • It is obvious the commandline part is a bit bloated cause I was trying to do a bit too much in one go. Actually, it is a lot cleaner to put the command in a batch file and this line can be replaced by the path to that specific batch file as well.
    • Windows Auto Start
      • Press Windows+R and type shell:startup, this will bring up a folder called "StartUp" where you can put a bunch of things that you want to auto start when Windows starts.
      • Drag the Batch script created into this folder to create a shortcut.

After these setup, Windows will now start the virtual machine every time you start your computer.

Bonus: shutdown VM in one click

The same aforementioned VboxManage.exe can be used to poweroff the virtual machine as well. You can achieve that by creating a batch file with the following content:

1
2
@echo off
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm DEV_MACHINE poweroff

You can also halt or save the state of the VM rather than poweroff. More information on this can be found in the virtualbox manual.

Further readings

VirualBox manual on VboxManage
Systemd manual on special units