@@ -0,0 +1,276 @@
#! /usr/bin/env bash
# Download VMware Fusion for macOS without a Broadcom account.
#
# This script allows you to download various versions of VMware Fusion for
# different architectures by parsing available metadata and downloading from Cloudflare CDN.
#
# Only builds v8.0.0 - v13.6.3 are supported (for now)
#
# Use '-k' to keep the download file compressed, exiting after download.
BASE_URL=" https://softwareupdate-prod.broadcom.com/cds/vmw-desktop"
CDN_MIRROR=" softwareupdate-prod.broadcom.com:443:softwareupdate-prod.broadcom.com.cdn.cloudflare.net:443"
read -r -d ' ' XML_DATA << 'EOF '
<metalist>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.0.0/2985594/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.0.1/3094680/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.0.2/3164312/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.1.0/3272237/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.1.1/3771013/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.0/4352717/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.1/4543325/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.10/7527438/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.2/4635224/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.3/4696910/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.4/5115894/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.5/5192483/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.6/5234762/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.7/5528452/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.8/5824040/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>8.0.0</version><url>fusion/8.5.9/7098239/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.0.0/6665085/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.0.1/6754183/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.0/7370838/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.1/7520154/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.2/8502123/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.3/9472307/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.4/10700604/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.5/10950653/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>10.0.0</version><url>fusion/10.1.6/12989998/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.0.0</version><url>fusion/11.0.0/10120384/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.0.0</version><url>fusion/11.0.1/10738065/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.0.0</version><url>fusion/11.0.2/10952296/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.0.0</version><url>fusion/11.0.3/12992109/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.0.0</version><url>fusion/11.1.0/13668589/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.0/14634996/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.1/15018442/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.2/15794494/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.3/15870345/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.5/16269456/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.6/16696540/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>11.5.0</version><url>fusion/11.5.7/17130923/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.1.0/17195230/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.1.1/17801503/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.1.2/17964953/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.2.0/18760249/x86/core/</url></metadata>
<metadata><productid>fusion-arm64</productid><version>12.0.0</version><url>fusion/12.2.0/18760249/arm64/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.2.1/18811640/x86/core/</url></metadata>
<metadata><productid>fusion-arm64</productid><version>12.0.0</version><url>fusion/12.2.1/18811640/arm64/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.2.3/19436697/x86/core/</url></metadata>
<metadata><productid>fusion-arm64</productid><version>12.0.0</version><url>fusion/12.2.3/19436697/arm64/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.2.4/20071091/x86/core/</url></metadata>
<metadata><productid>fusion-arm64</productid><version>12.0.0</version><url>fusion/12.2.4/20071091/arm64/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>12.0.0</version><url>fusion/12.2.5/20904517/x86/core/</url></metadata>
<metadata><productid>fusion-arm64</productid><version>12.0.0</version><url>fusion/12.2.5/20904517/arm64/core/</url></metadata>
<metadata><productid>fusion-x86_64</productid><version>13.0.0</version><url>fusion/13.0.0/20802013/x86/core/</url></metadata>
<metadata><productid>fusion-arm64</productid><version>13.0.0</version><url>fusion/13.0.0/20802013/arm64/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.0.0/20802013/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.0.1/21139760/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.0.2/21581413/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.5.0/22583790/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.5.1/23298085/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.5.2/23775688/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.6.0/24238079/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.6.1/24319021/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.6.2/24409261/universal/core/</url></metadata>
<metadata><productid>fusion-universal</productid><version>13.0.0</version><url>fusion/13.6.3/24585314/universal/core/</url></metadata>
</metalist>
EOF
KEEP_COMPRESSED=false
while getopts " k" opt; do
case $opt in
k) KEEP_COMPRESSED=true ;;
* ) echo " Usage: $0 [-k]" >&2 ; exit 1 ;;
esac
done
requirements_check () {
command -v curl > /dev/null 2>&1 || { echo " Error: curl is required but not installed." >&2 ; exit 1; }
command -v grep > /dev/null 2>&1 || { echo " Error: grep is required but not installed." >&2 ; exit 1; }
command -v awk > /dev/null 2>&1 || { echo " Error: awk is required but not installed." >&2 ; exit 1; }
command -v sed > /dev/null 2>&1 || { echo " Error: sed is required but not installed." >&2 ; exit 1; }
command -v tar > /dev/null 2>&1 || { echo " Error: tar is required but not installed." >&2 ; exit 1; }
command -v sort > /dev/null 2>&1 || { echo " Error: sort is required but not installed." >&2 ; exit 1; }
}
get_product_ids () {
echo " $XML_DATA " | sed -n ' s/.*<productid>\(.*\)<\/productid>.*/\1/p' | sort -u
}
get_base_versions_for_product () {
local product_id=" $1 "
echo " $XML_DATA " | awk -v prodid=" $product_id " '
BEGIN { RS="</metadata>" }
$0 ~ "<productid>" prodid "</productid>" {
if (match($0, /<version>[^<]+<\/version>/)) {
line = $0
sub(/.*<version>/, "", line)
sub(/<\/version>.*/, "", line)
print line
}
}
' | $SORT_UNIQUE_CMD
}
get_full_versions_and_urls () {
local product_id=" $1 "
local base_version=" $2 "
echo " $XML_DATA " | awk -v prodid=" $product_id " -v basever=" $base_version " '
BEGIN { RS="</metadata>" }
($0 ~ "<productid>" prodid "</productid>") && ($0 ~ "<version>" basever "</version>") {
if (match($0, /<url>[^<]+<\/url>/)) {
line = $0
sub(/.*<url>/, "", line)
sub(/<\/url>.*/, "", line)
url_path = line
split(url_path, parts, "/")
print parts[2], url_path
}
}
' | $SORT_CMD
}
check_url () {
local url=$1
curl -s --head --connect-to " $CDN_MIRROR " " $url " | head -n 1 | grep " 200" > /dev/null
}
requirements_check
if sort --version 2> /dev/null | grep -q " GNU coreutils" ; then
SORT_CMD=" sort -V"
SORT_UNIQUE_CMD=" sort -uV"
else
SORT_CMD=" sort -t. -k1,1n -k2,2n -k3,3n -k4,4n"
SORT_UNIQUE_CMD=" sort -t. -k1,1n -k2,2n -k3,3n -k4,4n -u"
fi
IS_MACOS=false
if [[ $( uname | tr ' [:upper:]' ' [:lower:]' ) == " darwin" * ]]; then
IS_MACOS=true
macos_requirements_check
else
KEEP_COMPRESSED=true
echo " Warning: Not running on macOS. Downloaded file will be kept compressed." >&2
fi
echo " Fetching available architectures..."
products=()
while IFS= read -r line; do
products+=(" $line " )
done < <( get_product_ids)
[[ ${# products[@]} -eq 0 ]] && { echo " No product architectures found in XML data. Exiting." >&2 ; exit 1; }
PS3=" Select an architecture: "
select selected_product in " ${products[@]} " ; do
[[ -n " $selected_product " ]] && break || echo " Invalid selection. Please try again."
done
echo " Fetching available base versions for $selected_product ..."
base_versions=()
while IFS= read -r line; do
base_versions+=(" $line " )
done < <( get_base_versions_for_product " $selected_product " )
[[ ${# base_versions[@]} -eq 0 ]] && { echo " No base versions found for $selected_product . Exiting." >&2 ; exit 1; }
PS3=" Select a base version: "
select selected_base_version in " ${base_versions[@]} " ; do
[[ -n " $selected_base_version " ]] && break || echo " Invalid selection. Please try again."
done
echo " Fetching available full versions under $selected_base_version ..."
version_url_pairs=()
while IFS= read -r line; do
version_url_pairs+=(" $line " )
done < <( get_full_versions_and_urls " $selected_product " " $selected_base_version " )
[[ ${# version_url_pairs[@]} -eq 0 ]] && { echo " No full versions found for the selected criteria. Exiting." >&2 ; exit 1; }
display_versions=()
for item in " ${version_url_pairs[@]} " ; do
display_versions+=(" $( echo " $item " | awk ' {print $1}' ) " )
done
PS3=" Select a full version to download: "
select full_version_selected in " ${display_versions[@]} " ; do
if [[ -n " $full_version_selected " ]]; then
selected_pair=" ${version_url_pairs[$REPLY-1]} "
read -r VERSION URL_PATH <<< " $selected_pair"
break
else
echo " Invalid selection. Please try again."
fi
done
BUILD=$( echo " $URL_PATH " | cut -d' /' -f3)
[[ -z " $VERSION " || -z " $BUILD " || -z " $URL_PATH " ]] && { echo " Error: Could not determine version, build, or URL path. Exiting." >&2 ; exit 1; }
echo " Selected version: $VERSION "
DOWNLOAD_URL=" ${BASE_URL} /${URL_PATH} com.vmware.fusion.zip.tar"
DOWNLOAD_DIR=" ${HOME} /Downloads"
DOWNLOAD_FILE=" ${DOWNLOAD_DIR} /com.vmware.fusion-${VERSION} -${BUILD} .zip.tar"
UNZIP_DIR=" ${DOWNLOAD_DIR} /com.vmware.fusion-${VERSION} -${BUILD} "
APP_PATH=" ${UNZIP_DIR} /VMware Fusion.app"
echo " Downloading VMware Fusion v${VERSION} (${BUILD} )..."
mkdir -p " ${DOWNLOAD_DIR} "
check_url " $DOWNLOAD_URL " || { echo " Error: Installer file not found at $DOWNLOAD_URL . Please check the XML data or network connection." >&2 ; exit 1; }
curl -k -q --progress-bar -f -o " ${DOWNLOAD_FILE} " --connect-to " $CDN_MIRROR " " ${DOWNLOAD_URL} " || {
echo " Error: Download failed for ${DOWNLOAD_URL} ." >&2
exit 1
}
if ${KEEP_COMPRESSED} ; then
echo -e " \nFinished. Downloaded file location: ${DOWNLOAD_FILE} "
exit 0
fi
echo " Extracting tar..."
mkdir -p " ${UNZIP_DIR} "
tar -xf " ${DOWNLOAD_FILE} " -C " ${UNZIP_DIR} " || {
echo " Error: Extraction of tar file failed. The file may be corrupt." >&2
echo " Downloaded file location: ${DOWNLOAD_FILE} " >&2
rm -rf " ${UNZIP_DIR} "
exit 1
}
echo " Extracting zip..."
unzip -q " ${UNZIP_DIR} /com.vmware.fusion.zip" " payload/VMware Fusion.app/*" -d " ${UNZIP_DIR} " || {
echo " Error: Extraction of zip file failed. The file may be corrupt." >&2
echo " Downloaded file location: ${DOWNLOAD_FILE} " >&2
rm -rf " ${UNZIP_DIR} "
exit 1
}
echo " Cleaning up..."
mv " ${UNZIP_DIR} /payload/VMware Fusion.app" " ${APP_PATH} "
if ${IS_MACOS} ; then
xattr -dr com.apple.quarantine " ${APP_PATH} " & > /dev/null
fi
rm -rf " ${DOWNLOAD_FILE} " " ${UNZIP_DIR} /com.vmware.fusion.zip" " ${UNZIP_DIR} /descriptor.xml" " ${UNZIP_DIR} /payload" 2> /dev/null
if ${IS_MACOS} ; then
LICENSE_FILES=$( ls -1 " /Library/Preferences/VMware Fusion/license-fusion" * 2> /dev/null)
if [[ -n " ${LICENSE_FILES} " ]]; then
echo -e " \nNotice: Existing license file(s) found." >&2
echo " Deletion may be required if converting to the 'Free for Personal Use' model." >&2
echo " To remove them, run the following command(s):" >&2
for LICENSE_FILE in ${LICENSE_FILES} ; do
echo " sudo rm \" ${LICENSE_FILE} \" " >&2
done
fi
fi
echo -e " \nFinished. You can now move the app to your desired location."
echo " VMware Fusion.app location: ${APP_PATH} "