Skip to content

Instantly share code, notes, and snippets.

@enkiusz
Created February 9, 2021 21:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enkiusz/f5d2f214b0581e78876cdcb270ef1016 to your computer and use it in GitHub Desktop.
Save enkiusz/f5d2f214b0581e78876cdcb270ef1016 to your computer and use it in GitHub Desktop.
This scripts is almost as broken as VMWare's download site. Except that it works.
#!/usr/bin/env python3
import requests
import sys
import re
import urllib
import os
import logging
from os.path import basename
from bs4 import BeautifulSoup
# This file is in the public domain.
# Maciej Grela <enki@fsck.pl>
#
# This scripts is almost as broken as VMWare's download site.
# Except that it works.
#
# Usage: vmware-esxi-dl.py <vmware_login> <vmware_password>
#
# Some notes:
# 0. Double check the account login and password you are using!
# I wasted almost 1h of debugging only to discover that I was
# using an old password.
#
# 1. You need to be registered for the free-esxi6 product and
# accept the EULA. This script cannot do this for you. To check
# if you are registered please go to:
# https://my.vmware.com/en/group/vmware/evalcenter?p=free-esxi6,
# select the "License and Download" panel and see if you have a
# "License Information" and "Download Packages" sections there.
# If you do you are good to go. If instead you only have a
# "Register" button you need to click it and accept the EULA.
# If it's something different then your account is borked.
#
# 2. You can't have a another session open in the browser.
# This will cause problems. If the script doesn't work and
# you're getting messages like:
# CRITICAL:vmware-esxi-dl.py:License page not found and no Register button,
# something stinks. Please try to login usign the browser, log
# out and try again. In case this doesn't help, check the file called
# 'dump.html' in the current directory. It will contain the website HTML
# from the point where the script failed. Examine it in a browser to
# try and figure out what went wrong.
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__file__)
session = requests.Session()
identity = sys.argv[1]
secret = sys.argv[2]
session.get("https://my.vmware.com/web/vmware/login")
session.post('https://my.vmware.com/oam/server/auth_cred_submit',
data={'vmware': 'login',
'username': identity,
'password': secret})
page = BeautifulSoup(session.get(
"https://my.vmware.com/en/group/vmware/evalcenter?p=free-esxi6").content,
"lxml")
license_name = "VMware vSphere Hypervisor 6 License"
# Check if we have to register for this product
if not page.find("td", string=re.compile(license_name)):
log.warn("No license found, checking for register button")
register_btn = page.find("input", id="button-download-license-register")
if register_btn is None:
log.fatal("License page not found and no Register button")
open("dump.html", "w").write(str(page))
sys.exit(1)
log.error("You need to register and accept the EULA")
license_key = page.find(
"td",
string=re.compile(license_name)
).parent.find_all("td")[1].get_text()
description = page.find(
"div",
class_="binary-description"
).get_text(strip=True)
md5 = re.search('([a-f0-9]{32})', description).group(1)
sha1 = re.search('([a-f0-9]{40})', description).group(1)
sha256 = re.search('([a-f0-9]{64})', description).group(1)
log.info("Expected MD5='%s' SHA1='%s' SHA256='%s'" % (md5, sha1, sha256))
dl_js = page.find("div", class_="downloadManager").find("button")['onclick']
dl_url = re.search(
re.compile('doDownloadAction\([\'"](.+)[\'"]\)'), dl_js
).group(1)
real_dl_url = session.get(dl_url).json()['popupurl']
filename = basename(urllib.parse.urlparse(real_dl_url).path)
# Store license key and metadata
with open(filename + ".key", 'w') as fd:
fd.write("%s\n" % (license_key))
with open(filename + ".checksum", 'w') as fd:
fd.write("MD5 (%s) = %s\n" % (filename, md5))
fd.write("SHA1 (%s) = %s\n" % (filename, sha1))
fd.write("SHA256 (%s) = %s\n" % (filename, sha256))
log.info("Downloading image to '%s'" % (filename))
file_content = session.get(real_dl_url, stream=True)
with open(filename, 'wb') as fd:
for chunk in file_content.iter_content(chunk_size=256*1024):
sys.stdout.write('+')
sys.stdout.flush()
fd.write(chunk)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment