Skip to content

Instantly share code, notes, and snippets.

@ChaosJohn
Forked from jetfir3/download_workstation.ps1
Created July 12, 2025 13:58
Show Gist options
  • Save ChaosJohn/35b81f94e78712b790d73922fcb41c13 to your computer and use it in GitHub Desktop.
Save ChaosJohn/35b81f94e78712b790d73922fcb41c13 to your computer and use it in GitHub Desktop.
Download VMware Workstation for Windows without a Broadcom Account
<#
.SYNOPSIS
Download VMware Workstation for Windows without a Broadcom Account
.DESCRIPTION
This script fetches available VMware Workstation versions from Broadcom's update servers,
allows the user to select a version in a two-step process (base, then full), and downloads
the installer using a Cloudflare CDN mirror. It then extracts the installer from the downloaded .tar archive.
.PARAMETER KeepCompressed
If specified, the script will not extract the .exe from the downloaded .tar file.
.PARAMETER Version
Specifies the version of VMware Workstation to download (e.g., "17.5.2"), bypassing the interactive prompts.
If not provided, the script will prompt the user to select from a list of available versions.
.EXAMPLE
.\download_workstation.ps1
Prompts the user to select a base version, then a full version, and then downloads and extracts it.
.EXAMPLE
.\download_workstation.ps1 -Version 17.6.3
Downloads and extracts VMware Workstation version 17.6.3 directly.
.EXAMPLE
.\download_workstation.ps1 -Version 17.5.1 -KeepCompressed
Downloads the .exe.tar file for version 17.5.1 without extracting it.
#>
param(
[switch]$KeepCompressed,
[string]$Version
)
$ErrorActionPreference = 'Stop'
$BaseUrl = "https://softwareupdate-prod.broadcom.com/cds/vmw-desktop/"
$CdnHost = "softwareupdate-prod.broadcom.com"
$CdnAlias = "softwareupdate-prod.broadcom.com.cdn.cloudflare.net"
[xml]$XmlData = @"
<metalist>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.0/4352439/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.0/7370693/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.0.2/21581411/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.2.1/18811642/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.0.1/21139696/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.6/12368378/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.5.2/15785246/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.0.0/6661328/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.4/10722678/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.7/12989993/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.1/4542065/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.2.5/20904516/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.9/7535481/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.0.0/10134415/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.7/5813279/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.1.0/17198959/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.6.0/24238078/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.6.1/24319023/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.6.2/24409262/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.6.3/24583834/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.2.3/19376536/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.0.0/16894299/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.0.4/12990004/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.2/8497320/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.0.1/3160714/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.1.0/3272444/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.1.1/3770994/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.5.5/16285975/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.0.2/10952284/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.5.0/22583795/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.4/5192485/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.5/5234757/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.2.4/20089737/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.0.1/10737736/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.0.3/12422535/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.1/7528167/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.5.1/15018445/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.5/10950780/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.1.0/13591040/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.1.1/17801498/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.5.6/16341506/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.5.0/14665864/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.8/7098237/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.6/5528349/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.0.0/2985596/windows/core/</url>
</metadata>
<metadata>
<version>15.0.0</version>
<url>ws/15.5.7/17171714/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.0.0/20800274/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.2/4638234/windows/core/</url>
</metadata>
<metadata>
<version>12.0.0</version>
<url>ws/12.5.3/5115892/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.5.2/23775571/windows/core/</url>
</metadata>
<metadata>
<version>14.0.0</version>
<url>ws/14.1.3/9474260/windows/core/</url>
</metadata>
<metadata>
<version>17.0.0</version>
<url>ws/17.5.1/23298084/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.2.0/18760230/windows/core/</url>
</metadata>
<metadata>
<version>16.0.0</version>
<url>ws/16.1.2/17966106/windows/core/</url>
</metadata>
</metalist>
"@
$availableVersions = @{}
$baseVersions = [System.Collections.Generic.List[string]]::new()
foreach ($node in $XmlData.metalist.metadata) {
if (-not $baseVersions.Contains($node.version)) {
$baseVersions.Add($node.version)
}
if ($node.url -match "ws/(\d+\.\d+\.\d+)/(\d+)/windows/core/") {
$fullVersion = $matches[1]
$buildNumber = $matches[2]
if (-not $availableVersions.ContainsKey($fullVersion)) {
$availableVersions[$fullVersion] = $buildNumber
}
}
}
if ($PSBoundParameters.ContainsKey('Version')) {
if (-not $availableVersions.ContainsKey($Version)) {
Write-Error "Version '$Version' was not found in the available metadata."
exit 1
}
$Build = $availableVersions[$Version]
}
else {
$sortedBaseVersions = $baseVersions | ForEach-Object { [System.Version]$_ } | Sort-Object -Descending | ForEach-Object { $_.ToString() }
$title = "Available Base Versions"
$message = "Please select a base product version:"
$choiceIndex = $Host.UI.PromptForChoice($title, $message, $sortedBaseVersions, 0)
$selectedBaseVersion = $sortedBaseVersions[$choiceIndex]
$majorVersion = ($selectedBaseVersion.Split('.'))[0]
$filteredFullVersions = $availableVersions.Keys | Where-Object { $_.StartsWith("$majorVersion.") } | ForEach-Object { [System.Version]$_ } | Sort-Object -Descending | ForEach-Object { $_.ToString() }
if ($filteredFullVersions.Count -eq 0) {
Write-Error "No full versions found for the selected base version '$selectedBaseVersion'."
exit 1
}
$title = "Full Versions for $selectedBaseVersion"
$message = "Please select the full version you wish to download:"
$choiceIndex = $Host.UI.PromptForChoice($title, $message, $filteredFullVersions, 0)
$Version = $filteredFullVersions[$choiceIndex]
$Build = $availableVersions[$Version]
}
Write-Host "Selected VMware Workstation $Version (Build $Build)" -ForegroundColor Green
$TarFileName = "VMware-workstation-${Version}-${Build}.exe.tar"
$ExeFileName = "VMware-workstation-${Version}-${Build}.exe"
$DownloadUrl = "${BaseUrl}ws/$Version/$Build/windows/core/$TarFileName"
$OutDir = $env:USERPROFILE + "\Downloads"
$TarOutPath = Join-Path -Path $OutDir -ChildPath $TarFileName
$ExtractDir = Join-Path -Path $OutDir -ChildPath "VMware-Workstation-$Version-$Build"
$FinalExePath = Join-Path -Path $ExtractDir -ChildPath $ExeFileName
if (-not (Test-Path -Path $OutDir)) {
New-Item -ItemType Directory -Path $OutDir -Force | Out-Null
}
try {
$cdnIPs = (Resolve-DnsName -Name $CdnAlias -Type A).IPAddress
if ($cdnIPs.Count -eq 0) {
throw "No IPs found for CDN alias."
}
}
catch {
Write-Error "Failed to resolve Cloudflare CDN hostname: $CdnAlias"
exit 1
}
Write-Host "Attempting to download from URL:"
Write-Host $DownloadUrl -ForegroundColor Cyan
$downloadSuccess = $false
foreach ($ip in $cdnIPs) {
$ResolveArg = "${CdnHost}:443:${ip}"
$CurlArgs = @(
"--progress-bar",
"--fail",
"--location",
"--output", $TarOutPath,
"--resolve", $ResolveArg,
$DownloadUrl
)
$process = Start-Process curl.exe -ArgumentList $CurlArgs -Wait -NoNewWindow -PassThru
if ($process.ExitCode -eq 0) {
$downloadSuccess = $true
Write-Host "`nDownload successful." -ForegroundColor Green
break
} else {
Write-Warning "Download failed using IP: $ip (curl exit code: $($process.ExitCode)). Trying next IP if available..."
}
}
if (-not $downloadSuccess) {
Write-Error "Download failed after trying all available CDN IPs."
exit 1
}
if ($KeepCompressed) {
Write-Host "File saved to: $TarOutPath"
exit 0
}
Write-Host "Extracting installer..."
try {
if (Test-Path -Path $ExtractDir) {
Remove-Item -Path $ExtractDir -Recurse -Force
}
New-Item -ItemType Directory -Path $ExtractDir -Force | Out-Null
tar.exe -xf $TarOutPath -C $ExtractDir
Write-Host "Extraction successful." -ForegroundColor Green
}
catch {
Write-Error "Extraction failed. Please ensure 'tar.exe' is available in your system's PATH. Error: $_"
exit 1
}
finally {
if (Test-Path -Path $TarOutPath) {
Remove-Item -Path $TarOutPath -Force
}
}
if (Test-Path -Path $FinalExePath) {
Write-Host "`nFinished." -ForegroundColor Cyan
Write-Host "Installer location: $FinalExePath"
} else {
Write-Error "Extraction seems to have completed, but the installer EXE was not found at the expected path."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment