ventoy-extras/docs/generate-ventoy-json.md
Laurence Horrocks-Barlow 74b210a702 Add README, runbook, per-script docs, CHANGELOG and LICENSE.
Documents the organise-isos and generate-ventoy-json workflow end-to-end:
quick start in the README, full procedure with troubleshooting and recovery
in docs/RUNBOOK.md, and reference docs for each script covering parameters,
parsing rules, category groupings, and extensibility. Ships a YOLO licence
(no warranty) and seeds CHANGELOG.md for the v0.1.0 release.
2026-05-21 10:33:10 +01:00

4.9 KiB

generate-ventoy-json.ps1

Walks an iso-library directory tree and emits a ventoy.json with per-category submenus. Output is UTF-8, no BOM, ready to drop into \ventoy\ventoy.json on the Ventoy USB.

Parameters

Parameter Default Description
-IsoRoot .\iso-library Root of the ISO tree to scan (recursively, for *.iso).
-OutFile .\ventoy.json Where to write the generated JSON.
-VentoyDrive E Cosmetic — currently unused at runtime; kept for forward compat.

Expected input tree

<IsoRoot>\
  <os-slug>\
    <version>\
      <arch>\
        *.iso

This is exactly what organise-isos.ps1 produces. Files that don't fit this layout still get included, but with a best-effort fallback:

  • 3 path segments deep → arch defaults to noarch.
  • < 3 segments → os and version both default to unknown.

Output structure

Each top-level entry in ventoy.json is a category submenu, containing one entry per ISO:

{
  "menu_alias": [
    {
      "name": "Ubuntu Family",
      "image": [
        { "image": "/ubuntu/24.04/x86_64/ubuntu-24.04.1-desktop-amd64.iso",
          "menu_alias": "Ubuntu 24.04 [x86_64]" },
        { "image": "/lubuntu/24.04/x86_64/lubuntu-24.04-desktop-amd64.iso",
          "menu_alias": "Lubuntu 24.04 [x86_64]" }
      ]
    },
    {
      "name": "Rescue & Tools",
      "image": [
        { "image": "/clonezilla/3.1/x86_64/clonezilla-live-3.1.2-22-amd64.iso",
          "menu_alias": "Clonezilla 3.1 [x86_64]" }
      ]
    }
  ]
}

Menu labels

For each ISO, the label is built as:

<display name> <version>[ [<arch>]]

Where:

  • <display name> is looked up in $displayNames (e.g. ubuntuUbuntu, proxmox-veProxmox VE). Unmapped slugs are title-cased as a fallback.
  • The arch suffix [<arch>] is omitted when arch is noarch.

Examples: Ubuntu 24.04 [x86_64], Proxmox VE 8.2, Memtest86+ 6.20 [x86_64].

Category groupings

Slugs are mapped to category names via $categoryMap:

Category Slugs included
Windows windows, windows-server, ms-dos, reactos
RHEL Family rhel, centos, rocky, almalinux, oraclelinux, scientific, eurolinux, navylinux
Fedora Family fedora, qubes, coreos
SUSE Family opensuse*, sles, geckolinux
Debian Family debian, raspios, armbian, devuan, mx, antix, deepin, pureos, grml, lmde
Ubuntu Family ubuntu*, lubuntu, kubuntu, xubuntu, linuxmint, pop_os, elementary, zorin
Arch Family arch, manjaro, endeavouros, garuda, artix, cachyos, arcolinux
Gentoo Family gentoo, funtoo, calculate
Slackware Family slackware, salix, porteus
Independent Linux void, nixos, alpine, solus, clearlinux, flatcar
Security kali, parrot, backbox, tails, whonix, blackarch
Network & Firewall pfsense, opnsense, ipfire, vyos, openwrt, ddwrt
Virtualisation proxmox-*, esxi, vsphere, xcp-ng, xenserver, harvester
BSD Family freebsd, openbsd, netbsd, dragonflybsd, truenas*, ghostbsd
Solaris & illumos openindiana, omnios, smartos, solaris
Media libreelec, osmc
Exotic haiku, freedos, reactos
Rescue & Tools clonezilla, systemrescue, gparted, memtest, memtest86, rescuezilla, hirens, winpe, dban, ubcd, vendor rescue disks
Other anything unmapped — sorted alphabetically at the end

Matching is exact-first, then prefix. So opensuse-leap matches the exact opensuse-leap entry if present, otherwise falls through to the opensuse prefix.

Category order in the output menu is fixed (see $categoryOrder in the script). Unlisted categories — including any new ones you add — append alphabetically after the predefined order.

Adding a category

Edit generate-ventoy-json.ps1:

$categoryMap = [ordered]@{
    # ...existing...
    'mycoolos' = 'Hobbyist OSes'   # new category name appears as-is in the menu
}

# Optional — place it explicitly in the menu order:
$categoryOrder = @(
    'Windows',
    # ...
    'Hobbyist OSes',
    # ...
)

Output details

  • Encoding: UTF-8 without BOM. Ventoy accepts this.
  • Indentation: ConvertTo-Json -Depth 10 default formatting.
  • Path separators: forward slashes, leading /. Ventoy paths are rooted at the Ventoy data partition root, not at filesystem root.

Exit codes

  • 0 — always. The script prints to stderr but does not exit non-zero on parsing edge cases; "unknown" categories are silently bucketed into Other.

Idempotency

Pure function of the directory tree. Re-running over the same tree always produces byte-identical output (modulo line endings if you edited the script). Safe to run on every Ventoy refresh.