diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1
index 58f721c..533975f 100644
--- a/FFUDevelopment/BuildFFUVM.ps1
+++ b/FFUDevelopment/BuildFFUVM.ps1
@@ -174,6 +174,9 @@ When set to $true, will remove the FFU file from the $FFUDevelopmentPath\FFU fol
.PARAMETER RemoveUpdates
When set to $true, will remove the downloaded CU, MSRT, Defender, Edge, OneDrive, and .NET files downloaded. Default is $true.
+.PARAMETER RemoveDownloadedESD
+When set to $true, will remove downloaded Windows ESD files after they have been applied. Default is $true.
+
.PARAMETER ShareName
Name of the shared folder for FFU capture. The default is FFUCaptureShare. This share will be created with rights for the user account. When finished, the share will be removed.
@@ -426,6 +429,7 @@ param(
[bool]$CleanupDeployISO = $true,
[bool]$CleanupAppsISO = $true,
[bool]$RemoveUpdates = $true,
+ [bool]$RemoveDownloadedESD = $true,
[bool]$RemoveApps = $true,
[string]$DriversFolder,
[string]$PEDriversFolder,
@@ -2139,7 +2143,20 @@ function Get-WindowsESD {
}
$esdFilePath = $esdMetadata.LocalPath
- if (-not (Test-Path $esdFilePath)) {
+ $latestEsdFileName = $esdMetadata.FileName
+ $existingEsdMatch = $null
+
+ # Reuse an existing ESD only when it matches the latest metadata filename
+ if (-not [string]::IsNullOrWhiteSpace($latestEsdFileName)) {
+ $existingEsdMatch = Get-ChildItem -Path $PSScriptRoot -Filter *.esd -File -ErrorAction SilentlyContinue | Where-Object { $_.Name -ieq $latestEsdFileName } | Select-Object -First 1
+ }
+
+ if ($null -ne $existingEsdMatch) {
+ $esdFilePath = $existingEsdMatch.FullName
+ WriteLog "Found existing ESD matching metadata filename '$latestEsdFileName' at $esdFilePath. Skipping download."
+ }
+ else {
+ WriteLog "No existing ESD matching metadata filename '$latestEsdFileName' was found. Downloading latest ESD to $esdFilePath."
WriteLog "Downloading $($esdMetadata.FileUrl) to $esdFilePath"
$OriginalVerbosePreference = $VerbosePreference
$VerbosePreference = 'SilentlyContinue'
@@ -2149,9 +2166,6 @@ function Get-WindowsESD {
$VerbosePreference = $OriginalVerbosePreference
WriteLog "ESD download succeeded"
}
- else {
- WriteLog "Found existing ESD at $esdFilePath, skipping download"
- }
return $esdFilePath
}
@@ -4405,7 +4419,7 @@ function Get-FFUEnvironment {
}
#Run shared cleanup to avoid duplicated logic
- Invoke-FFUPostBuildCleanup -RootPath $FFUDevelopmentPath -AppsPath $AppsPath -DriversPath $DriversFolder -FFUCapturePath $FFUCaptureLocation -CaptureISOPath $CaptureISO -DeployISOPath $DeployISO -AppsISOPath $AppsISO -RemoveCaptureISO:$CleanupCaptureISO -RemoveDeployISO:$CleanupDeployISO -RemoveAppsISO:$CleanupAppsISO -RemoveDrivers:$CleanupDrivers -RemoveFFU:$RemoveFFU -RemoveApps:$RemoveApps -RemoveUpdates:$RemoveUpdates -KBPath:$KBPath
+ Invoke-FFUPostBuildCleanup -RootPath $FFUDevelopmentPath -AppsPath $AppsPath -DriversPath $DriversFolder -FFUCapturePath $FFUCaptureLocation -CaptureISOPath $CaptureISO -DeployISOPath $DeployISO -AppsISOPath $AppsISO -RemoveCaptureISO:$CleanupCaptureISO -RemoveDeployISO:$CleanupDeployISO -RemoveAppsISO:$CleanupAppsISO -RemoveDrivers:$CleanupDrivers -RemoveFFU:$RemoveFFU -RemoveApps:$RemoveApps -RemoveUpdates:$RemoveUpdates -RemoveDownloadedESD:$RemoveDownloadedESD -KBPath:$KBPath
# Remove existing Apps.iso
if (Test-Path -Path $AppsISO) {
@@ -6782,11 +6796,16 @@ try {
Dismount-DiskImage -ImagePath $ISOPath | Out-null
WriteLog 'Done'
}
- #If $wimPath is an esd file, remove it
- If ($wimPath -match '.esd') {
- WriteLog "Deleting $wimPath file"
- Remove-Item -Path $wimPath -Force
- WriteLog "$wimPath deleted"
+ # If $wimPath is an ESD file, remove it only when configured
+ If ($wimPath -match '\.esd$') {
+ if ($RemoveDownloadedESD -and (Test-Path -Path $wimPath)) {
+ WriteLog "Deleting $wimPath file"
+ Remove-Item -Path $wimPath -Force
+ WriteLog "$wimPath deleted"
+ }
+ else {
+ WriteLog "Keeping downloaded ESD file $wimPath"
+ }
}
}
@@ -6868,10 +6887,15 @@ catch {
WriteLog 'Done'
}
else {
- #Remove ESD file
- WriteLog "Deleting ESD file"
- Remove-Item -Path $wimPath -Force
- WriteLog "ESD File deleted"
+ # Remove ESD file only when configured
+ if ($RemoveDownloadedESD -and -not [string]::IsNullOrWhiteSpace($wimPath) -and ($wimPath -match '\.esd$') -and (Test-Path -Path $wimPath)) {
+ WriteLog "Deleting ESD file $wimPath"
+ Remove-Item -Path $wimPath -Force
+ WriteLog "ESD File deleted"
+ }
+ else {
+ WriteLog "Keeping downloaded ESD file $wimPath"
+ }
}
throw $_
@@ -7238,7 +7262,7 @@ If ($BuildUSBDrive) {
Set-Progress -Percentage 99 -Message "Finalizing and cleaning up..."
# Delegated post-build cleanup to common module
-Invoke-FFUPostBuildCleanup -RootPath $FFUDevelopmentPath -AppsPath $AppsPath -DriversPath $DriversFolder -FFUCapturePath $FFUCaptureLocation -CaptureISOPath $CaptureISO -DeployISOPath $DeployISO -AppsISOPath $AppsISO -RemoveCaptureISO:$CleanupCaptureISO -RemoveDeployISO:$CleanupDeployISO -RemoveAppsISO:$CleanupAppsISO -RemoveDrivers:$CleanupDrivers -RemoveFFU:$RemoveFFU -RemoveApps:$RemoveApps -RemoveUpdates:$RemoveUpdates -KBPath:$KBPath
+Invoke-FFUPostBuildCleanup -RootPath $FFUDevelopmentPath -AppsPath $AppsPath -DriversPath $DriversFolder -FFUCapturePath $FFUCaptureLocation -CaptureISOPath $CaptureISO -DeployISOPath $DeployISO -AppsISOPath $AppsISO -RemoveCaptureISO:$CleanupCaptureISO -RemoveDeployISO:$CleanupDeployISO -RemoveAppsISO:$CleanupAppsISO -RemoveDrivers:$CleanupDrivers -RemoveFFU:$RemoveFFU -RemoveApps:$RemoveApps -RemoveUpdates:$RemoveUpdates -RemoveDownloadedESD:$RemoveDownloadedESD -KBPath:$KBPath
# Remove WinGetWin32Apps.json so it is always rebuilt next run
diff --git a/FFUDevelopment/BuildFFUVM_UI.xaml b/FFUDevelopment/BuildFFUVM_UI.xaml
index cd1aa94..b12a5b6 100644
--- a/FFUDevelopment/BuildFFUVM_UI.xaml
+++ b/FFUDevelopment/BuildFFUVM_UI.xaml
@@ -837,6 +837,7 @@
+
diff --git a/FFUDevelopment/FFU.Common/FFU.Common.Cleanup.psm1 b/FFUDevelopment/FFU.Common/FFU.Common.Cleanup.psm1
index a7c191d..2a28a14 100644
--- a/FFUDevelopment/FFU.Common/FFU.Common.Cleanup.psm1
+++ b/FFUDevelopment/FFU.Common/FFU.Common.Cleanup.psm1
@@ -16,12 +16,13 @@ function Invoke-FFUPostBuildCleanup {
[bool]$RemoveDrivers = $false,
[bool]$RemoveFFU = $false,
[bool]$RemoveApps = $false,
- [bool]$RemoveUpdates = $false
+ [bool]$RemoveUpdates = $false,
+ [bool]$RemoveDownloadedESD = $false
)
$originalProgressPreference = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'
try {
- WriteLog "CommonCleanup: Starting cleanup (CaptureISO=$RemoveCaptureISO DeployISO=$RemoveDeployISO AppsISO=$RemoveAppsISO Drivers=$RemoveDrivers FFU=$RemoveFFU Apps=$RemoveApps Updates=$RemoveUpdates KBPath=$KBPath)."
+ WriteLog "CommonCleanup: Starting cleanup (CaptureISO=$RemoveCaptureISO DeployISO=$RemoveDeployISO AppsISO=$RemoveAppsISO Drivers=$RemoveDrivers FFU=$RemoveFFU Apps=$RemoveApps Updates=$RemoveUpdates RemoveDownloadedESD=$RemoveDownloadedESD KBPath=$KBPath)."
# Primary ISO paths (new naming/location)
if ($RemoveCaptureISO -and -not [string]::IsNullOrWhiteSpace($CaptureISOPath) -and (Test-Path -LiteralPath $CaptureISOPath)) {
@@ -123,6 +124,20 @@ function Invoke-FFUPostBuildCleanup {
}
}
+ # Remove downloaded ESD files from the root path when requested
+ if ($RemoveDownloadedESD -and -not [string]::IsNullOrWhiteSpace($RootPath) -and (Test-Path -LiteralPath $RootPath -PathType Container)) {
+ WriteLog "CommonCleanup: Removing downloaded ESD files in $RootPath"
+ Get-ChildItem -LiteralPath $RootPath -Filter *.esd -File -ErrorAction SilentlyContinue | ForEach-Object {
+ try {
+ WriteLog "CommonCleanup: Removing ESD $($_.FullName)"
+ Remove-Item -LiteralPath $_.FullName -Force -ErrorAction Stop
+ }
+ catch {
+ WriteLog "CommonCleanup: Failed removing ESD $($_.FullName) : $($_.Exception.Message)"
+ }
+ }
+ }
+
WriteLog "CommonCleanup: Completed."
}
catch {
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1
index b20b7e8..befaed3 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1
@@ -82,6 +82,7 @@ function Get-UIConfig {
RemoveApps = $State.Controls.chkRemoveApps.IsChecked
RemoveFFU = $State.Controls.chkRemoveFFU.IsChecked
RemoveUpdates = $State.Controls.chkRemoveUpdates.IsChecked
+ RemoveDownloadedESD = $State.Controls.chkRemoveDownloadedESD.IsChecked
ShareName = $State.Controls.txtShareName.Text
UpdateADK = $State.Controls.chkUpdateADK.IsChecked
UpdateEdge = $State.Controls.chkUpdateEdge.IsChecked
@@ -461,6 +462,7 @@ function Update-UIFromConfig {
Set-UIValue -ControlName 'chkRemoveFFU' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'RemoveFFU' -State $State
Set-UIValue -ControlName 'chkRemoveApps' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'RemoveApps' -State $State
Set-UIValue -ControlName 'chkRemoveUpdates' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'RemoveUpdates' -State $State
+ Set-UIValue -ControlName 'chkRemoveDownloadedESD' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'RemoveDownloadedESD' -State $State
# Hyper-V Settings
Select-VMSwitchFromConfig -State $State -ConfigContent $ConfigContent
@@ -908,7 +910,8 @@ function Invoke-RestoreDefaults {
-RemoveDrivers:$true `
-RemoveFFU:$true `
-RemoveApps:$true `
- -RemoveUpdates:$true
+ -RemoveUpdates:$true `
+ -RemoveDownloadedESD:$true
# Clear UI lists / state
if ($null -ne $State.Data.allDriverModels) { $State.Data.allDriverModels.Clear() }
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
index 350bfff..fc84a6c 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
@@ -135,6 +135,7 @@ function Initialize-UIControls {
$State.Controls.chkCleanupDeployISO = $window.FindName('chkCleanupDeployISO')
$State.Controls.chkCleanupDrivers = $window.FindName('chkCleanupDrivers')
$State.Controls.chkRemoveFFU = $window.FindName('chkRemoveFFU')
+ $State.Controls.chkRemoveDownloadedESD = $window.FindName('chkRemoveDownloadedESD')
$State.Controls.txtDiskSize = $window.FindName('txtDiskSize')
$State.Controls.txtMemory = $window.FindName('txtMemory')
$State.Controls.txtProcessors = $window.FindName('txtProcessors')
@@ -258,6 +259,7 @@ function Initialize-UIDefaults {
$State.Controls.chkRemoveFFU.IsChecked = $State.Defaults.generalDefaults.RemoveFFU
$State.Controls.chkRemoveApps.IsChecked = $State.Defaults.generalDefaults.RemoveApps
$State.Controls.chkRemoveUpdates.IsChecked = $State.Defaults.generalDefaults.RemoveUpdates
+ $State.Controls.chkRemoveDownloadedESD.IsChecked = $State.Defaults.generalDefaults.RemoveDownloadedESD
$State.Controls.chkVerbose.IsChecked = $State.Defaults.generalDefaults.Verbose
$State.Controls.usbSection.Visibility = if ($State.Controls.chkBuildUSBDriveEnable.IsChecked) { 'Visible' } else { 'Collapsed' }
$State.Controls.usbSelectionPanel.Visibility = if ($State.Controls.chkSelectSpecificUSBDrives.IsChecked) { 'Visible' } else { 'Collapsed' }
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1
index 72dc8b9..a01c312 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.psm1
@@ -141,6 +141,7 @@ function Get-GeneralDefaults {
RemoveFFU = $false
RemoveApps = $false
RemoveUpdates = $false
+ RemoveDownloadedESD = $true
# Hyper-V Settings Defaults
VMHostIPAddress = ""
DiskSizeGB = 50