Skip to content

Instantly share code, notes, and snippets.

@drewreece
Last active June 26, 2018 16:32
Show Gist options
  • Save drewreece/1239489 to your computer and use it in GitHub Desktop.
Save drewreece/1239489 to your computer and use it in GitHub Desktop.
Import locally defined hosts into Windows VM hosts file
#!/bin/sh
# hosts-to-vm.sh
#
# Made for use alongside the excellent ievms -
# https://github.com/xdissent/ievms
#
# Will export the local hosts (from /etc/hosts)
# to a batch script & add that batch script to a Windows VM
# The batch script will be executed to import the hosts onto the VM
# The batch file seems convoluted, until you only want to append the new hosts.
#
# REQUIREMENTS :
# VirtualBox & Guest Additions installed (v4.0 or greater) on the guest
# VirtualBox command line tools installed on the host
# Local hosts defined in /etc/hosts using 127.0.0.1 address.
# VM's setup via ievms.sh - the user listed below must be an admin on the VM.
#
# OVERVIEW :
# 1 Parse local (127.0.0.1 ONLY) hosts to a list
# 2 Create a .bat file to copy to the Windows VM disk
# 3 Loop over hosts, adding commands to batchfile.
# 4 Copy batchfile to C:\ of Administrator in the VM
# 5 Execute the batch
#
# For info on getting UAC on Windows from within batch script see
# http://www.sevenforums.com/general-discussion/12936-how-run-batch-file-admin-2.html?s=0c0b169bcd910dc62c1adc18ef279179
#
#
# USAGE:
# Call with Virtualbox VM name, or without args to see usage.
# hosts-to-vm.sh "VM - Name" [ "VM2 - Name" "VM3 - Name" ... ]
#
# To run on all
# ./hosts-to-vm.sh "IE6 - WinXP" "IE7 - WinXP" "IE8 - WinXP" "IE9 - Win7" "IE10 - Win7" "IE11 - Win7"
#
# CONFIG
###########################################################
# VM admin username
USERNAME='IEUser'
# VM admin user password
PASSWD='Passw0rd!'
# check delay when starting VM's
sleep_wait="5"
###########################################################
# The generated batch file
BATCHFILE="/tmp/hosts.bat"
# Source hosts file
HOSTS="/etc/hosts"
# Helpers
SCRIPT=`basename "$0"`
IP=`ifconfig | grep "inet " | grep -v 127.0.0.1 | cut -d\ -f2`
# Requires VM pass it as arg1
if [[ -z $1 ]]; then
echo " NAME
${SCRIPT}
USAGE
Specify at least one Virtual Machine to use.
Call the script as follows on the host
${SCRIPT} \"VM - Name\" [ \"VM2 - Name\" \"VM3 - Name\" ... ]
Edit this script if you want to avoid overwriting the Windows hosts file.
See OVERWRITE comment in get_hosts function in ${SCRIPT}
${SCRIPT} \"VM - Name\"
A hosts.bat is generated, copied to the VM and then run.
The VM will launch, the Windows Console should open & disappear.
The hosts.bat can be re-run, it will request admin priveledges via UAC
The batch file will remain in the users home directory.
UAC on Windows 7 - USER INTERACTION REQUIRED INSIDE THE VM.
Manually agree to run the hosts.bat file with admin privileges on Windows 7 VM's.
The new hosts file in Windows uses the hosts IP address,
127.0.0.1 would resolve to the VM, not the host OS.
Ensure the guest has a static IP on the primary interface or
re-run this script to overwrite the hosts file.
"
exit 0
fi
# Get local hostnames on the host machine
# batch file requires header to disable echo,
# request admin priveldges on via UAC
function get_hosts() {
HOSTLIST=`awk '/localhost/ || /broadcasthost/ || /^#/ {next}; /127.0.0.1/ {print $2}' "${HOSTS}"`
# Setup batch file
touch "${BATCHFILE}"
#### Will OVERWRITE hosts file on VM unless you remove the echo. >NUL 2>%hostspath%
cat > "${BATCHFILE}" <<"BATCHHEADER"
@echo off
net session >NUL 2>&1|| powershell Start-Process '%0' -Verb RunAs&& exit /b|| exit /b
set hostspath=%windir%\System32\drivers\etc\hosts
echo. >NUL 2>%hostspath%
BATCHHEADER
# for each host add a line to create it in our batchfile...
# echo local-IP-addr host.name >> %hostspath%
for host in "${HOSTLIST}" ; do
echo "echo ${IP} ${host} >> %hostspath%" >> "${BATCHFILE}"
done
# Add the script closure to the batch file
cat >> "${BATCHFILE}" << 'CLOSURE'
exit
CLOSURE
}
# function taken from ievms
# Pause execution until guest control is available for a virtual machine
wait_for_guestcontrol() {
while true ; do
echo "Waiting for ${1} to be available for guestcontrol..."
sleep "${sleep_wait}"
VBoxManage showvminfo "${1}" | grep 'Additions run level:' | grep -q "3" && return 0 || true
done
}
# Is it a virtual machine in VirtualBox?
is_vm() {
VBoxManage showvminfo "${1}" >/dev/null 2>&1
if [[ "$?" -ne "0" ]]; then
return 1
fi
}
get_hosts
# Quote to allow for spaces in arguments
for VM in "$@" ; do
# sanity check
is_vm "${VM}"
if [[ "$?" -eq "0" ]]; then
STATE=`VBoxManage showvminfo "${VM}" | awk '/State/ {print $2}'`
if [[ "${STATE}" != 'running' ]]; then
echo "The virtual machine ${VM} is not running ... starting it"
VBoxManage startvm "${VM}"
fi
wait_for_guestcontrol "${VM}"
# Import the batch to the VM
# Using windows back slashes fails
# Copying into user directory
# Win 7 has different path, check os version
echo "Copying ${BATCHFILE} to ${VM}"
WIN_OS_VER=$(VBoxManage showvminfo --machinereadable "${VM}" | grep "ostype=" | cut -d '=' -f2 | sed 's/\"//g' )
#echo "${WIN_OS_VER}"
if [[ ${WIN_OS_VER} == "Windows 7 (32 bit)" ]]; then
VBoxManage guestcontrol "${VM}" cp "${BATCHFILE}" "C:/Users/IEUser/hosts.bat" --username "${USERNAME}" --password "${PASSWD}" --verbose
VBoxManage guestcontrol "${VM}" exec "C:/Users/IEUser/hosts.bat" --username "${USERNAME}" --password "${PASSWD}" --verbose
echo "Check for UAC popup in taskbar in ${VM}"
fi
if [[ ${WIN_OS_VER} == "Windows XP (32 bit)" ]]; then
VBoxManage guestcontrol "${VM}" cp "${BATCHFILE}" "C:/Documents and Settings/IEUser/hosts.bat" --username "${USERNAME}" --password "${PASSWD}" --verbose
VBoxManage guestcontrol "${VM}" exec "C:/Documents and Settings/IEUser/hosts.bat" --username "${USERNAME}" --password "${PASSWD}" --verbose
fi
else
echo "ERROR ${VM} is not a virtual machine in VirtualBox... skipping."
fi
done
# Cleanup local copy
rm "${BATCHFILE}"
exit 0
@airblade
Copy link

@drewreece It works now – fantastic!

Not sure how to get notifications from comments; I assumed they happened automatically.

@drewreece
Copy link
Author

Great, thanks for the input.

I expect the notifications are off because gists don't support them or maybe I have a cheapskate free account :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment