Compare commits

..

3 Commits

Author SHA1 Message Date
rbalsleyMSFT a0dc5a6ae9 Cleans up README formatting and announcements
Removes transient release announcements and outdated progress notes to streamline the document. Improves overall readability by splitting paragraphs and properly formatting section headers for older content.
2026-03-09 19:16:32 -07:00
rbalsleyMSFT 6b548a34e6 Updates changelog for version 2603.1
Adds comprehensive release notes for version 2603.1. Documents the finalization of the UI preview, various servicing improvements, ESD and VHDX caching optimizations, and multiple bug fixes related to updates, driver downloads, and file cleanup mechanisms.
2026-03-09 19:14:03 -07:00
rbalsleyMSFT 8c5629c9ce Merge pull request #422 from rbalsleyMSFT/UI
Merge UI into Main
2026-03-09 17:28:16 -07:00
6 changed files with 82 additions and 1607 deletions
+62
View File
@@ -1,5 +1,67 @@
# Change Log # Change Log
# 2603.1
## What's Changed
### UI Out of Preview
The UI is finally out of preview and the code from the UI branch has been pushed to main.
### Remove old MSU files before servicing
Fixes an issue where older cumulative update MSU files were mixed with newer files. In Windows 11 24H2, dism treats all MSU files in the same folder as possible update sources, causing servicing issues.
This will primarily be an issue for those of you who use ISO files that don't have the latest updates, or those of you who create your FFUs with the ESD media shortly after patch Tuesday.
### Adds OS-scoped update KB folders
The KB folder where the CU and .NET updates downloads to will now have sub-folders for each Windows version. You may notice that if selecting 25H2, that the KB sub-folder for Windows 11 will show 24H2, this is to keep consistent with Windows 11 LTSC 2024 and Windows Server 2025, which all use the same 24H2 source OS (25H2 is just an eKB, not a full OS Swap Windows release like 24H2 was).
### .NET Updates stored under their own dedicated KB folder
This is more so to keep things clean, rather than fixing any sort of technical issue
### Reworked Windows 10 LTSB\LTSC Cumulative Update Installation
Since Windows 10 is out of support, offline servicing Windows 10 LTSC builds that are still supported fails due to extended security update requirements. The workaround to this is to install the updates in audit mode. FFU Builder now creates an Apps\LTSCUpdate folder and copies the LCU for Windows 10 LTSC builds still in support to the folder and installs the update in audit mode.
### Fixes an issue with Update ADK failing for non-English languages
Fixed a bug where updating the ADK would fail on non-English installations of Windows due to an assumption that the add/remove programs display information would be in English. Update ADK should correctly identify if the latest release of the ADK is installed and work as expected.
### Added dependency validation when selecting Build USB drive and Copy Drivers
Fixed an issue where a build would begin even though Copy Drivers to USB was set to true but no USB was inserted. FFU Builder will now check before the build gets started and inform the user if no USB drive is inserted.
### Normalizes Windows LTSC release versions to handle driver downloads
Driver downloads would fail if you were building certain LTSC releases due to FFU Builder incorrectly using the LTSC release year instead of the base Windows client version information. When build LTSC FFUs, the drivers should now download as expected.
### Scopes select-all to visible filtered list items in drivers listview
When filtering the drivers listview and selecting all driver models using the select all header checkbox, the select all behavior was selecting everything, even the hidden models in the list. If then selecting Download Selected, FFU Builder would download all models, even hidden ones. This now fixes that issue to only select all visible models and download those selected models.
### Retain downloaded ESD files
FFU Builder will now allow you to retain a downloaded ESD file. There's a new option on the Build tab to Remove Downloaded ESD File(s) which is checked by default to keep with the previous behavior. The intent here is to prevent from having to re-download the ESD file every time you're doing a build. This gives you another option along with Allow VHDX Caching to reduce the need of redownloading media.
### Reduce the size of cached VHDX files
Added some code to reduce the size of the cached VHDX files.
### Include disk size in VHDX cache validation
Prevents reusing cached images when the requested disk size changes. Ensures the disk size property is properly saved and verified against existing cache items to maintain configuration accuracy. This makes it so that if you create a new build with a larger disk size and have Allow VHDX caching selected, it won't use a cached VHDX with a smaller size.
### Enhances file backup and cleanup for cancelled builds
Improves the current-run cleanup mechanism by tracking file downloads explicitly. This ensures that files downloaded via BITS or preserving older timestamps are correctly identified and removed during cleanup. Extends the run manifest schema to support file backups, allowing for safe restoration of pre-existing scripts and configuration files modified during a run. Additional cleanup logic now correctly prunes residual empty directories after tracked files are removed.
### Fixed an issue with arm64 ESD downloads
With the change to how ESD downloads work with 25H2 and the Media Creation Tool, arm64 was broken. This was fixed.
# 2602.1 UI Preview # 2602.1 UI Preview
## What's Changed ## What's Changed
+5 -22
View File
@@ -2781,25 +2781,11 @@ function Add-BootFiles {
[string]$OsPartitionDriveLetter, [string]$OsPartitionDriveLetter,
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string]$SystemPartitionDriveLetter, [string]$SystemPartitionDriveLetter,
[Parameter(Mandatory = $true)]
[string]$AdkPath,
[Parameter(Mandatory = $true)]
[ValidateSet('x86', 'x64', 'arm64')]
[string]$WindowsArch,
[string]$FirmwareType = 'UEFI' [string]$FirmwareType = 'UEFI'
) )
# Use the ADK copy of BCDBoot so the boot binaries come from the validated ADK toolset WriteLog "Adding boot files for `"$($OsPartitionDriveLetter):\Windows`" to System partition `"$($SystemPartitionDriveLetter):`"..."
# instead of the local OS installation, which can differ based on Secure Boot servicing state. Invoke-Process bcdboot "$($OsPartitionDriveLetter):\Windows /S $($SystemPartitionDriveLetter): /F $FirmwareType" | Out-Null
$bcdBootArchitecture = if ($WindowsArch -ieq 'arm64') { 'arm64' } else { 'amd64' }
$bcdBootPath = Join-Path $AdkPath "Assessment and Deployment Kit\Deployment Tools\$bcdBootArchitecture\BCDBoot\bcdboot.exe"
if (-not (Test-Path -Path $bcdBootPath)) {
throw "ADK BCDBoot was not found at $bcdBootPath"
}
WriteLog "Adding boot files for `"$($OsPartitionDriveLetter):\Windows`" to System partition `"$($SystemPartitionDriveLetter):`" using ADK BCDBoot at `"$bcdBootPath`"..."
Invoke-Process $bcdBootPath "$($OsPartitionDriveLetter):\Windows /S $($SystemPartitionDriveLetter): /F $FirmwareType" | Out-Null
WriteLog "Done." WriteLog "Done."
} }
@@ -3428,7 +3414,6 @@ function New-PEMedia {
"en-us\WinPE-Scripting_en-us.cab", "en-us\WinPE-Scripting_en-us.cab",
"WinPE-PowerShell.cab", "WinPE-PowerShell.cab",
"en-us\WinPE-PowerShell_en-us.cab", "en-us\WinPE-PowerShell_en-us.cab",
"WinPE-SecureBootCmdlets.cab",
"WinPE-StorageWMI.cab", "WinPE-StorageWMI.cab",
"en-us\WinPE-StorageWMI_en-us.cab", "en-us\WinPE-StorageWMI_en-us.cab",
"WinPE-DismCmdlets.cab", "WinPE-DismCmdlets.cab",
@@ -5707,8 +5692,7 @@ If (Test-Path -Path "$FFUDevelopmentPath\dirty.txt") {
Get-FFUEnvironment Get-FFUEnvironment
} }
WriteLog 'Creating dirty.txt file' WriteLog 'Creating dirty.txt file'
$dirtyFilePath = Join-Path -Path $FFUDevelopmentPath -ChildPath 'dirty.txt' New-Item -Path .\ -Name "dirty.txt" -ItemType "file" | Out-Null
New-Item -Path $dirtyFilePath -ItemType "file" | Out-Null
# Early CLI prompt for additional FFUs (only if enabled and not provided) # Early CLI prompt for additional FFUs (only if enabled and not provided)
if ($BuildUSBDrive -and $CopyAdditionalFFUFiles -and ((-not $AdditionalFFUFiles) -or ($AdditionalFFUFiles.Count -eq 0))) { if ($BuildUSBDrive -and $CopyAdditionalFFUFiles -and ((-not $AdditionalFFUFiles) -or ($AdditionalFFUFiles.Count -eq 0))) {
@@ -7040,7 +7024,7 @@ try {
WriteLog 'All necessary partitions created.' WriteLog 'All necessary partitions created.'
Add-BootFiles -OsPartitionDriveLetter $osPartitionDriveLetter -SystemPartitionDriveLetter $systemPartitionDriveLetter[1] -AdkPath $adkPath -WindowsArch $WindowsArch Add-BootFiles -OsPartitionDriveLetter $osPartitionDriveLetter -SystemPartitionDriveLetter $systemPartitionDriveLetter[1]
#Add Windows packages #Add Windows packages
if ($UpdateLatestCU -or $UpdateLatestNet -or $UpdatePreviewCU ) { if ($UpdateLatestCU -or $UpdateLatestNet -or $UpdatePreviewCU ) {
@@ -7631,8 +7615,7 @@ else {
} }
#Clean up dirty.txt file #Clean up dirty.txt file
$dirtyFilePath = Join-Path -Path $FFUDevelopmentPath -ChildPath 'dirty.txt' Remove-Item -Path .\dirty.txt -Force | out-null
Remove-Item -Path $dirtyFilePath -Force | out-null
# Remove per-run session folder if present # Remove per-run session folder if present
$sessionDir = Join-Path $FFUDevelopmentPath '.session' $sessionDir = Join-Path $FFUDevelopmentPath '.session'
if (Test-Path -Path $sessionDir) { if (Test-Path -Path $sessionDir) {
-2
View File
@@ -295,7 +295,6 @@ $script:uiState.Controls.btnRun.Add_Click({
$startCleanupParams = @{ $startCleanupParams = @{
FilePath = $pwshPath FilePath = $pwshPath
ArgumentList = $cleanupArgs ArgumentList = $cleanupArgs
WorkingDirectory = $ffuDevPath
PassThru = $true PassThru = $true
} }
if ($Host.Name -eq 'ConsoleHost') { if ($Host.Name -eq 'ConsoleHost') {
@@ -458,7 +457,6 @@ $script:uiState.Controls.btnRun.Add_Click({
$startBuildParams = @{ $startBuildParams = @{
FilePath = $pwshPath FilePath = $pwshPath
ArgumentList = $pwshArgs ArgumentList = $pwshArgs
WorkingDirectory = $config.FFUDevelopmentPath
PassThru = $true PassThru = $true
} }
if ($Host.Name -eq 'ConsoleHost') { if ($Host.Name -eq 'ConsoleHost') {
-1
View File
@@ -115,7 +115,6 @@ function New-PEMedia {
"en-us\WinPE-Scripting_en-us.cab", "en-us\WinPE-Scripting_en-us.cab",
"WinPE-PowerShell.cab", "WinPE-PowerShell.cab",
"en-us\WinPE-PowerShell_en-us.cab", "en-us\WinPE-PowerShell_en-us.cab",
"WinPE-SecureBootCmdlets.cab",
"WinPE-StorageWMI.cab", "WinPE-StorageWMI.cab",
"en-us\WinPE-StorageWMI_en-us.cab", "en-us\WinPE-StorageWMI_en-us.cab",
"WinPE-DismCmdlets.cab", "WinPE-DismCmdlets.cab",
File diff suppressed because it is too large Load Diff
+4 -8
View File
@@ -1,5 +1,3 @@
**Update 2026-02-04:** [2602.1 UI Preview is now available](https://github.com/rbalsleyMSFT/FFU/releases) - click the link to get the build and check out the [Quick Start Guide](https://rbalsleymsft.github.io/FFU/quickstart.html)
# Using Full Flash Update (FFU) files to speed up Windows deployment # Using Full Flash Update (FFU) files to speed up Windows deployment
What if you could have a Windows image (Windows 10/11/Server/LTSC) that has: What if you could have a Windows image (Windows 10/11/Server/LTSC) that has:
@@ -22,14 +20,12 @@ The Full-Flash update (FFU) process can automatically download the latest releas
# Getting Started # Getting Started
If you're new, check out the [Quick Start Guide](https://rbalsleymsft.github.io/FFU/quickstart.html). This will be the fastest way to create your first FFU. There's a new [FFU Builder Quickstart Youtube video](https://youtu.be/kOIK5OmDugc) based on the 2602.1 UI Preview release. If you're new, check out the [Quick Start Guide](https://rbalsleymsft.github.io/FFU/quickstart.html).
Older Youtube Videos This will be the fastest way to create your first FFU. There's a new [FFU Builder Quickstart Youtube video](https://youtu.be/kOIK5OmDugc) based on the 2602.1 UI Preview release.
## Older Youtube Videos
[2507.1 UI Preview Video](https://www.youtube.com/watch?v=oozG1aVcg9M) - First UI Preview release video. This goes deeper than the quick start video, but is missing some features that have been added since 2507.1 was released. [2507.1 UI Preview Video](https://www.youtube.com/watch?v=oozG1aVcg9M) - First UI Preview release video. This goes deeper than the quick start video, but is missing some features that have been added since 2507.1 was released.
[2407.2 Video](https://www.youtube.com/watch?v=rqXRbgeeKSQ) - This was the main deep-dive video on FFU Builder (before it had that name). This is a good deep dive into how the BuildFFUVM.ps1 script works, but a lot has changed since that build. [2407.2 Video](https://www.youtube.com/watch?v=rqXRbgeeKSQ) - This was the main deep-dive video on FFU Builder (before it had that name). This is a good deep dive into how the BuildFFUVM.ps1 script works, but a lot has changed since that build.
# UI Progress
The UI builds are in a good spot now that most people should have moved over to using the UI if you haven't yet. I'll likely be updating main with the UI branch code within the next month or so.