Unsolved
1 Rookie
•
1 Message
0
43
March 15th, 2026 10:39
How to bulk detect and download new Bios to a laptop
I have 11 different Dell devices and I need to automate downloading new Bios versions to one place (we can't use the DCU app). Is there a way to automatically check and download them to my PC?
Thank you
Mirka


ejn63
10 Elder
•
30.8K Posts
0
March 15th, 2026 10:53
Not without using a third party (paid) administrative application, no.
petermuss
2 Intern
•
258 Posts
0
March 18th, 2026 12:33
@Mirka
1) create a txt file with this content: (use your 11 different machines)
Latitude 5420
Latitude 7430
OptiPlex 7090
Precision 3581
2) create a bash-script: dell_bios_from_list.sh
#!/usr/bin/env bash
set -euo pipefail
# usecase:
# ./dell_bios_from_list.sh models.txt
#
# prerequest:
# - curl
# - cabextract
# - python3
#
# Output:
# CSV to STDOUT:
# Model,BIOS_Version,ReleaseDate,DownloadURL,FileName
MODEL_LIST="${1:-models.txt}"
WORKDIR="$(mktemp -d)"
CATALOG_URL="https://downloads.dell.com/catalog/CatalogPC.cab"
cleanup() {
rm -rf "$WORKDIR"
}
trap cleanup EXIT
if [[ ! -f "$MODEL_LIST" ]]; then
echo "Error: Modell-List '$MODEL_LIST' not found." >&2
exit 1
fi
echo "Download Dell Catalog ..." >&2
curl -fsSL -o "$WORKDIR/CatalogPC.cab" "$CATALOG_URL"
echo "Unpack Catalog..." >&2
cabextract -q -d "$WORKDIR" "$WORKDIR/CatalogPC.cab" >/dev/null
XML_FILE="$(find "$WORKDIR" -maxdepth 1 -type f -iname '*.xml' | head -n1)"
if [[ -z "${XML_FILE:-}" ]]; then
echo "Error: No XML-File found in Catalog" >&2
exit 1
fi
python3 - "$MODEL_LIST" "$XML_FILE" <<'PY'
import sys
import csv
import xml.etree.ElementTree as ET
from pathlib import Path
model_file = Path(sys.argv[1])
xml_file = Path(sys.argv[2])
wanted_models = [
line.strip() for line in model_file.read_text(encoding="utf-8").splitlines()
if line.strip() and not line.strip().startswith("#")
]
tree = ET.parse(xml_file)
root = tree.getroot()
def local_name(tag):
if "}" in tag:
return tag.split("}", 1)[1]
return tag
def child_text(elem, name, default=""):
for c in elem:
if local_name(c.tag) == name:
return (c.text or "").strip()
return default
def find_first_text(elem, names):
for e in elem.iter():
if local_name(e.tag) in names and (e.text and e.text.strip()):
return e.text.strip()
return ""
def get_supported_models(component):
models = []
for e in component.iter():
if local_name(e.tag) == "Display" and e.text and e.text.strip():
# Meist gibt es viele Display-Knoten; wir sammeln nur plausible Modellnamen
text = e.text.strip()
# Grobe Filterung gegen irrelevante Display-Texte
if any(prefix in text.lower() for prefix in [
"bios", "firmware", "driver", "application"
]):
continue
models.append(text)
# Reihenfolge beibehalten, Dubletten raus
seen = set()
result = []
for m in models:
if m not in seen:
seen.add(m)
result.append(m)
return result
def is_bios_component(component):
# Dell-Kataloge enthalten BIOS-Komponenten; je nach XML-Struktur sitzt das
# in ComponentType oder als Value darunter.
ctype = child_text(component, "ComponentType", "").strip().lower()
if ctype == "bios":
return True
for e in component.iter():
if local_name(e.tag) == "ComponentType":
txt = (e.text or "").strip().lower()
if txt == "bios":
return True
if local_name(e.tag) == "Value":
txt = (e.text or "").strip().lower()
if txt == "bios":
return True
return False
rows = []
for comp in root.iter():
if local_name(comp.tag) != "SoftwareComponent":
continue
if not is_bios_component(comp):
continue
version = find_first_text(comp, {"dellVersion", "vendorVersion", "DisplayVersion"})
release_date = find_first_text(comp, {"ReleaseDate", "releaseDate", "DateTime"})
path = find_first_text(comp, {"Path", "path"})
filename = find_first_text(comp, {"FileName", "fileName"})
download_url = f"https://downloads.dell.com/{path.lstrip('/')}" if path else ""
supported_models = get_supported_models(comp)
for wanted in wanted_models:
wanted_l = wanted.lower()
for supported in supported_models:
if wanted_l == supported.lower():
rows.append([wanted, version, release_date, download_url, filename])
break
# Pro Modell nur den "besten" Treffer behalten:
# bevorzugt Einträge mit Version/Datum/URL
best = {}
for row in rows:
model = row[0]
score = sum(1 for x in row[1:] if x)
if model not in best or score > best[model][0]:
best[model] = (score, row)
writer = csv.writer(sys.stdout)
writer.writerow(["Model", "BIOS_Version", "ReleaseDate", "DownloadURL", "FileName"])
for wanted in wanted_models:
if wanted in best:
writer.writerow(best[wanted][1])
else:
writer.writerow([wanted, "NICHT_GEFUNDEN", "", "", ""])
PY
3)
use this command to run the complete script
chmod +x dell_bios_from_list.sh
./dell_bios_from_list.sh models.txt > dell_bios.csv
4)
the csv file will look like this:
Model,BIOS_Version,ReleaseDate,DownloadURL,FileName
Latitude 5420,1.30.0,2026-02-14T00:00:00,https://downloads.dell.com/.../Latitude_5420_1.30.0.exe,Latitude_5420_1.30.0.exe
OptiPlex 7090,1.25.1,2026-01-22T00:00:00,https://downloads.dell.com/.../OptiPlex_7090_1.25.1.exe,OptiPlex_7090_1.25.1.exe
HTH
Peter