Skip to content

Instantly share code, notes, and snippets.

@root9b-zz
Last active July 8, 2022 23:34
Show Gist options
  • Save root9b-zz/65f0236128ba11a44cdb00e29e5ab81b to your computer and use it in GitHub Desktop.
Save root9b-zz/65f0236128ba11a44cdb00e29e5ab81b to your computer and use it in GitHub Desktop.
Rapidly downloads the current Windows development VM, streaming the extraction and import.
#!/bin/bash
# Streaming setup of the VirtualBox Windows Dev VM. Saves lots of time, since instead of downloading a zip, then extracting it
# to an ova, then extracting that to an actual VM, it does it all in one stream, only writing the VM to disk once.
# On a Linux host or a Windows host with WSL and feeling the YOLO?
# curl -L https://bit.ly/2m9tr7B | bash
# Or just run the commands individually, it's ain't that long.
# If you use VMWare instead of VirtualBox, try curling from https://aka.ms/windev_VM_vmware and skipping the .vbox file creation
# Compile our modded sunzip if you don't already have it. This will decompress the zip file to stdout without hitting disk.
if [ ! -f sunzip ] ; then
curl -L https://raw.githubusercontent.com/root9b/sunzip/master/sunzip.c > sunzip.c
sudo apt install libz-dev gcc -y || ( sudo apt update && sudo apt install libz-dev gcc -y )
gcc -DJUST_DEFLATE -o sunzip sunzip.c -lz
fi
# Download the VM, extracting the zip streaming and then extracting the ova streaming (which is in tar format)
curl -L https://aka.ms/windev_VM_virtualbox | ./sunzip -s | tar -xv
# Now we have the raw files; a VMDK and ovf, but VirtualBox doesn't import them directly without another copy
# so we need to create a vbox file that will work. First we get the VM name, and make up a GUID:
VMNAME=$(ls -t *.ovf | head -1 | awk -F. '{print $1}')
GUID=$(echo $(xxd -l 4 -p /dev/urandom)-$(xxd -l 2 -p /dev/urandom)-$(xxd -l 2 -p /dev/urandom)-$(xxd -l 2 -p /dev/urandom)-$(xxd -l 6 -p /dev/urandom))
DISKPATH=$(ls -t *$VMNAME*.vmdk | head -1)
# The disk UUID in the actual disk doesn't match the "Image uuid" in the ovf. We'll need to fix that for the .vbox
DISKUUID=$(head -c 2048000 "$DISKPATH" | grep -a uuid.image | head -1 | awk -F\" '{print $2}')
IMGUUID=$(grep -A1 'AttachedDevice type="HardDisk"' "$VMNAME.ovf" | grep 'Image uuid' | head -1 | awk -F\" '{print $2}')
# Now we echo out the new vbox file, including the configuration blob in the ovf:
echo '<?xml version="1.0"?><VirtualBox xmlns="http://www.virtualbox.org/" version="1.15-windows"><Machine uuid="{'"$GUID"'}" name="'"$VMNAME"'" OSType="Windows10_64" snapshotFolder="Snapshots">' > "$VMNAME.vbox"
echo '<MediaRegistry><HardDisks><HardDisk uuid="{'"$DISKUUID"'}" location="'"$DISKPATH"'" format="VMDK"/></HardDisks></MediaRegistry>' >> "$VMNAME.vbox"
LINESTART=$(grep -n ovf:Info "$VMNAME.ovf" | head -1 | awk -F: '{print $1}')
LINESTOP=$(grep -n vbox:Machine "$VMNAME.ovf" | tail -1 | awk -F: '{print $1}')
tail -n +$(( $LINESTART + 1 )) "$VMNAME.ovf" | head -n $(( $LINESTOP - $LINESTART - 1 )) | sed "s/$IMGUUID/{$DISKUUID}/" >> "$VMNAME.vbox"
echo '</Machine></VirtualBox>' >> "$VMNAME.vbox"
echo "Now double-click the .vbox file to import it, or run VBoxManage registervm $VMNAME.vbox"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment