Skip to content

feat: injectable WinPE driver framework for VMware boot-test networking (NIC injection + per-image driver manifest + guardrails) #6

Description

@DevSecNinja

Summary

Add a generic, data-driven WinPE/image driver-injection framework, first used to inject a NIC driver so the VMware boot test can get network in WinPE. Because this changes what the produced image contains, also add a per-image driver manifest (sidecar metadata file next to install.wim) plus guardrails so a VMware boot test refuses to run against an image that was not built with the required VMware drivers.

Related: #5 (24H2 ConX product-key/edition validation). Networking WinPE under VMware is a prerequisite for exercising the ConX online path outside Hyper-V.

Background / root cause (confirmed)

While validating the VMware boot test on a real VMware Workstation Pro 26 install (Win11 24H2 Pro media), WinPE never obtained a DHCP lease:

  • Guest ipconfig /all in WinPE lists no Ethernet adapter at all (only tunnel/loopback).
  • Host side is fully healthy: VMware NAT Service + VMnetDHCP running, VMnet8 up at 192.168.101.1/24, DHCP scope correctly serves 192.168.101.128–254 (gateway/DNS .2), and vmware.log shows the emulated NIC device inits and the VMnet8 link comes up (MACVNetLinkStateEventHandler ... up:1). The vmnetdhcp.leases file stayed empty across every run (no guest ever leased).
  • Cause: the Windows 11 24H2 Setup boot.wim (WinPE) has no inbox driver for any VMware emulated NIC — neither e1000 (Intel 82545EM) nor e1000e (82574L); vmxnet3 needs the VMware Tools driver, which is never inbox. So no adapter is enumerated and DHCP cannot run.
  • There is no NIC driver available locally to harvest: the VMware Tools windows.iso bundled with Workstation ships only the pvscsi storage driver as loose INF/SYS; the host driver store contains no Intel e1000-family driver (24H2 removed it).
  • By contrast, Hyper-V's synthetic NIC (netvsc) is inbox in WinPE, which is why the Hyper-V boot test gets an adapter/IP (earlier Hyper-V runs could at least ping; the issue there was DNS, not a missing adapter). This is a fundamental VMware-vs-Hyper-V WinPE difference, not a bug in our .vmx.

Conclusion: getting the VMware WinPE online requires injecting a NIC driver into boot.wim, which means a new (downloaded) driver dependency + an elevated DISM step in the ISO build.

Note: commit 5ee6975 currently sets ethernet0.virtualDev = "e1000". That alone does not fix networking (no inbox driver either way). Once injection lands, the NIC model in New-VMwareVmxConfiguration must be aligned to whichever driver is injected (e.g. vmxnet3 if we inject the VMware vmxnet3 driver, or keep e1000e/e1000 if we inject the matching Intel driver).

Goals

  1. A generic, adaptable driver-injection feature — not hard-coded to the VMware NIC; any driver can be declared and injected (data-driven, like the existing config/catalog.*.psd1 model).
  2. Inject the required VMware NIC driver into boot.wim (and optionally install.wim) so the VMware boot test networks in WinPE.
  3. A per-image metadata/manifest file written next to install.wim describing that WIM (details + exactly which drivers were injected and where).
  4. Guardrail in Invoke-QuickBootTest.ps1: when -Hypervisor VMware is used, read the image manifest and, if the image was not built with the required VMware drivers, error out with a clear, actionable message (rather than silently booting a VM that can never get network).
  5. Warning in build.ps1 when the user selects -Hypervisor VMware (i.e. the path that triggers driver injection) that the VMware driver will be injected into the produced media.

Detailed requirements

A. Generic driver-injection framework

  • Declare drivers in a data-driven config, e.g. config/drivers.psd1, mirroring the catalog schema. Suggested per-entry fields:
    • Id (e.g. driver-vmware-nic), Description, Category.
    • Target: one or more of boot.wim, install.wim (some drivers, e.g. NIC for WinPE, only need boot.wim; storage/NVMe may need both).
    • Source: local path and/or a pinned download (Url + Sha256), Renovate-managed per repo convention (# renovate: comment + custom manager). Prefer a trusted/Microsoft-or-vendor source; document licensing/redistribution (do not vendor a driver we cannot redistribute — download at build time, pinned by hash, like Fido).
    • Inf (relative INF path within the extracted driver), plus optional applicability tags (e.g. Hypervisor = 'VMware' / Profiles).
  • Injection uses dism.exe /Image:<mount> /Add-Driver /Driver:<inf> /Recurse (route via the existing Invoke-DismExe seam — Add/Remove driver cmdlets have the same PowerShell 7 "Class not registered" issue as the other DISM module cmdlets). Mounting boot.wim/install.wim requires elevation.
  • Selection is driven by the build inputs (e.g. -Hypervisor VMware pulls in the Hypervisor = 'VMware' NIC driver). Keep it extensible so future drivers (storage, GPU, etc.) can be added without code changes.

B. Per-image driver manifest (sidecar next to install.wim)

  • Write a metadata file next to install.wim (media is assembled under <WorkingDirectory>\media, WIM at media\sources\install.wim), e.g. media\sources\install.wim.manifest.json (name TBD).
  • Contents should describe the WIM and the build enough to make the guardrail (D) reliable:
    • Image details: edition/image name, build/version, architecture, language, install.wim SHA256, servicing tool versions.
    • Injected drivers: list of { Id, Description, Version, Source, Inf, Target(s) (boot.wim/install.wim) }.
    • Build identity: hypervisor the media was prepared for, timestamp, module version / pinned tooling.
  • Reuse existing provenance infrastructure where possible (New-RunReport + Export-ImageBom, docs/provenance-bom.md) rather than inventing a parallel format; the driver list can extend the RunReport/BOM and/or a lightweight sidecar the boot test can read cheaply.

C. build.ps1 warning

  • When -Hypervisor VMware is selected (the injection path), emit a clear warning during the build that the VMware NIC driver will be injected into the produced media (what driver, where from, into which WIM), so the user knows the output media differs from a stock build.

D. Invoke-QuickBootTest.ps1 guardrail

  • On -Hypervisor VMware, before starting the VM, read the image manifest (B) from the resolved media\sources.
  • If the manifest is missing or does not record the required VMware NIC driver, throw a clear error explaining the image was built without the VMware drivers and how to rebuild (e.g. build.ps1 -Hypervisor VMware), instead of booting a VM that cannot network.
  • The same check should be reusable by build.ps1 -BootTest -Hypervisor VMware / Test-ImageIntegrity / Invoke-VmBootTest.

Affected areas / files

  • config/ — new drivers.psd1 (+ schema test under tests/), Renovate wiring in renovate.json5 for any pinned driver download.
  • src/WindowsIsoMaker/Private/ImageServicing.ps1Invoke-DismExe seam for /Add-Driver; new inject helper.
  • src/WindowsIsoMaker/Private/VMwareBootTest.ps1 — align ethernet0.virtualDev in New-VMwareVmxConfiguration with the injected NIC driver.
  • Image assembly / servicing path that mounts install.wim/boot.wim (e.g. Invoke-IsoBuild, Mount-WindowsBuildImage, New-BootableIso) — hook injection + manifest write.
  • src/WindowsIsoMaker/Private/New-RunReport.ps1 / src/WindowsIsoMaker/Public/Export-ImageBom.ps1 — record injected drivers; docs/provenance-bom.md update.
  • build.ps1 — VMware injection warning.
  • scripts/Invoke-QuickBootTest.ps1 + src/WindowsIsoMaker/Public/Test-ImageIntegrity.ps1 — manifest guardrail for -Hypervisor VMware.
  • Docs: docs/usage.md / a new driver-injection doc.

Acceptance criteria

  • Drivers are declared in a data-driven config and can be extended without code changes.
  • build.ps1 -Hypervisor VMware injects the VMware NIC driver into boot.wim, warns the user it is doing so, and records it in the per-image manifest next to install.wim.
  • A VMware boot test against such media yields a WinPE adapter with a DHCP lease (guest ipconfig /all shows an IPv4 in 192.168.101.0/24; a lease appears in vmnetdhcp.leases).
  • Invoke-QuickBootTest.ps1 -Hypervisor VMware against media built without the VMware drivers throws a clear, actionable error and does not start a VM.
  • Injection is generic enough to add a second (non-VMware) driver purely via config, proven by a test.
  • Unit tests cover: driver config schema, injection seam (mocked dism.exe), manifest read/write, and the QuickBoot guardrail. Full Pester suite green; PSScriptAnalyzer clean.

Open questions

  • Driver source & licensing: VMware vmxnet3 (extract from VMware Tools windows.iso setup packages — no download but fragile) vs. Intel e1000e/e1000 (download + hash-pin). Which is redistributable / preferred?
  • Manifest format: extend RunReport/Image BOM vs. a dedicated lightweight sidecar the boot test reads.
  • Do we inject into install.wim too (benefits real-hardware/other-VM installs) or boot.wim only (minimum needed for the boot test)?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions