Convert W7 ISO to USB key

http://github.com/abock/win7-usb/blob/master/win7-iso-to-usb.sh

Linux script to convert the Windows 7 ISO to a USB key for easier and faster installation of

 
#!/usr/bin/env bash
#
# win7-iso-to-usb.sh
# Written by Aaron Bockover <aaron@abock.org>
# Copyright 2009 Aaron Bockover
# Licensed under the MIT/X11 license
#
 
function usage {
echo "Written by Aaron Bockover <aaron@abock.org>."
echo "Copyright 2009 Aaron Bockover"
echo "Licensed under the MIT/X11 license"
echo
echo "Usage: $0 ISO [TARGET DEVICE]"
echo
echo " ISO Path to the Windows 7 ISO file"
echo
echo " TARGET DEVICE Target USB block device node. This argument"
echo " is optional if devkit-disks is installed."
echo
echo " Omitting this argument will present a list"
echo " of available target USB block devices."
echo
}
 
function check-program {
full_path="$(which "$1" 2>/dev/null)"
if ! test -x "$full_path"; then
usage
echo "You must have $1 installed and in your PATH."
exit 1
fi
}
 
function dk-enum-device-files {
devkit-disks --dump | grep device-file: | cut -f2 -d:
}
 
function dk-get-device-field {
devkit-disks --show-info $1 | awk -F: '/'"$2"':[ ]*/{
sub (/^[ ]*/, "", $2);
sub (/[ ]*$/, "", $2);
print $2
}'
}
 
function dk-compare-device-field {
test "$(dk-get-device-field $1 "$2")" $3 "$4"
}
 
function dk-id-for-device-file {
devkit-disks --show-info $1 | head -n1 | awk -F' ' '{print $NF}'
}
 
function select-target-device {
declare -a devices=()
device_count=0
 
echo Select a target USB device:
echo
 
for device in $(dk-enum-device-files); do
if dk-compare-device-field $device removable -eq 1 && \
dk-compare-device-field $device interface = usb; then
 
devkit_id=$(dk-id-for-device-file $device)
display_name=$(dk-get-device-field $device model)
 
echo " 1) $display_name [$device]"
 
devices[$device_count]="$device:"
for child_device in $(dk-enum-device-files); do
if dk-compare-device-field $child_device \
"part of" = $devkit_id && \
dk-compare-device-field $child_device "is mounted" -eq 1; then
mount_path=$(dk-get-device-field $child_device "mount paths")
devices[$device_count]="${devices[$device_count]}$child_device "
echo " $child_device mounted at $mount_path"
fi
done
 
let device_count++
fi
done
 
if test $device_count -eq 0; then
echo " No available devices"
exit 0
fi
 
echo ; read -p "Device number (1): " device_index ; echo
test -z $device_index && device_index=1
let device_index--
if test $device_index -lt 0 || test $device_index -ge $device_count; then
echo Invalid device selection.
exit 1
fi
 
device="${devices[$device_index]}"
device_file="$(echo "$device" | cut -f1 -d:)"
device_mounts="$(echo "$device" | cut -f2 -d:)"
 
if ! test -z "$device_mounts"; then
echo "Device $device_file has mounted partitions."
read -p "Unmount all partitions on $device_file? [Y/N]: " unmount_device
case "$unmount_device" in
Y|y) ;;
N|n) echo "Cannot continue with mounted partitions."; exit 1 ;;
*) echo "Invalid choice."; exit 1 ;;
esac
for mount in $device_mounts; do
echo "Unmounting $mount..."
if ! umount $mount; then
echo "Failed to unmount $mount"
exit 1
fi
done
fi
}
 
if test $# -le 0; then
usage
exit 1
fi
 
if test $UID -ne 0; then
usage
echo "You must be root to run this tool."
exit 1
fi
 
check-program ntfs-3g
check-program sfdisk
check-program mount
check-program umount
check-program mkntfs
 
iso_path="$1"
if ! test -f "$iso_path"; then
usage
echo "You must specify a path to the Windows 7 ISO."
exit 1
fi
 
if test -e "$2"; then
device_file=$2
else
if test -x $(which devkit-disks 2>/dev/null); then
select-target-device
else
usage
echo You do not have devkit-disks installed. Without this tool
echo the target device must be specified as the second argument
echo to this script.
echo
echo Ensure there are no mounted partitions on the device first.
echo
exit 1
fi
fi
 
## Windows 7 Installation ##
 
read -p "WARNING: All data on $device_file will be DESTROYED. Continue? [Y/N]: " destroy_device
case "$destroy_device" in
Y|y) ;;
N|n) echo "Quitting. $device_file has not been touched."; exit 1 ;;
*) echo "Invalid choice."; exit 1 ;;
esac
echo
 
# Create mount points for later use
win7_iso_mount=$(mktemp -d /tmp/win7-iso.XXXX)
win7_usb_mount=$(mktemp -d /tmp/win7-usb.XXXX)
if ! test -d "$win7_iso_mount" || ! test -d "$win7_usb_mount"; then
echo "Could not create mount directories."
exit 1
fi
 
# From here on we will just bail if something fails
set -e
 
# Partition the USB key with a bootable NTFS
# partition that consumes the entire disk
echo "Creating partitions on $device_file..."
sfdisk $device_file &>/dev/null <<EOF
,,7,*
;
EOF
 
device_ntfs_partition=$(sfdisk -l $device_file | grep '^'"$device_file" \
| head -n1 | cut -f1 -d' ')
 
echo " NTFS data partition = $device_ntfs_partition"
 
# Format the data partition with NTFS
echo "Formatting $device_ntfs_partition as NTFS..."
mkntfs --fast -L WIN7SETUP $device_ntfs_partition
 
# Mount the NTFS partition
echo "Mounting $device_ntfs_partition using ntfs-3g at $win7_usb_mount..."
mount -t ntfs-3g $device_ntfs_partition "$win7_usb_mount"
 
# Mount the UDF ISO
echo "Mounting $iso_path using udf at $win7_iso_mount..."
mount -t udf -o loop,ro "$iso_path" "$win7_iso_mount"
 
# Copy the ISO contents to the USB NTFS partition
echo "Copying $iso_path contents to the USB stick. This may take some time..."
cp -a "$win7_iso_mount"/* "$win7_usb_mount"
 
# Rename bootmgr to NTLDR since that's what the MBR loads
echo "Renaming bootmgr to NTLDR..."
mv "$win7_usb_mount/bootmgr" "$win7_usb_mount/NTLDR"
 
echo "Syncing filesystems and umounting..."
sync
umount "$win7_iso_mount"
rmdir "$win7_iso_mount"
umount "$win7_usb_mount"
rmdir "$win7_usb_mount"
 
# Install the Windows 7 MBR code
echo "Installing Windows 7 MBR to $device_file..."
 
WIN7_MBR_CODE="
33c0 8ed0 bc00 7c8e c08e d8be 007c bf00 06b9 0002 fcf3 a450 681c 06cb fbb9 0400
bdbe 0780 7e00 007c 0b0f 850e 0183 c510 e2f1 cd18 8856 0055 c646 1105 c646 1000
b441 bbaa 55cd 135d 720f 81fb 55aa 7509 f7c1 0100 7403 fe46 1066 6080 7e10 0074
2666 6800 0000 0066 ff76 0868 0000 6800 7c68 0100 6810 00b4 428a 5600 8bf4 cd13
9f83 c410 9eeb 14b8 0102 bb00 7c8a 5600 8a76 018a 4e02 8a6e 03cd 1366 6173 1cfe
4e11 750c 807e 0080 0f84 8a00 b280 eb84 5532 e48a 5600 cd13 5deb 9e81 3efe 7d55
aa75 6eff 7600 e88d 0075 17fa b0d1 e664 e883 00b0 dfe6 60e8 7c00 b0ff e664 e875
00fb b800 bbcd 1a66 23c0 753b 6681 fb54 4350 4175 3281 f902 0172 2c66 6807 bb00
0066 6800 0200 0066 6808 0000 0066 5366 5366 5566 6800 0000 0066 6800 7c00 0066
6168 0000 07cd 1a5a 32f6 ea00 7c00 00cd 18a0 b707 eb08 a0b6 07eb 03a0 b507 32e4
0500 078b f0ac 3c00 7409 bb07 00b4 0ecd 10eb f2f4 ebfd 2bc9 e464 eb00 2402 e0f8
2402 c349 6e76 616c 6964 2070 6172 7469 7469 6f6e 2074 6162 6c65 0045 7272 6f72
206c 6f61 6469 6e67 206f 7065 7261 7469 6e67 2073 7973 7465 6d00 4d69 7373 696e
6720 6f70 6572 6174 696e 6720 7379 7374 656d 0000 0063 7b9a"
 
echo -n -e $(echo "$WIN7_MBR_CODE" | tr -d '[:space:]' | sed 's/../\\x&/g') \
| dd of=$device_file conv=notrunc &>/dev/null
 
sync
 
echo Done.