Skip to content

Instantly share code, notes, and snippets.

@jetfir3
Last active July 17, 2025 13:39
Show Gist options
  • Save jetfir3/e25e74a42e7c7ac2c808a537b12dc768 to your computer and use it in GitHub Desktop.
Save jetfir3/e25e74a42e7c7ac2c808a537b12dc768 to your computer and use it in GitHub Desktop.
Download VMware Workstation for Linux without a Broadcom Account
#!/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}"
@jetfir3
Copy link
Author

jetfir3 commented Mar 8, 2025

  • Run script to download without sign-up
  • Use -k to keep download file compressed, exiting after download
  • Use -v VERSION to specify the desired version (12.0.0 or higher required)

Run directly with:

bash <(curl -sSL https://gist.github.com/jetfir3/e25e74a42e7c7ac2c808a537b12dc768/raw/download_workstation.sh)

Example with arguments:

bash <(curl -sSL https://gist.github.com/jetfir3/e25e74a42e7c7ac2c808a537b12dc768/raw/download_workstation.sh) -k -v 17.0.1

@jetfir3
Copy link
Author

jetfir3 commented Jul 8, 2025

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