Virtualbox Headless Command Line Hacks

By thomas, 14 August, 2019

For reasons I'm running vagrant with VirtualBox inside a docker container.  Most of the time this goes great and no problems, but when it fails it's difficult to see what's happening on the machine.  I've tried and failed to get VNC going on the vm running inside the container. I should note that my problem is with Windows VMs, with Linux VMs it's never a problem to get console. My workaround for Windows is to use screenshots and send keystrokes to the vm via vboxmanage.

First step is to get the uuid or name of the vm

List vms


$ vboxmanage list vms
"foo" {34bcbbef-ffff-4d2d-8546-031d7b597332}
"bar" {06e5696c-ffff-4c44-908e-e38aac1152fd}
"rhel76" {312f38c2-ffff-4e46-af79-6c951eeef63d}
"win2012" {4230645c-ffff-4c38-a933-a78787521ea6}
"win2019" {92d7e563-ffff-444d-afd4-242a9e24d219}

You can use either the name or the uuid to then controlvm:

Screenshot


$ vboxmanage controlvm win2019 screenshotpng win2019.png

You can then view that PNG to see what's on the screen right now. Next, you can send keyboard input to the VM using keyboardputscancode

Control-Alt-Delete on the VM


$ vboxmanage controlvm foo keyboardputscancode 1D 38 53 D3 B8 9D

Using this scancodes page to figure out what keystrokes you wish to type on the VM. The above corresponds to Keypress Ctrl, Keypress Alt, Keypress Del, Release Del, Release Alt, Release Ctl. You can use printf to print the Release codes, the release codes are the Keypress codes + 0x80, so for 1d:

$ printf '%#X\n' "$((0x80+0x1d))"
0X9D

Using the same trick we can fake a Windows Logo key press and release with "E0 5B E0 DB", so to do a "Run Command" with the Windows Logo Key:

$ vboxmanage controlvm foo keyboardputscancode E0 5B 13 E0 DB 93
$ vboxmanage controlvm foo keyboardputstring "CMD"
$ vboxmanage controlvm foo keyboardputscancode 1C 9C

This types a Windows Key + R, then releases both. I then type "CMD" and then 1C 9C is an Enter. You can also cheat above using a Ctl-J in the string, if you type CMD then Ctrl-V Ctl-J, you'll get a literal carriage return in your keyboardputstring which will be sent to the remote host.

Using this method you can "view" the screen on your vm and "type" without having a real console.

It's worth noting that VRDP should work here, but I've had no success getting that working remotely. I only have SSH access to the vsphere host running docker/vagrant. VRDP will not work without the EXTPACK installed in virtualbox as well, you need to install the EXTPACK before trying VRDP.