# Runbook: Building and refreshing a Ventoy USB End-to-end procedure for taking a pile of downloaded ISOs and turning them into a categorised Ventoy boot stick. Designed to be safe to run repeatedly — adding new ISOs later is the same flow. ## Audience and assumptions - You already have a Ventoy-formatted USB drive (Ventoy installed via `Ventoy2Disk` or similar). If not, do that first at [ventoy.net](https://www.ventoy.net/) — these scripts only manage the payload, not the bootloader. - You're on Windows with PowerShell 5.1+ or PowerShell 7+. - You have all the ISOs you want to deploy in a single staging directory. ## Drive layout this runbook produces Two locations on the Ventoy USB matter: | Path on USB | What it holds | | --- | --- | | `\iso-library\\\\*.iso` | The actual ISO payload | | `\ventoy\ventoy.json` | The menu definition Ventoy reads at boot | Ventoy itself only requires that ISOs exist somewhere on the data partition. The `iso-library\` tree and the `ventoy.json` menu definition are layered on top to give a navigable boot menu. --- ## Procedure ### Step 1 — Stage the ISOs Put every ISO you want into one directory. Filenames don't need to be "clean"; the parser handles vendor-supplied names like `Win11_24H2_English_x64.iso`, `ubuntu-24.04.1-desktop-amd64.iso`, `Rocky-9.3-x86_64-minimal.iso`, etc. ```powershell # Example staging area: dir D:\iso-staging\ # Win11_24H2_English_x64.iso # ubuntu-24.04.1-desktop-amd64.iso # debian-12.5.0-amd64-netinst.iso # Rocky-9.3-x86_64-minimal.iso # clonezilla-live-3.1.2-22-amd64.iso ``` ### Step 2 — Dry-run the organiser Always start with `-DryRun` to confirm the parser inferred the right `os/version/arch` for each file. Nothing is moved. ```powershell cd D:\Projects\own\forgejo\ventoy-extras .\organise-isos.ps1 -SourceDir D:\iso-staging -DestDir D:\iso-library -DryRun ``` Output shows the planned target for every ISO. Look for anything that parsed as `unknown` or landed in a surprising slot — those are the cases to triage before committing to a move. ### Step 3 — Run the organiser for real Once the dry-run looks right: ```powershell .\organise-isos.ps1 -SourceDir D:\iso-staging -DestDir D:\iso-library ``` This **moves** (not copies) ISOs into `iso-library\\\\`. Source directory will be left empty (modulo non-ISO files). If you want copies kept, copy the staging directory aside first. ### Step 4 — Generate `ventoy.json` ```powershell .\generate-ventoy-json.ps1 -IsoRoot D:\iso-library -OutFile D:\ventoy.json ``` The script prints the menu tree it built. Skim it to confirm sensible category groupings and labels. ### Step 5 — Deploy to the USB Plug in the Ventoy USB and note its drive letter (assume `E:` below). ```powershell # Mirror the iso-library tree onto the stick. Robocopy is safest because # it handles long paths and resumes gracefully. robocopy D:\iso-library E:\iso-library /MIR /R:1 /W:1 # Drop the menu file into the ventoy\ folder on the stick. Copy-Item D:\ventoy.json E:\ventoy\ventoy.json -Force ``` `E:\ventoy\` should already exist — Ventoy creates it when it installs the bootloader. If it doesn't, the Ventoy install is incomplete. ### Step 6 — Verify the boot menu Boot a machine (or a VM with USB passthrough) from the stick. The Ventoy menu should show category submenus rather than one flat list. If categories are missing, see [Troubleshooting](#troubleshooting). --- ## Adding ISOs later You don't have to redo the whole flow. To add a single new ISO: ```powershell # Option A — let the organiser handle it .\organise-isos.ps1 -SourceDir C:\downloads -DestDir D:\iso-library .\generate-ventoy-json.ps1 -IsoRoot D:\iso-library -OutFile D:\ventoy.json robocopy D:\iso-library E:\iso-library /MIR /R:1 /W:1 Copy-Item D:\ventoy.json E:\ventoy\ventoy.json -Force # Option B — manually drop the ISO into the right tree, then just regenerate Copy-Item C:\downloads\new.iso D:\iso-library\foo\1.2\x86_64\ .\generate-ventoy-json.ps1 -IsoRoot D:\iso-library -OutFile D:\ventoy.json Copy-Item D:\ventoy.json E:\ventoy\ventoy.json -Force ``` `robocopy /MIR` will also **remove** ISOs from the stick that no longer exist in the local library — useful for retiring old versions, dangerous if your local copy is incomplete. Skip `/MIR` and use `/E` instead if you only want additive sync. --- ## Troubleshooting ### An ISO landed in `unknown\unknown\noarch\` The filename didn't match any pattern in the OS map. Fix one of: 1. Rename the ISO to start with a recognised slug (e.g. `myweirdspin-2024.iso` becomes `arch-2024-myweirdspin.iso`). 2. Add a pattern to `$osNormMap` in [`organise-isos.ps1`](../organise-isos.ps1) — the regex matches against the lowercased first token of the cleaned filename. After fixing, move the file back to staging and re-run. ### Version parsed as `unknown` Filename didn't contain a recognisable version. Either rename the file to include a `\d+\.\d+` style version, or move it manually into the right `` folder and regenerate. ### Wrong architecture detected `organise-isos.ps1` checks arch tokens in priority order (see [`docs/organise-isos.md`](organise-isos.md)). If a token in the filename collides (e.g. a date that looks like an arch), rename the file or move it manually. Common gotcha: macOS-style x64 in the version string. ### Ventoy boots but shows the old flat list `ventoy.json` is in the wrong place. It must be at the **root** of the Ventoy data partition's `ventoy\` folder, exactly: `\ventoy\ventoy.json`. Not `\ventoy\config\`, not anywhere else. ### Ventoy reports JSON parse error on boot Open `ventoy.json` in any editor and confirm it's valid JSON. The generator writes UTF-8 with no BOM, which Ventoy accepts. If you've hand-edited it, double-check for trailing commas (not valid JSON) or unbalanced brackets. ### A category I want is missing Add the slug to `$categoryMap` in [`generate-ventoy-json.ps1`](../generate-ventoy-json.ps1), then re-run. Unmapped slugs land in `Other`. ### `Access denied` when moving ISOs The source ISO is probably open in another process (mount, antivirus scan, browser download still finalising). Close it and retry. If on a removable drive, eject and reattach. --- ## Recovery ### "I ran organise-isos and now my ISOs are scattered, how do I get them back?" The organiser only moves files into `\\\\`. To collapse everything back into one directory: ```powershell Get-ChildItem -Path D:\iso-library -Recurse -Filter *.iso | Move-Item -Destination D:\iso-staging ``` Then delete the empty tree: ```powershell Get-ChildItem -Path D:\iso-library -Recurse -Directory | Where-Object { -not (Get-ChildItem $_.FullName -Recurse -File) } | Remove-Item -Recurse ``` ### "My USB is borked" These scripts don't touch the Ventoy bootloader — only the data partition content. To recover the bootloader, reinstall Ventoy with `Ventoy2Disk.exe` using the **upgrade** option (preserves the data partition) or the **install** option (wipes it). If you only modified `ventoy.json` and the boot menu now errors, just delete `\ventoy\ventoy.json` from the stick; Ventoy falls back to its default flat menu. --- ## Smoke test before deploying Want to confirm the menu before copying to a real USB? Mount the `iso-library` and `ventoy.json` into a VM with Ventoy installed, or use [VBoxVentoy](https://www.ventoy.net/en/doc_vbox.html) to boot from a VirtualBox USB device. Saves wear on physical sticks.