Last active
July 17, 2025 13:39
-
-
Save jetfir3/e25e74a42e7c7ac2c808a537b12dc768 to your computer and use it in GitHub Desktop.
Download VMware Workstation for Linux without a Broadcom Account
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# Download VMware Workstation for Linux without a Broadcom account | |
# | |
# Use '-k' to keep the download file compressed, exiting after download. | |
# Use '-v <Version>' to specify desired version (12.0.0 or higher required). | |
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> | |
<version>12.0.0</version> | |
<url>ws/12.5.0/4352439/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.0/7370693/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.0.2/21581411/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.2.1/18811642/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.0.1/21139696/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.6/12368378/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.5.2/15785246/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.0.0/6661328/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</url> | |
<url>ws/14.1.4/10722678/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.7/12989993/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.1/4542065/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.2.5/20904516/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.9/7535481/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.0.0/10134415/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.7/5813279/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.1.0/17198959/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.6.0/24238078/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.6.1/24319023/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.6.2/24409262/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.6.3/24583834/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.2.3/19376536/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.0.0/16894299/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.0.4/12990004/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.2/8497320/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.0.1/3160714/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.1.0/3272444/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.1.1/3770994/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.5.5/16285975/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.0.2/10952284/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.5.0/22583795/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.4/5192485/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.5/5234757/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.2.4/20089737/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.0.1/10737736/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.0.3/12422535/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.1/7528167/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.5.1/15018445/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.5/10950780/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.1.0/13591040/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.1.1/17801498/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.5.6/16341506/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.5.0/14665864/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.8/7098237/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.6/5528349/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.0.0/2985596/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>15.0.0</version> | |
<url>ws/15.5.7/17171714/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.0.0/20800274/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.2/4638234/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>12.0.0</version> | |
<url>ws/12.5.3/5115892/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.5.2/23775571/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>14.0.0</version> | |
<url>ws/14.1.3/9474260/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>17.0.0</version> | |
<url>ws/17.5.1/23298084/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.2.0/18760230/linux/core/</url> | |
</metadata> | |
<metadata> | |
<version>16.0.0</version> | |
<url>ws/16.1.2/17966106/linux/core/</url> | |
</metadata> | |
</metalist> | |
EOF | |
KEEP_COMPRESSED=false | |
USER_VERSION="" | |
VERSION="" | |
BUILD="" | |
while getopts "kv:" opt; do | |
case $opt in | |
k) KEEP_COMPRESSED=true ;; | |
v) USER_VERSION=$OPTARG ;; | |
*) echo "Usage: $0 [-k] [-v VERSION]" >&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; } | |
} | |
requirements_check | |
if [[ $(uname | tr '[:upper:]' '[:lower:]') != "linux"* ]]; then | |
KEEP_COMPRESSED=true | |
echo "Warning: Not running on Linux. Keeping file compressed." >&2 | |
fi | |
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 | |
version_gte() { | |
printf '%s\n%s\n' "$1" "$2" | eval "$SORT_CMD" | head -n 1 | grep -q "^$2$" | |
} | |
get_base_versions() { | |
echo "$XML_DATA" | awk ' | |
BEGIN {FS="[<>]"} | |
/<version>/ { | |
if ($3 ~ /^[0-9]+\.0\.0$/) { | |
print $3; | |
} | |
}' | eval "$SORT_UNIQUE_CMD" | |
} | |
get_full_versions_and_builds() { | |
local selected_base_major="$1" | |
local major_version_prefix=$(echo "$selected_base_major" | cut -d'.' -f1) | |
echo "$XML_DATA" | awk -v target_major="$major_version_prefix" ' | |
BEGIN { | |
in_metadata = 0; | |
current_version_tag = ""; | |
} | |
/<metadata>/ { in_metadata = 1; current_version_tag = ""; } | |
/<\/metadata>/ { in_metadata = 0; } | |
in_metadata && /<version>/ { | |
current_version_tag = $0; | |
gsub(/.*<version>|<\/version>.*/, "", current_version_tag); | |
} | |
in_metadata && /<url>/ { | |
url_tag=$0; | |
gsub(/.*<url>ws\/|<\/url>.*/, "", url_tag); | |
split(url_tag, parts, "/"); | |
if (current_version_tag == target_major ".0.0" && parts[1] ~ "^" target_major "\\..*") { | |
print parts[1], parts[2]; | |
} | |
}' | eval "$SORT_UNIQUE_CMD" | |
} | |
get_specific_version_and_build() { | |
local target_version="$1" | |
local target_major_prefix=$(echo "$target_version" | cut -d'.' -f1) | |
echo "$XML_DATA" | awk -v target_ver="$target_version" -v target_major_prefix_awk="$target_major_prefix" ' | |
BEGIN { | |
FS="[<>]"; | |
current_version_tag_content = ""; | |
} | |
/<metadata>/ { current_version_tag_content = ""; } | |
/<version>/ { current_version_tag_content = $3; } | |
/<url>/ { | |
if (current_version_tag_content == target_major_prefix_awk ".0.0") { | |
split($3, url_parts, "/"); | |
full_version = url_parts[2]; | |
build_number = url_parts[3]; | |
if (full_version == target_ver) { | |
print full_version, build_number; | |
exit; | |
} | |
} | |
}' | |
} | |
check_url() { | |
local url=$1 | |
curl -s --head --connect-to "$CDN_MIRROR" "$url" | head -n 1 | grep "200" >/dev/null | |
} | |
if [[ -n "$USER_VERSION" ]]; then | |
version_gte "${USER_VERSION}" "12.0.0" || { echo "Error: Specified version ${USER_VERSION} is not supported. Workstation 12.0.0 or higher is required." >&2; exit 1; } | |
read -r VERSION BUILD <<< "$(get_specific_version_and_build "$USER_VERSION")" | |
[[ -z "$VERSION" || -z "$BUILD" ]] && { echo "Error: Version ${USER_VERSION} not found in the embedded XML data or URL format is unexpected." >&2; exit 1; } | |
else | |
echo "Available base versions:" | |
base_versions_array=() | |
while IFS= read -r line; do | |
base_versions_array+=("$line") | |
done < <(get_base_versions) | |
[[ ${#base_versions_array[@]} -eq 0 ]] && { echo "No base versions found in XML data. Exiting." >&2; exit 1; } | |
PS3="Select a base version: " | |
select base_version_selected in "${base_versions_array[@]}"; do | |
[[ -n "$base_version_selected" ]] && break || echo "Invalid selection. Please try again." | |
done | |
echo "Available full versions for base version $base_version_selected:" | |
full_versions_builds_array=() | |
while IFS= read -r line; do | |
full_versions_builds_array+=("$line") | |
done < <(get_full_versions_and_builds "$base_version_selected") | |
[[ ${#full_versions_builds_array[@]} -eq 0 ]] && { echo "No full versions found for base version $base_version_selected. Exiting." >&2; exit 1; } | |
declare -a display_full_versions | |
for item in "${full_versions_builds_array[@]}"; do | |
display_full_versions+=("$(echo "$item" | awk '{print $1}')") | |
done | |
IFS=$'\n' sorted_display_full_versions=($(printf "%s\n" "${display_full_versions[@]}" | eval "$SORT_CMD")) | |
unset IFS | |
PS3="Select a full version: " | |
select full_version_selected in "${sorted_display_full_versions[@]}"; do | |
[[ -n "$full_version_selected" ]] && break || echo "Invalid selection. Please try again." | |
done | |
for item in "${full_versions_builds_array[@]}"; do | |
read -r ver build_num <<< "$item" | |
[[ "$ver" == "$full_version_selected" ]] && { BUILD="$build_num"; break; } | |
done | |
[[ -z "$BUILD" ]] && { echo "Error: Could not find build number for version '$full_version_selected'. This can happen if selection is invalid." >&2; exit 1; } | |
VERSION="$full_version_selected" | |
fi | |
echo "Selected version: $VERSION with build: $BUILD" | |
DOWNLOAD_URL="${BASE_URL}ws/${VERSION}/${BUILD}/linux/core/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle.tar" | |
DOWNLOAD_DIR="${HOME}" | |
DOWNLOAD_FILE="${DOWNLOAD_DIR}/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle.tar" | |
EXTRACT_DIR="${DOWNLOAD_DIR}/VMware-Workstation-${VERSION}-${BUILD}" | |
BUNDLE_PATH="${EXTRACT_DIR}/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle" | |
echo "Downloading VMware Workstation v${VERSION} (${BUILD})..." | |
mkdir -p "${DOWNLOAD_DIR}" | |
check_url "$DOWNLOAD_URL" || { echo "Error: Installer file not found at $DOWNLOAD_URL even via CDN. Please check the version/build or XML data." >&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 | |
} | |
${KEEP_COMPRESSED} && { echo -e "\nFinished. Downloaded file location: ${DOWNLOAD_FILE}"; exit 0; } | |
echo "Extracting tar..." | |
mkdir -p "${EXTRACT_DIR}" && \ | |
tar -xf "${DOWNLOAD_FILE}" -C "${EXTRACT_DIR}" || { | |
echo "Error: Extraction of tar file failed and may be corrupt." >&2 | |
echo "Downloaded file location: ${DOWNLOAD_FILE}" >&2 | |
rm -rf "${EXTRACT_DIR}" | |
exit 1 | |
} | |
echo "Cleaning up..." | |
chmod +x "${EXTRACT_DIR}/VMware-Workstation-${VERSION}-${BUILD}.x86_64.bundle" | |
rm -rf "${DOWNLOAD_FILE}" "${EXTRACT_DIR}/descriptor.xml" 2>/dev/null | |
echo -e "\nFinished. You can now run the installer bundle.\nVMware Workstation bundle location: ${BUNDLE_PATH}" |
Supports all Linux Workstation builds 12.0.0 - 17.6.3 (as of July 2025).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-k
to keep download file compressed, exiting after download-v VERSION
to specify the desired version (12.0.0 or higher required)Run directly with:
Example with arguments: