diff --git a/FFUDevelopment/BuildFFUVM_UI.ps1 b/FFUDevelopment/BuildFFUVM_UI.ps1
index 6f2c462..f2503d6 100644
--- a/FFUDevelopment/BuildFFUVM_UI.ps1
+++ b/FFUDevelopment/BuildFFUVM_UI.ps1
@@ -46,7 +46,8 @@ $script:uiState = [PSCustomObject]@{
logStreamReader = $null;
pollTimer = $null;
currentBuildProcess = $null;
- lastConfigFilePath = $null
+ lastConfigFilePath = $null;
+ loadedDeviceNamingMode = $null
};
Flags = @{
installAppsForcedByUpdates = $false;
@@ -56,7 +57,9 @@ $script:uiState = [PSCustomObject]@{
lastSortAscending = $true;
isBuilding = $false;
isCleanupRunning = $false;
- isFluentSupported = $false
+ isFluentSupported = $false;
+ deviceNamingModeWasExplicitlyChanged = $false;
+ suppressDeviceNamingChangeTracking = $false
};
Defaults = @{};
LogFilePath = "$FFUDevelopmentPath\FFUDevelopment_UI.log"
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1
index f9e24de..a7a5d6d 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Config.psm1
@@ -36,7 +36,7 @@ function Get-UIConfig {
UseDriversAsPEDrivers = $State.Controls.chkUseDriversAsPEDrivers.IsChecked
CopyPPKG = $State.Controls.chkCopyPPKG.IsChecked
CopyUnattend = $State.Controls.chkCopyUnattend.IsChecked
- DeviceNamingMode = Get-SelectedDeviceNamingMode -State $State
+ DeviceNamingMode = Get-ConfiguredDeviceNamingMode -State $State
DeviceNameTemplate = $State.Controls.txtDeviceNameTemplate.Text
DeviceNamePrefixesPath = $State.Controls.txtDeviceNamePrefixesPath.Text
DeviceNamePrefixes = @(Get-DeviceNamePrefixes -State $State)
@@ -480,17 +480,20 @@ function Update-UIFromConfig {
$State.Controls.txtDeviceNamePrefixesPath.Text = Get-DefaultDeviceNamePrefixesPath -FFUDevelopmentPath $State.Controls.txtFFUDevPath.Text
}
- $deviceNamingMode = 'None'
+ $loadedDeviceNamingMode = $null
if ($ConfigContent.PSObject.Properties.Name -contains 'DeviceNamingMode') {
- $deviceNamingMode = [string]$ConfigContent.DeviceNamingMode
+ $candidateDeviceNamingMode = [string]$ConfigContent.DeviceNamingMode
+ if ($candidateDeviceNamingMode -in @('Legacy', 'None', 'Prompt', 'Template', 'Prefixes')) {
+ $loadedDeviceNamingMode = $candidateDeviceNamingMode
+ }
}
- if ($deviceNamingMode -eq 'Legacy') {
- $deviceNamingMode = 'Prompt'
+ $displayDeviceNamingMode = if ($loadedDeviceNamingMode -in @('Prompt', 'Template', 'Prefixes')) {
+ $loadedDeviceNamingMode
}
- if ($deviceNamingMode -notin @('None', 'Prompt', 'Template', 'Prefixes')) {
- $deviceNamingMode = 'None'
+ else {
+ 'None'
}
- Set-DeviceNamingMode -State $State -Mode $deviceNamingMode
+ Set-DeviceNamingModeState -State $State -DisplayMode $displayDeviceNamingMode -LoadedMode $loadedDeviceNamingMode
Import-DeviceNamePrefixesFromConfiguredPath -State $State
Update-DeviceNamingControls -State $State
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1
index 37a0c96..6b86f6f 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Handlers.psm1
@@ -58,6 +58,55 @@ function Set-DeviceNamingMode {
$State.Controls.rbDeviceNamingPrefixes.IsChecked = $Mode -eq 'Prefixes'
}
+function Set-DeviceNamingModeState {
+ param(
+ [PSCustomObject]$State,
+ [ValidateSet('None', 'Prompt', 'Template', 'Prefixes')]
+ [string]$DisplayMode,
+ [AllowNull()]
+ [string]$LoadedMode
+ )
+
+ if ($null -eq $State.Flags) {
+ $State.Flags = @{}
+ }
+
+ if ($null -eq $State.Data) {
+ $State.Data = @{}
+ }
+
+ $previousSuppressionState = $true -eq $State.Flags.suppressDeviceNamingChangeTracking
+ $State.Flags.suppressDeviceNamingChangeTracking = $true
+ try {
+ Set-DeviceNamingMode -State $State -Mode $DisplayMode
+ }
+ finally {
+ $State.Flags.suppressDeviceNamingChangeTracking = $previousSuppressionState
+ }
+
+ $State.Data.loadedDeviceNamingMode = if ([string]::IsNullOrWhiteSpace($LoadedMode)) {
+ $null
+ }
+ else {
+ $LoadedMode.Trim()
+ }
+ $State.Flags.deviceNamingModeWasExplicitlyChanged = $false
+}
+
+function Get-ConfiguredDeviceNamingMode {
+ param([PSCustomObject]$State)
+
+ if (($null -ne $State.Flags) -and ($true -eq $State.Flags.deviceNamingModeWasExplicitlyChanged)) {
+ return Get-SelectedDeviceNamingMode -State $State
+ }
+
+ if (($null -ne $State.Data) -and -not [string]::IsNullOrWhiteSpace([string]$State.Data.loadedDeviceNamingMode)) {
+ return [string]$State.Data.loadedDeviceNamingMode
+ }
+
+ return $null
+}
+
function Get-DeviceNamePrefixes {
param([PSCustomObject]$State)
@@ -467,17 +516,32 @@ function Register-EventHandlers {
$State.Controls.rbDeviceNamingNone.Add_Checked({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
- Update-DeviceNamingControls -State $window.Tag
+ $localState = $window.Tag
+ if (-not ($true -eq $localState.Flags.suppressDeviceNamingChangeTracking)) {
+ $localState.Flags.deviceNamingModeWasExplicitlyChanged = $true
+ $localState.Data.loadedDeviceNamingMode = $null
+ }
+ Update-DeviceNamingControls -State $localState
})
$State.Controls.rbDeviceNamingPrompt.Add_Checked({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
- Update-DeviceNamingControls -State $window.Tag
+ $localState = $window.Tag
+ if (-not ($true -eq $localState.Flags.suppressDeviceNamingChangeTracking)) {
+ $localState.Flags.deviceNamingModeWasExplicitlyChanged = $true
+ $localState.Data.loadedDeviceNamingMode = $null
+ }
+ Update-DeviceNamingControls -State $localState
})
$State.Controls.rbDeviceNamingTemplate.Add_Checked({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
- Update-DeviceNamingControls -State $window.Tag
+ $localState = $window.Tag
+ if (-not ($true -eq $localState.Flags.suppressDeviceNamingChangeTracking)) {
+ $localState.Flags.deviceNamingModeWasExplicitlyChanged = $true
+ $localState.Data.loadedDeviceNamingMode = $null
+ }
+ Update-DeviceNamingControls -State $localState
})
$State.Controls.txtDeviceNameTemplate.Add_TextChanged({
param($eventSource, $textChangedEventArgs)
@@ -489,7 +553,12 @@ function Register-EventHandlers {
$State.Controls.rbDeviceNamingPrefixes.Add_Checked({
param($eventSource, $routedEventArgs)
$window = [System.Windows.Window]::GetWindow($eventSource)
- Update-DeviceNamingControls -State $window.Tag
+ $localState = $window.Tag
+ if (-not ($true -eq $localState.Flags.suppressDeviceNamingChangeTracking)) {
+ $localState.Flags.deviceNamingModeWasExplicitlyChanged = $true
+ $localState.Data.loadedDeviceNamingMode = $null
+ }
+ Update-DeviceNamingControls -State $localState
})
$State.Controls.btnBrowseDeviceNamePrefixesPath.Add_Click({
param($eventSource, $routedEventArgs)
diff --git a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1 b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
index 62dcdc0..43530b8 100644
--- a/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
+++ b/FFUDevelopment/FFUUI.Core/FFUUI.Core.Initialize.psm1
@@ -400,7 +400,13 @@ function Initialize-UIDefaults {
$State.Controls.chkCopyAutopilot.IsChecked = $State.Defaults.generalDefaults.CopyAutopilot
$State.Controls.chkCopyUnattend.IsChecked = $State.Defaults.generalDefaults.CopyUnattend
$State.Controls.chkCopyPPKG.IsChecked = $State.Defaults.generalDefaults.CopyPPKG
- Set-DeviceNamingMode -State $State -Mode $State.Defaults.generalDefaults.DeviceNamingMode
+ $defaultDeviceNamingMode = if ($State.Defaults.generalDefaults.DeviceNamingMode -in @('None', 'Prompt', 'Template', 'Prefixes')) {
+ $State.Defaults.generalDefaults.DeviceNamingMode
+ }
+ else {
+ 'None'
+ }
+ Set-DeviceNamingModeState -State $State -DisplayMode $defaultDeviceNamingMode -LoadedMode $null
$State.Controls.txtDeviceNameTemplate.Text = $State.Defaults.generalDefaults.DeviceNameTemplate
$State.Controls.txtDeviceNamePrefixesPath.Text = $State.Defaults.generalDefaults.DeviceNamePrefixesPath
$State.Controls.txtDeviceNamePrefixes.Text = ($State.Defaults.generalDefaults.DeviceNamePrefixes -join [System.Environment]::NewLine)
diff --git a/FFUDevelopment/config/Sample_default.json b/FFUDevelopment/config/Sample_default.json
index dcc97ea..09ee380 100644
Binary files a/FFUDevelopment/config/Sample_default.json and b/FFUDevelopment/config/Sample_default.json differ
diff --git a/docs/build.md b/docs/build.md
index 4e92747..99f7b20 100644
--- a/docs/build.md
+++ b/docs/build.md
@@ -371,9 +371,12 @@ Use the **Device Naming** expander to decide whether `ComputerName` should be se
### No Device Name
-This is the default option. The unattend file is still applied, but Windows generates a random computer name instead of forcing a prompt or a fixed name.
+This is the default radio selection in the UI.
-The active `unattend_*.xml` files in `FFUDevelopment\Unattend` use `*` for this default behavior.
+- If you leave device naming untouched, FFU Builder does not write `DeviceNamingMode` to the generated config. This preserves the script's `Legacy` default, so an existing `FFUDevelopment\Unattend\prefixes.txt` file is still copied to deployment media when present.
+- If you explicitly select this option, FFU Builder writes `DeviceNamingMode = None`. The unattend file is still applied, but Windows generates a random computer name instead of forcing a prompt or a fixed name.
+
+The active `unattend_*.xml` files in `FFUDevelopment\Unattend` use `*` in the current sample files.
### Prompt for Device Name
diff --git a/docs/parameters_reference.md b/docs/parameters_reference.md
index ec31da0..400f89b 100644
--- a/docs/parameters_reference.md
+++ b/docs/parameters_reference.md
@@ -41,7 +41,7 @@ This table lists all top-level parameters in BuildFFUVM.ps1.
| -CopyUnattend | bool | Copy Unattend.xml | When set to $true, stages the selected architecture-specific unattend XML file as Unattend.xml on the Deployment partition of the USB drive. Cannot be used together with -InjectUnattend. Default is $false. |
| -CreateDeploymentMedia | bool | Create Deployment Media | When set to $true, this will create WinPE deployment media for use when deploying to a physical device. |
| -CustomFFUNameTemplate | string | Custom FFU Name Template | Sets a custom FFU output name with placeholders. Allowed placeholders are: {WindowsRelease}, {WindowsVersion}, {SKU}, {BuildDate}, {yyyy}, {MM}, {dd}, {H}, {hh}, {mm}, {tt}. |
-| -DeviceNamingMode | string | Device Naming expander | Controls how device naming is handled when unattend content is copied to USB media or injected into the FFU. Accepted values are Legacy, None, Prompt, Template, and Prefixes. The UI uses None, Prompt, Template, and Prefixes. Prompt rewrites the staged deployment unattend to the existing manual prompt placeholder and requires -CopyUnattend. |
+| -DeviceNamingMode | string | Device Naming expander | Controls how device naming is handled when unattend content is copied to USB media or injected into the FFU. Accepted values are Legacy, None, Prompt, Template, and Prefixes. The UI shows None, Prompt, Template, and Prefixes. When device naming is left untouched in the UI, the generated config does not write DeviceNamingMode, which preserves the script default of Legacy. Prompt rewrites the staged deployment unattend to the existing manual prompt placeholder and requires -CopyUnattend. |
| -DeviceNameTemplate | string | Specify Device Name | Sets the device name used when DeviceNamingMode is Template. Supports a static name or the %serial% token when -CopyUnattend is used. |
| -DeviceNamePrefixesPath | string | Prefixes File Path | Path to the source prefixes file used for legacy copy or when -DeviceNamePrefixes is not supplied. Default is $FFUDevelopmentPath\Unattend\prefixes.txt. |
| -UnattendX64FilePath | string | x64 Unattend File Path | Path to the x64 unattend XML source file used by Copy Unattend.xml and Inject Unattend.xml. Default is $FFUDevelopmentPath\Unattend\unattend_x64.xml. |