Script to set up port forwarding, start/stop & automatically SSH into headless VirtualBox VM
Table of Contents
Virtual machines are very useful not only on servers or in cloud environments, but also installed locally on a workstation to try out things. I often install virtual machines without graphical interface, such as CentOS Minimal. One thing that can become a bit annoying is the fact that the available screen size in a VM’s CLI can be quite limited, as it does not automatically resize with the VM window:
In an environment that provides a GUI this would be solved by installing the VirtualBox GuestAdditions. There are also many instructions on how to install these on non-graphical VMs, but none of them did really work for me. Moreover, what these instructions have in common is that quite a lot of additional packages have to be installed, which I obviously would like to avoid when purposefully running on a minimal setup.
Script for VM startup, port forwarding, SSH
The more straightforward solution is therefore to SSH into the VM from the host using an SSH client like PuTTY or simply the ssh command that is available in current versions of Windows. Since we will not need any visible window from VirtualBox for this, such startup mode is called “headless“.
Once you set up your VM in VirtualBox (for example by using my tutorial), you could now manually set up port forwarding so that you can connect from your host to your VM, start up the VM, use an SSH client to log in and eventually shut down the machine again… Or you could use my simple batch script for this (see below). You just have to replace a few variable values (path to your VirtualBox installation, name of your VM, GuestPort and HostPort etc.) and you are ready to go.
I’m fully aware that writing a batch script for Windows is not the most trendy thing you could do, but it will work on most Windows environments including older ones and you do not have to deal with PowerShell execution policies. You could save the script for example as “start-vm.bat” and run it from your command line or by doubleclicking on it.
By default, the script will assume that your VirtualBox is installed in C:\Program Files\Oracle\VirtualBox\VBoxManage.exe, that your VM is called CentOS 8 Minimal and that you will want to connect via SSH from your local port 2222 to VM port 22. The default login user is root. All of these values can be easily changed of course. The latest version of the script can be found on GitHub.
The script checks if the VM is already running and if not, will start it up. It will also check if port forwarding is already set up- if not, it will take care of it. If the VM was not already running, the script will wait for 120 seconds, assuming that after this time the VM should be ready to accept SSH login requests. There are more elegant solutions for finding out if a VM is in a desired state, but we want to keep it simple for now.
Extension for automatic shutdown and cleanup
You can extend the script if you want so that once you close the SSH connection, the virtual machine will be automatically shut down. Moreover, the script will take care of removing the port forwarding. For this additional functionality, just paste the following code directly under the code above. A part of the shutdown logic is taken from StackOverflow with some adaptations.
If you run the complete script, it will look like this:
In the following, some tips which might come in handy when you work with the script.
Find out names of all your VMs
If you wonder what the names of your VMs are that you set up (and which you can use for the script’s “VM” variable), you can run the following command:
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" list vms
This creates an output like this:
Alternatively, you can of course also simply have a look into your VirtualBox Manager:
Set up port forwarding manually
If for some reason you do not want the script to manage your port forwarding settings, you can also do so manually via Settings > Network > Advanced (for your NAT adapter) > Port Forwarding:
Use PuTTY instead of SSH
On older Windows versions you do not have a pre-installed ssh command. In other cases you might want to load sophisticated settings to connect to your VM. In both cases, you could use PuTTY instead of ssh. The adjustment of the script is pretty easy. You need to replace the following line in the script:
ssh %LogonUserfirstname.lastname@example.org -p %HostPort%
With either this one (notice the capital letter -P instead of the lowercase -p for ssh!)…
"C:\Program Files\PuTTY\putty.exe" %LogonUseremail@example.com -P %HostPort%
… or with the following line that loads an existing PuTTY connection profile:
"C:\Program Files\PuTTY\putty.exe" -load "NameOfYourSession"
Grant firewall permissions
When you run the script for the first time, you might see a firewall prompt. For the script to work properly you would want to Allow Access: