mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-13 18:07:20 -06:00
Adds Prompt option to device naming mode
Introduces an explicit "Prompt" option for device naming to allow technicians to enter the device name during deployment. This replaces the implicit legacy behavior, providing clear UI controls and validation to ensure that Unattend.xml is copied, which is required for prompt-based naming. Relevant documentation is updated to reflect this new workflow capability.
This commit is contained in:
@@ -73,7 +73,7 @@ When set to $true, will copy the provisioning package from the $FFUDevelopmentPa
|
||||
When set to $true, will copy the $FFUDevelopmentPath\Unattend folder to the Deployment partition of the USB drive. Default is $false.
|
||||
|
||||
.PARAMETER DeviceNamingMode
|
||||
Controls how device naming is handled when unattend content is copied to USB media or injected into the FFU. Supported values are Legacy, None, Template, and Prefixes.
|
||||
Controls how device naming is handled when unattend content is copied to USB media or injected into the FFU. Supported values are Legacy, None, Prompt, Template, and Prefixes.
|
||||
|
||||
.PARAMETER DeviceNameTemplate
|
||||
Sets the device name used when DeviceNamingMode is Template. Supports a static name or the %serial% token when CopyUnattend is used.
|
||||
@@ -419,7 +419,7 @@ param(
|
||||
[bool]$AllowVHDXCaching,
|
||||
[bool]$CopyPPKG,
|
||||
[bool]$CopyUnattend,
|
||||
[ValidateSet('Legacy', 'None', 'Template', 'Prefixes')]
|
||||
[ValidateSet('Legacy', 'None', 'Prompt', 'Template', 'Prefixes')]
|
||||
[string]$DeviceNamingMode = 'Legacy',
|
||||
[string]$DeviceNameTemplate,
|
||||
[string[]]$DeviceNamePrefixes,
|
||||
@@ -557,7 +557,7 @@ function Save-StagedUnattendFile {
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$DestinationPath,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[ValidateSet('Legacy', 'None', 'Template', 'Prefixes')]
|
||||
[ValidateSet('Legacy', 'None', 'Prompt', 'Template', 'Prefixes')]
|
||||
[string]$DeviceNamingMode,
|
||||
[string]$DeviceNameTemplate
|
||||
)
|
||||
@@ -588,6 +588,9 @@ function Save-StagedUnattendFile {
|
||||
if ($DeviceNamingMode -eq 'None') {
|
||||
$computerNameComponent.ComputerName = '*'
|
||||
}
|
||||
elseif ($DeviceNamingMode -eq 'Prompt') {
|
||||
$computerNameComponent.ComputerName = 'MyComputer'
|
||||
}
|
||||
elseif ($DeviceNamingMode -eq 'Template') {
|
||||
$computerNameComponent.ComputerName = $DeviceNameTemplate
|
||||
}
|
||||
@@ -638,6 +641,11 @@ if ($DeviceNamingMode -eq 'Template') {
|
||||
throw 'The %serial% device name variable is only supported when CopyUnattend is used.'
|
||||
}
|
||||
}
|
||||
elseif ($DeviceNamingMode -eq 'Prompt') {
|
||||
if (-not $CopyUnattend) {
|
||||
throw 'DeviceNamingMode Prompt requires CopyUnattend. Prompt-based naming is not supported with InjectUnattend.'
|
||||
}
|
||||
}
|
||||
elseif ($DeviceNamingMode -eq 'Prefixes') {
|
||||
if (-not $CopyUnattend) {
|
||||
throw 'DeviceNamingMode Prefixes requires CopyUnattend. Prefix-based naming is not supported with InjectUnattend.'
|
||||
@@ -4364,6 +4372,9 @@ Function New-DeploymentUSB {
|
||||
if ($DeviceNamingMode -eq 'None') {
|
||||
$computerNameComponent.ComputerName = '*'
|
||||
}
|
||||
elseif ($DeviceNamingMode -eq 'Prompt') {
|
||||
$computerNameComponent.ComputerName = 'MyComputer'
|
||||
}
|
||||
elseif ($DeviceNamingMode -eq 'Template') {
|
||||
$computerNameComponent.ComputerName = $DeviceNameTemplate
|
||||
}
|
||||
@@ -5706,10 +5717,10 @@ if ($CopyUnattend) {
|
||||
throw "-CopyUnattend is set to `$true, but the $UnattendFolder folder is missing a .XML file"
|
||||
}
|
||||
|
||||
if ($DeviceNamingMode -eq 'Prefixes') {
|
||||
if ($DeviceNamingMode -in @('Prompt', 'Prefixes')) {
|
||||
$unattendSourcePath = Get-UnattendSourcePath -UnattendFolder $UnattendFolder -WindowsArch $WindowsArch
|
||||
if (-not (Test-UnattendHasComputerNameElement -Path $unattendSourcePath)) {
|
||||
throw "DeviceNamingMode Prefixes requires a ComputerName element in $unattendSourcePath"
|
||||
throw "DeviceNamingMode $DeviceNamingMode requires a ComputerName element in $unattendSourcePath"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -439,7 +439,15 @@ $script:uiState.Controls.btnRun.Add_Click({
|
||||
return
|
||||
}
|
||||
|
||||
if ($config.DeviceNamingMode -eq 'Template') {
|
||||
if ($config.DeviceNamingMode -eq 'Prompt') {
|
||||
if (-not $config.CopyUnattend) {
|
||||
[System.Windows.MessageBox]::Show("Select Copy Unattend.xml before using 'Prompt for Device Name'.", "Copy Unattend Required", "OK", "Warning") | Out-Null
|
||||
$btnRun.IsEnabled = $true
|
||||
$script:uiState.Controls.txtStatus.Text = "Build canceled: prompt naming requires Copy Unattend.xml."
|
||||
return
|
||||
}
|
||||
}
|
||||
elseif ($config.DeviceNamingMode -eq 'Template') {
|
||||
if ([string]::IsNullOrWhiteSpace([string]$config.DeviceNameTemplate)) {
|
||||
[System.Windows.MessageBox]::Show("Specify a device name before using 'Specify Device Name'.", "Device Name Required", "OK", "Warning") | Out-Null
|
||||
$btnRun.IsEnabled = $true
|
||||
|
||||
@@ -910,6 +910,7 @@
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<TextBlock Text="Choose how the device should be named when unattend is applied." Margin="0,0,0,12" TextWrapping="Wrap"/>
|
||||
<RadioButton x:Name="rbDeviceNamingNone" Content="No Device Name" GroupName="DeviceNamingMode" IsChecked="True" Margin="0,0,0,8" ToolTip="Apply unattend without setting a specific computer name."/>
|
||||
<RadioButton x:Name="rbDeviceNamingPrompt" Content="Prompt for Device Name" GroupName="DeviceNamingMode" Margin="0,0,0,8" ToolTip="Prompt the technician to enter a device name during deployment. This option requires Copy Unattend.xml."/>
|
||||
<RadioButton x:Name="rbDeviceNamingTemplate" Content="Specify Device Name" GroupName="DeviceNamingMode" Margin="0,0,0,8" ToolTip="Use a static device name or the %serial% variable when Copy Unattend.xml is selected."/>
|
||||
<StackPanel x:Name="deviceNameTemplatePanel" Margin="32,0,0,16" Visibility="Collapsed">
|
||||
<TextBlock Text="Use static text, %serial%, or both together, for example Comp-%serial%." Margin="0,0,0,4" TextWrapping="Wrap"/>
|
||||
|
||||
@@ -472,7 +472,10 @@ function Update-UIFromConfig {
|
||||
if ($ConfigContent.PSObject.Properties.Name -contains 'DeviceNamingMode') {
|
||||
$deviceNamingMode = [string]$ConfigContent.DeviceNamingMode
|
||||
}
|
||||
if ($deviceNamingMode -notin @('None', 'Template', 'Prefixes')) {
|
||||
if ($deviceNamingMode -eq 'Legacy') {
|
||||
$deviceNamingMode = 'Prompt'
|
||||
}
|
||||
if ($deviceNamingMode -notin @('None', 'Prompt', 'Template', 'Prefixes')) {
|
||||
$deviceNamingMode = 'None'
|
||||
}
|
||||
Set-DeviceNamingMode -State $State -Mode $deviceNamingMode
|
||||
|
||||
@@ -30,6 +30,10 @@ function Update-VMNetworkingControls {
|
||||
function Get-SelectedDeviceNamingMode {
|
||||
param([PSCustomObject]$State)
|
||||
|
||||
if ($true -eq $State.Controls.rbDeviceNamingPrompt.IsChecked) {
|
||||
return 'Prompt'
|
||||
}
|
||||
|
||||
if ($true -eq $State.Controls.rbDeviceNamingTemplate.IsChecked) {
|
||||
return 'Template'
|
||||
}
|
||||
@@ -44,11 +48,12 @@ function Get-SelectedDeviceNamingMode {
|
||||
function Set-DeviceNamingMode {
|
||||
param(
|
||||
[PSCustomObject]$State,
|
||||
[ValidateSet('None', 'Template', 'Prefixes')]
|
||||
[ValidateSet('None', 'Prompt', 'Template', 'Prefixes')]
|
||||
[string]$Mode
|
||||
)
|
||||
|
||||
$State.Controls.rbDeviceNamingNone.IsChecked = $Mode -eq 'None'
|
||||
$State.Controls.rbDeviceNamingPrompt.IsChecked = $Mode -eq 'Prompt'
|
||||
$State.Controls.rbDeviceNamingTemplate.IsChecked = $Mode -eq 'Template'
|
||||
$State.Controls.rbDeviceNamingPrefixes.IsChecked = $Mode -eq 'Prefixes'
|
||||
}
|
||||
@@ -132,9 +137,10 @@ function Update-UnattendSelectionControls {
|
||||
$isCopyUnattendSelected = $true -eq $State.Controls.chkCopyUnattend.IsChecked
|
||||
$isInjectUnattendSelected = $true -eq $State.Controls.chkInjectUnattend.IsChecked
|
||||
$deviceNameTemplateUsesSerialToken = Test-DeviceNameTemplateUsesSerialToken -State $State
|
||||
$requiresCopiedUnattend = ($selectedDeviceNamingMode -in @('Prompt', 'Prefixes')) -or $deviceNameTemplateUsesSerialToken
|
||||
|
||||
if ($isCopyUnattendSelected -and $isInjectUnattendSelected) {
|
||||
if (($selectedDeviceNamingMode -eq 'Prefixes') -or $deviceNameTemplateUsesSerialToken) {
|
||||
if ($requiresCopiedUnattend) {
|
||||
$State.Controls.chkInjectUnattend.IsChecked = $false
|
||||
$isInjectUnattendSelected = $false
|
||||
}
|
||||
@@ -144,7 +150,7 @@ function Update-UnattendSelectionControls {
|
||||
}
|
||||
}
|
||||
|
||||
if (($selectedDeviceNamingMode -eq 'Prefixes') -or $deviceNameTemplateUsesSerialToken) {
|
||||
if ($requiresCopiedUnattend) {
|
||||
if (-not $isCopyUnattendSelected) {
|
||||
$State.Controls.chkCopyUnattend.IsChecked = $true
|
||||
$isCopyUnattendSelected = $true
|
||||
@@ -177,13 +183,14 @@ function Update-UnattendSelectionControls {
|
||||
function Update-DeviceNamingControls {
|
||||
param([PSCustomObject]$State)
|
||||
|
||||
if (($true -eq $State.Controls.chkInjectUnattend.IsChecked) -and ($true -eq $State.Controls.rbDeviceNamingPrefixes.IsChecked)) {
|
||||
if (($true -eq $State.Controls.chkInjectUnattend.IsChecked) -and (($true -eq $State.Controls.rbDeviceNamingPrompt.IsChecked) -or ($true -eq $State.Controls.rbDeviceNamingPrefixes.IsChecked))) {
|
||||
$State.Controls.rbDeviceNamingNone.IsChecked = $true
|
||||
}
|
||||
|
||||
$selectedDeviceNamingMode = Get-SelectedDeviceNamingMode -State $State
|
||||
$State.Controls.deviceNameTemplatePanel.Visibility = if ($selectedDeviceNamingMode -eq 'Template') { 'Visible' } else { 'Collapsed' }
|
||||
$State.Controls.deviceNamePrefixesPanel.Visibility = if ($selectedDeviceNamingMode -eq 'Prefixes') { 'Visible' } else { 'Collapsed' }
|
||||
$State.Controls.rbDeviceNamingPrompt.IsEnabled = -not ($true -eq $State.Controls.chkInjectUnattend.IsChecked)
|
||||
$State.Controls.rbDeviceNamingPrefixes.IsEnabled = -not ($true -eq $State.Controls.chkInjectUnattend.IsChecked)
|
||||
|
||||
if ($selectedDeviceNamingMode -eq 'Prefixes') {
|
||||
@@ -435,6 +442,11 @@ function Register-EventHandlers {
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
Update-DeviceNamingControls -State $window.Tag
|
||||
})
|
||||
$State.Controls.rbDeviceNamingPrompt.Add_Checked({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
Update-DeviceNamingControls -State $window.Tag
|
||||
})
|
||||
$State.Controls.rbDeviceNamingTemplate.Add_Checked({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
|
||||
@@ -221,6 +221,7 @@ function Initialize-UIControls {
|
||||
$State.Controls.chkCreateDeploymentMedia = $window.FindName('chkCreateDeploymentMedia')
|
||||
$State.Controls.chkInjectUnattend = $window.FindName('chkInjectUnattend')
|
||||
$State.Controls.rbDeviceNamingNone = $window.FindName('rbDeviceNamingNone')
|
||||
$State.Controls.rbDeviceNamingPrompt = $window.FindName('rbDeviceNamingPrompt')
|
||||
$State.Controls.rbDeviceNamingTemplate = $window.FindName('rbDeviceNamingTemplate')
|
||||
$State.Controls.rbDeviceNamingPrefixes = $window.FindName('rbDeviceNamingPrefixes')
|
||||
$State.Controls.deviceNameTemplatePanel = $window.FindName('deviceNameTemplatePanel')
|
||||
|
||||
Reference in New Issue
Block a user