Skip to content

Add -BootFirst to New-OSDCloudUSB so the Data partition can be extended later - #384

Open
kristofferkhansen wants to merge 1 commit into
OSDeploy:masterfrom
kristofferkhansen:feature/osdcloudusb-bootfirst
Open

Add -BootFirst to New-OSDCloudUSB so the Data partition can be extended later#384
kristofferkhansen wants to merge 1 commit into
OSDeploy:masterfrom
kristofferkhansen:feature/osdcloudusb-bootfirst

Conversation

@kristofferkhansen

@kristofferkhansen kristofferkhansen commented Aug 17, 2026

Copy link
Copy Markdown

Problem

New-OSDCloudUSB always creates the Data (NTFS) partition first and the Boot/WinPE (FAT32) partition second with -UseMaximumSize, which lands Boot in whatever free space trails Data - i.e. the end of the disk. Windows can only extend a partition into contiguous free space that follows it, so with Boot occupying the tail, Data can never be extended - including after cloning the same built image onto a larger USB drive, a common way to distribute a single OSDCloud USB build across drives of different sizes.

Fix

  • New-BootableUSBDrive (Public/Functions/Disk.ps1): add a -BootFirst switch (default off, matching current behavior). When set, creates the fixed 2GB Boot partition first and lets Data take -UseMaximumSize of whatever's left, so Data ends up last on the disk and can be extended into any trailing free space.
  • New-OSDCloudUSB (Public/OSDCloud/OSDCloudUSB.ps1): add the same -BootFirst switch, passed through to New-BootableUSBDrive. Its WinPE/Data partition lookups depended on a hardcoded creation order (WinPE=partition 2, Data=partition 1), so they're now derived from -BootFirst instead of hardcoded.

Default behavior is unchanged; this is purely opt-in.

Test plan

  • Parser.ParseFile on both changed files - no syntax errors
  • Partition-number branch logic verified for both -BootFirst states (returns WinPE=1/Data=2 when set, WinPE=2/Data=1 default - matches current behavior when unset)
  • Real USB creation with -BootFirst on Windows (not verified in this environment - New-Partition/Format-Volume/Clear-Disk are Windows Storage-module cmdlets unavailable here)

…xtended later

New-BootableUSBDrive always created the Data (NTFS) partition first and
the Boot/WinPE (FAT32) partition second with -UseMaximumSize, which
lands Boot in whatever free space trails Data - i.e. the end of the
disk. Windows can only extend a partition into contiguous free space
that follows it, so with Boot occupying the tail, Data can never be
extended - including after cloning the same image onto a larger USB
drive, a common way to distribute a single built OSDCloud USB image
across drives of different sizes.

Add a -BootFirst switch (default off, matching current behavior) to
New-BootableUSBDrive that creates the fixed 2GB Boot partition first
and lets Data take -UseMaximumSize of whatever's left, so Data ends
up last on the disk and can be extended into any trailing free space.

New-OSDCloudUSB gets the same -BootFirst switch, passed through to
New-BootableUSBDrive. Its WinPE/Data partition lookups depended on a
hardcoded creation order (WinPE=partition 2, Data=partition 1), so
they're now derived from -BootFirst instead of hardcoded.
@OSDeploy

Copy link
Copy Markdown
Owner

So the use case is the ability to clone to a larger USB?
The use case for the current partition layout is:

  1. FAT32 (partition 2) tends to corrup easily whereas NTFS (partition 1) does not. Current layout allows easily formatting the boot partition without harming the data partition.
  2. Boot partition (partition 2) has increased in size from when I originally made this function. If there is a need to make the Boot partition larger, Data partition (partition 1) can be shrunk, allowing for a larger Boot partition.

Just wanted you to be aware of reasons. I'll run some tests, but if a change is required, multiple layout options may be preferred.

  1. DataBoot (current)
  2. BootData (proposed)
  3. BootOnly (new)

Thoughts?

@kristofferkhansen

Copy link
Copy Markdown
Author

Thanks for the context and for testing!

Use case: yes, exactly — we build one master stick and clone it sector-level (imageUSB/dd) onto a batch of mixed-size drives. Windows can only extend a partition into free space that follows it, so with Boot at the tail the cloned Data partition can never grow; with Boot first it's a single diskpart extend / Resize-Partition after cloning. (extend/shrink semantics)

On 1 (FAT32): reformatting Boot without touching Data works the same in either layout — a format only writes within that partition's own extent, wherever it sits. And in practice the FAT32 partition sees almost no writes after creation (Update-OSDCloudUSB only copies files to it) while the NTFS partition absorbs all the heavy WIM/driver traffic, so I don't think corruption exposure changes with position.

On 2 (growing Boot): agreed — that's the real tradeoff. DataBoot keeps Boot growable (shrink Data, recreate Boot); BootData makes Data growable instead. Since Boot is a fixed 2GB against a ~1GB WinPE payload while Data is what varies between stick sizes, we valued Data-growability — which is exactly why it's opt-in and DataBoot stays the default.

Two data points I found while double-checking myself: Microsoft's ADK guidance for a multipartition WinPE USB also creates the FAT32 boot partition first, and Ventoy documents legacy-BIOS machines failing to read boot files at the tail of large sticks — Boot-first sidesteps that on ≥128GB drives.

On layout options: happy to rework the switch into -PartitionLayout DataBoot|BootData|BootOnly if you'd prefer that shape — it's a small delta on this PR since the partition lookups are already parameterized. One thought on BootOnly: very useful for pure network deployments, but it has its own caveats (FAT32 format cap at 32GB, 4GB max file size so no offline WIMs), so it might fit better as a follow-up PR. Glad to update this one either way — your call.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants