├── .gitignore ├── README.markdown └── msie2vbox.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Introduction 2 | msie2vbox creates VirtualBox machines from the Microsoft Application Compatibility VPC images that Microsoft provide for testing websites in Internet Explorer versions 6, 7 or 8. This application only supports downloading and installing the Windows XP VPC image. This image defaults to IE6 but contains shortcuts to update to IE7 or IE8. It is recommended that a local copy of the downloaded VPC image be kept to make creating subsequent VirtualBox VMs quicker. 3 | 4 | To run msie2vbox, just execute in a shell. 5 | 6 | >`./msie2vbox.sh` 7 | 8 | ## Dependencies 9 | * [VirtualBox](http://www.virtualbox.org/) 10 | * [7-Zip](http://www.7-zip.org/download.html) (Available in most package managers as "p7zip") 11 | * [curl](http://curl.haxx.se/) 12 | * [mkisofs](http://freshmeat.net/projects/mkisofs/) 13 | 14 | ## Options 15 | This program can be used to create a new VirtualBox machine from a Microsoft 16 | Application Compatibility VPC image. Since the original Microsoft images 17 | are built for Microsoft Virtual PC, there are a few 'inconsistencies'*. At present, 18 | this script only supports IE 6,7,8 under Windows XP. 19 | 20 | The VMs can be installed to a specific location supplied by the '-l ' arguement 21 | or by default to ~/vbox/. The VM will be named based on the current timestamp, 22 | e.g. 'Windows_XP_IE_$(date +%s)', or by the name supplied by the '-n ' arguement. 23 | 24 | Each VM will default to 192M RAM; this can be overridden with the '-mN' arguement where 25 | 'N' is the desired amount of RAM to allocate, in megabytes. This program will 26 | download the appropriate VPC image, but you can specify the path to a local VPC image 27 | using the '-f ' arguement. 28 | 29 | The VMs require the Intel 82540EM network adapter. Drivers for this are downloaded and 30 | built into a ready-mounted ISO when the VM is booted. You will need to manually 31 | update the network adapter drivers before verifying your VM with Microsoft. 32 | 33 | By default, the VM will not boot when this script is complete. Use the '-b' arguement 34 | to boot the VM. 35 | 36 | >Usage: msie2vbox.sh [-h] [-mN] [-nName] [-f path] [-d path] [-l path] -b 37 | > 38 | >OPTIONS: 39 | > -h Show this message 40 | > -m RAM to allocate (in MB) 41 | > -n Name of the Virtual Machine 42 | > -f Path to existing VPC image 43 | > -d Path to Intel Drivers EXE 44 | > -l Path to store VHD files 45 | > -b Boot VM on completion. 46 | 47 | 48 | ## Examples 49 | ### IE 7 50 | * IE 7 51 | * Existing local copy of Intel drivers in /home/max/Desktop/PROWin32.exe 52 | * Default 192Mb RAM 53 | * Default name of Windows_XP_IE_$(date +%s) 54 | * Download the VPC image 55 | 56 | >`./msie2vbox.sh -d /home/max/Desktop/PROWin32.exe` 57 | 58 | After installation, you will need to use the desktop shortcut to update the machine to IE7. 59 | 60 | ### IE8 61 | * IE8 62 | * Use 265Mb RAM 63 | * Name of 'WinXPIE8' 64 | * Boot on completion 65 | * Specify path to existing VPC executable 66 | * Download Intel Drivers 67 | 68 | >`./msie2vbox -m 256 -f /path/to/Windows_XP_IE6.exe -n WinXPIE8 -b` 69 | 70 | After installation, you will need to use the desktop shortcut to update the machine to IE8. 71 | 72 | After booting the VM for the first time, you will be prompted to activate Windows XP. Cancel the activation 73 | for now, and log in using the password 'Password1'. Open Device Manager, right-click on the ethernet adapter and 74 | selected 'Reinstall Driver'. Search for the driver automatically, and it should install the drivers from the 75 | attached CD image. 76 | 77 | You should next install the VirtualBox Guest Additions. Once the installation is complete, you can reboot the VM 78 | and complete the activiation process; this should work okay. I've noticed that occasionally installation of the Guest 79 | Additions causes the machine to appear to crash. You can powercycle the VM, activate Windows XP, and generally 80 | the second attempt at installing the Guest Additions works fine. 81 | 82 | ## *Inconsistencies / Manual Steps 83 | * The VM is configured without USB support 84 | * The VM is configured without audio 85 | * Update the drivers for the ethernet device with those provided on the pre-mounted D:\ drive 86 | * Validate the VM with Microsoft 87 | * Install the Virtual Box Guest Additions 88 | * Disable 'battery' devices 89 | 90 | ## To Do 91 | * Investigate use of registry files or other some alternative method to automate driver installation 92 | * Automated installation of Vbox Guest Additions 93 | 94 | ## License 95 | This program is free software: you can redistribute it and/or modify 96 | it under the terms of the GNU General Public License as published by 97 | the Free Software Foundation, either version 3 of the License, or 98 | (at your option) any later version. 99 | 100 | This program is distributed in the hope that it will be useful, 101 | but WITHOUT ANY WARRANTY; without even the implied warranty of 102 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 103 | GNU General Public License for more details. 104 | 105 | You should have received a copy of the GNU General Public License 106 | along with this program. If not, see . 107 | 108 | -------------------------------------------------------------------------------- /msie2vbox.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Max Manders 4 | # max@maxmanders.co.uk 5 | # http://maxmanders.co.uk 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | # 20 | 21 | SCRIPT_NAME=$(basename $0) 22 | DIR_NAME=$(dirname $0) 23 | TMP_DIR="/tmp/${SCRIPT_NAME}.$$.tmp" 24 | INTEL_URL="http://downloadmirror.intel.com/18717/eng/PROWin32.exe" 25 | INTEL_ISO="${TMP_DIR}/INTEL_DRIVERS.ISO" 26 | INTEL_DIR="${TMP_DIR}/INTEL_DRIVERS" 27 | DOWNLOAD_URL="http://download.microsoft.com/download/B/7/2/B72085AE-0F04-4C6F-9182-BF1EE90F5273/Windows_XP_IE6.exe" 28 | 29 | cd ${DIR_NAME} 30 | 31 | mkdir -p ${TMP_DIR} 32 | 33 | # The path to a local IE VPC image. 34 | VPC_PATH="" 35 | # The path to the extracted VHD image. 36 | VHD_IMAGE="" 37 | # RAM to allocate to the VM 38 | RAM="192" 39 | # Name to give to the VM. 40 | VM_NAME="" 41 | # Path to Intel Drivers. 42 | INTEL_PATH="" 43 | # Path to store downloaded images 44 | VM_LOC="${HOME}/ievpc" 45 | # Whether to auto boot the VM 46 | AUTO_BOOT=0 47 | # Rate limit curl 48 | RATE_LIMIT="" 49 | # Directory to Create Virtualbox VM 50 | VM_STORE="" 51 | 52 | ## Functions ################################################################## 53 | usage() { 54 | 55 | cat << EOF 56 | This program can be used to create a new VirtualBox machine from a Microsoft 57 | Application Compatibility VPC image. Since the original Microsoft images 58 | are built for Microsoft Virtual PC, there are a few 'inconsistencies'*. 59 | 60 | The VMs can be installed to a specific location supplied by the '-l ' argument 61 | or by default to ~/vbox/. 62 | 63 | Each VM will default to 192M RAM; this can be overridden with the '-mN' argument where 64 | 'N' is the desired amount of RAM to allocate, in megabytes. This program will 65 | download the appropriate VPC image, but you can specify the path to a local VPC image 66 | using the '-f ' arguement. This latter option is more practical once an initial 67 | image has been downloaded to save time and bandwidth. 68 | 69 | The VMs require the Intel 82540EM network adapter. Drivers for this are downloaded and 70 | built into a ready-mounted ISO when the VM is booted. You will need to manually 71 | update the network adapter drivers before verifying your VM with Microsoft. 72 | 73 | By default, the VM will not boot when this script is complete. Use the '-b' arguement 74 | to boot the VM. 75 | 76 | Usage: ${SCRIPT_NAME} [-h] [-mN] [-nName] [-f path] [-d path] [-l path] -b 77 | 78 | OPTIONS: 79 | -h Show this message 80 | -m RAM to allocate (in MB) 81 | -n Name of the Virtual Machine 82 | -f Path to existing VPC image 83 | -d Path to Intel Drivers EXE 84 | -l Path to store VHD files 85 | -b Boot VM on completion. 86 | EOF 87 | } 88 | 89 | clean_and_exit() { 90 | 91 | rm -fr ${TMP_DIR} 92 | exit 1; 93 | } 94 | 95 | 96 | get_image() { 97 | 98 | # If we haven't been given the path to a local VPC executable, then we download the 99 | # appropriate image from the web. 100 | if [ -z ${VPC_PATH} ]; then 101 | echo "Downloading VPC image..." 102 | 103 | # Create download target directory if it doesn't already exist, the default is 104 | # ~/ievpc/ 105 | mkdir -p ${VM_LOC} 106 | 107 | # Destination full pathname for VPC executable download. 108 | VPC_PATH="${VM_LOC}/Windows_XP_IE6" 109 | 110 | if [ -n "${RATE_LIMIT}" ]; then 111 | curl --verbose -L ${DOWNLOAD_URL} --limit-rate=${RATE_LIMIT} -o ${VPC_PATH} 112 | else 113 | curl --verbose -L ${DOWNLOAD_URL} -o ${VPC_PATH} 114 | fi 115 | fi 116 | 117 | # Get the filename of the VHD disk image that will be extracted from the VPC executable. 118 | VHD_IMAGE_NAME=`7z l -slt ${VPC_PATH} | egrep --color=never "^Path = [^.]*\.vhd$" | sed -e 's/Path = \(.*\)$/\1/'` 119 | 120 | echo "VHD image from exe is called ${VHD_IMAGE_NAME}" 121 | 122 | # Extract the VHD disk image from the VPC executable and store in the same directory 123 | # as the downloaded VPC executable. 124 | echo "Extracting VHD file ${VHD_IMAGE_NAME}..." 125 | 7z x ${VPC_PATH} -o${VM_LOC}/ -y >/dev/null 2>&1 126 | 127 | VHD_IMAGE="${VM_LOC}/${VHD_IMAGE_NAME}" 128 | } 129 | 130 | 131 | prepare_intel_drivers() { 132 | 133 | echo "Preparing Intel drivers..." 134 | 135 | # If we've installed a VM before using the script, the INTEL_DRIVERS.ISO 136 | # might already exist in the VM directory. 137 | if [ ! -f "${VM_LOC}/INTEL_DRIVERS/INTEL_DRIVERS.ISO" ]; then 138 | # If we haven't specified a local path, we need to retrieve the 139 | # drivers from the web. 140 | if [ -z ${INTEL_PATH} ]; then 141 | echo "Downloading Intel drivers..." 142 | if [ -n "${RATE_LIMIT}" ]; then 143 | curl --verbose -L ${INTEL_URL} --limit-rate=${RATE_LIMIT} -o "/tmp/PROWin32.exe" 144 | else 145 | curl --verbose -L ${INTEL_URL} -o "/tmp/PROWin32.exe" 146 | fi 147 | else 148 | cp ${INTEL_PATH} ${TMP_DIR}/ 149 | fi 150 | 151 | mkdir -p ${INTEL_DIR} 152 | echo "Extracting Intel drivers from PROWin32.exe." 153 | 7z x ${TMP_DIR}"/PROWin32.exe" -o${INTEL_DIR} -y > /dev/null 2>&1 154 | mkisofs -o ${INTEL_ISO} ${INTEL_DIR} > /dev/null 2>&1 155 | mkdir -p "${VM_LOC}/INTEL_DRIVERS" 156 | cp ${INTEL_ISO} "${VM_LOC}/INTEL_DRIVERS/" 157 | else 158 | echo "Intel drivers already present in ${VM_LOC}..." 159 | fi 160 | } 161 | 162 | 163 | prepare_vm() { 164 | 165 | # If we haven't passed in a name, create one based on the current timestamp. 166 | if [ -z "${VM_NAME}" ]; then 167 | VM_NAME="Windows_XP_IE_$(date +%s)" 168 | echo "No VM name given, setting name as ${VM_NAME}." 169 | fi 170 | 171 | # If we havem't passed in an installation directory, then default to 172 | # ~/vbox/. 173 | if [ -z ${VM_STORE} ]; then 174 | VM_STORE="${HOME}/vbox" 175 | echo "No VM location given, setting location as ${VM_STORE}." 176 | fi 177 | 178 | # Delete and unregister any existing VM with the same name. 179 | if [ -d "${VM_STORE}/${VM_NAME}" ]; then 180 | echo "A VM with the given name already exists." 181 | while true; do 182 | read -p "Continue, replacing this VM?[y/n]" ans 183 | case ${ans} in 184 | [Yy]* ) 185 | is_vm_registered=$(vboxmanage list vms | grep --color=never ${VM_NAME}) 186 | 187 | if [ -n "${is_vm_registered}" ]; then 188 | vboxmanage storagectl ${VM_NAME} --name="IDEController" --controller="PIIX4" --remove 189 | vboxmanage unregistervm ${VM_NAME} --delete 190 | fi 191 | 192 | rm -fr ${VM_STORE}/${VM_NAME} 193 | break 194 | ;; 195 | [Nn]* ) 196 | clean_and_exit 197 | break 198 | ;; 199 | * ) 200 | echo "Please answer 'Y' or 'N'." 201 | ;; 202 | esac 203 | done 204 | fi 205 | 206 | mkdir -p "${VM_STORE}/${VM_NAME}" 207 | mv "${VHD_IMAGE}" "${VM_STORE}/${VM_NAME}/" 208 | VHD_IMAGE="${VM_STORE}/${VM_NAME}/${VHD_IMAGE_NAME}" 209 | mkdir -p "${VM_STORE}/INTEL_DRIVERS" 210 | 211 | # We need to make a mountable image containing the VM Intel drivers. 212 | prepare_intel_drivers 213 | 214 | # Name and register an empty Windows XP VM. 215 | echo "Creating and registering VM..." 216 | vboxmanage createvm --name ${VM_NAME} --ostype WindowsXP --register 217 | 218 | # Create the IDE controller. 219 | echo "Creating and attaching IDE controller..." 220 | vboxmanage storagectl ${VM_NAME} --name "IDEController" --add ide --controller PIIX4 221 | 222 | # Set a new/unique UUID for this disk. 223 | echo "Resetting UUID for VM..." 224 | vboxmanage internalcommands sethduuid "${VHD_IMAGE}" 225 | 226 | # Clone VHD to VDI and attach 227 | # See http://forums.virtualbox.org/viewtopic.php?f=2&t=43940#p197795 228 | echo "Attaching VHD/VDI to IDE controller..." 229 | vboxmanage clonehd "${VHD_IMAGE}" "${VM_STORE}/${VM_NAME}/${VM_NAME}.vdi" --format=VDI 230 | rm -f ${VHD_IMAGE} 231 | VHD_IMAGE=${VM_STORE}/${VM_NAME}/${VM_NAME}.vdi 232 | vboxmanage storageattach ${VM_NAME} --storagectl IDEController --port 0 --device 0 --type hdd --medium "${VHD_IMAGE}" 233 | 234 | # Attach the ISO. 235 | echo "Attaching Intel Drivers ISO..." 236 | vboxmanage storageattach ${VM_NAME} --storagectl IDEController --port 0 --device 1 --type dvddrive --medium "${VM_LOC}/INTEL_DRIVERS/INTEL_DRIVERS.ISO" 237 | 238 | # Set boot priorities. 239 | echo "Configuring boot priorities..." 240 | vboxmanage modifyvm ${VM_NAME} --boot1 disk --boot2 none --boot3 none --boot4 none 241 | 242 | # Set other hardware. 243 | echo "Configuring VM hardware..." 244 | vboxmanage modifyvm ${VM_NAME} --vram 32 --memory ${RAM} --nic1 nat --nictype1 82540EM --cableconnected1 on --audio none --usb off 245 | } 246 | 247 | 248 | check_dependencies() { 249 | 250 | echo "Checking Dependencies..." 251 | 252 | is_vbox_installed=$(which vboxmanage) 253 | if [ -z ${is_vbox_installed} ]; then 254 | echo "ERROR: Missing: VirtualBox not installed." 255 | exit 1 256 | fi 257 | 258 | is_7zip_installed=$(which 7z) 259 | if [ -z ${is_7zip_installed} ]; then 260 | echo "ERROR: Missing: 7-Zip not installed." 261 | exit 1 262 | fi 263 | 264 | is_curl_installed=$(which curl) 265 | if [ -z ${is_curl_installed} ]; then 266 | echo "ERROR: Missing: curl not installed." 267 | exit 1 268 | fi 269 | 270 | is_mkisofs_installed=$(which mkisofs) 271 | if [ -z ${is_mkisofs_installed} ]; then 272 | echo "ERROR: Missing: mkisofs not installed." 273 | exit 1 274 | fi 275 | } 276 | 277 | 278 | main() { 279 | 280 | ## Make sure we have all the required packages. 281 | check_dependencies 282 | ## Download an Windows XP image from MS if necessary. 283 | get_image 284 | ## Prepare and configure the VM. 285 | prepare_vm 286 | 287 | ## Start VM if appropriate option set. 288 | if [ "${AUTO_BOOT}" -eq "1" ]; then 289 | echo "Launching VM..." 290 | vboxmanage startvm "${VM_NAME}" 291 | fi 292 | 293 | clean_and_exit 294 | } 295 | 296 | 297 | # Process command line args. 298 | while getopts "hbv:m:n:f:d:l:r:" OPTION; do 299 | case ${OPTION} in 300 | h) 301 | usage 302 | exit 303 | ;; 304 | m) 305 | RAM=${OPTARG} 306 | ;; 307 | n) 308 | VM_NAME=${OPTARG} 309 | ;; 310 | f) 311 | VPC_PATH=${OPTARG} 312 | ;; 313 | d) 314 | INTEL_PATH=${OPTARG} 315 | ;; 316 | l) 317 | VM_STORE=${OPTARG} 318 | ;; 319 | b) 320 | AUTO_BOOT=1 321 | ;; 322 | r) 323 | RATE_LIMIT=${OPTARG} 324 | ;; 325 | esac 326 | done 327 | 328 | trap clean_and_exit INT TERM EXIT 329 | 330 | # Run main() 331 | main 332 | 333 | --------------------------------------------------------------------------------