mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-13 18:07:20 -06:00
Adds custom unattend XML file selection paths
Adds parameters for x64 and arm64 unattend XML file paths. Updates the BuildFFUVM_UI to let the user pick specific XML files to copy or inject instead of requiring them to exist in the `unattend` folder. Adds validation to ensure the selected unattend XML files are not empty. Updates documentation to reflect the new functionality.
This commit is contained in:
@@ -70,7 +70,7 @@ When set to $true, enables adding WinPE drivers. By default copies drivers from
|
||||
When set to $true, will copy the provisioning package from the $FFUDevelopmentPath\PPKG folder to the Deployment partition of the USB drive. Default is $false.
|
||||
|
||||
.PARAMETER CopyUnattend
|
||||
When set to $true, will copy the $FFUDevelopmentPath\Unattend folder to the Deployment partition of the USB drive. Default is $false.
|
||||
When set to $true, stages the selected architecture-specific unattend XML file as Unattend.xml on 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, Prompt, Template, and Prefixes.
|
||||
@@ -84,6 +84,12 @@ Sets the prefixes used when DeviceNamingMode is Prefixes. Each entry becomes a l
|
||||
.PARAMETER DeviceNamePrefixesPath
|
||||
Path to the source prefixes file used for legacy copy or when DeviceNamePrefixes is not supplied. Default is $FFUDevelopmentPath\Unattend\prefixes.txt.
|
||||
|
||||
.PARAMETER UnattendX64FilePath
|
||||
Path to the x64 unattend XML source file. Default is $FFUDevelopmentPath\Unattend\unattend_x64.xml.
|
||||
|
||||
.PARAMETER UnattendArm64FilePath
|
||||
Path to the arm64 unattend XML source file. Default is $FFUDevelopmentPath\Unattend\unattend_arm64.xml.
|
||||
|
||||
.PARAMETER CreateDeploymentMedia
|
||||
When set to $true, this will create WinPE deployment media for use when deploying to a physical device.
|
||||
|
||||
@@ -118,7 +124,7 @@ Prefix for the generated FFU file. Default is _FFU.
|
||||
Headers to use when downloading files. Not recommended to modify.
|
||||
|
||||
.PARAMETER InjectUnattend
|
||||
When set to $true and InstallApps is also $true, copies unattend_[arch].xml from $FFUDevelopmentPath\unattend to $FFUDevelopmentPath\Apps\Unattend\Unattend.xml so sysprep can use it inside the VM. Default is $false.
|
||||
When set to $true and InstallApps is also $true, stages the selected architecture-specific unattend XML file to $FFUDevelopmentPath\Apps\Unattend\Unattend.xml so sysprep can use it inside the VM. Default is $false.
|
||||
|
||||
.PARAMETER InstallApps
|
||||
When set to $true, the script will create an Apps.iso file from the $FFUDevelopmentPath\Apps folder. It will also create a VM, mount the Apps.iso, install the apps, sysprep, and capture the VM. When set to $false, the FFU is created from a VHDX file, and no VM is created.
|
||||
@@ -424,6 +430,8 @@ param(
|
||||
[string]$DeviceNameTemplate,
|
||||
[string[]]$DeviceNamePrefixes,
|
||||
[string]$DeviceNamePrefixesPath,
|
||||
[string]$UnattendX64FilePath,
|
||||
[string]$UnattendArm64FilePath,
|
||||
[bool]$CopyAutopilot,
|
||||
[bool]$CompactOS = $true,
|
||||
[bool]$CleanupDeployISO = $true,
|
||||
@@ -527,11 +535,31 @@ function Get-UnattendSourcePath {
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$UnattendFolder,
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$WindowsArch
|
||||
[string]$WindowsArch,
|
||||
[string]$UnattendX64FilePath,
|
||||
[string]$UnattendArm64FilePath
|
||||
)
|
||||
|
||||
$archSuffix = if ($WindowsArch -ieq 'arm64') { 'arm64' } else { 'x64' }
|
||||
return Join-Path $UnattendFolder "unattend_$archSuffix.xml"
|
||||
$resolvedArch = if ($WindowsArch -ieq 'arm64') { 'arm64' } else { 'x64' }
|
||||
$resolvedSourcePath = if ($resolvedArch -eq 'arm64') {
|
||||
if ([string]::IsNullOrWhiteSpace($UnattendArm64FilePath)) {
|
||||
Join-Path $UnattendFolder 'unattend_arm64.xml'
|
||||
}
|
||||
else {
|
||||
$UnattendArm64FilePath
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ([string]::IsNullOrWhiteSpace($UnattendX64FilePath)) {
|
||||
Join-Path $UnattendFolder 'unattend_x64.xml'
|
||||
}
|
||||
else {
|
||||
$UnattendX64FilePath
|
||||
}
|
||||
}
|
||||
|
||||
WriteLog "Resolved unattend source path for ${resolvedArch}: $resolvedSourcePath"
|
||||
return $resolvedSourcePath
|
||||
}
|
||||
|
||||
function Initialize-UnattendComputerNamePath {
|
||||
@@ -915,6 +943,8 @@ if (-not $EdgePath) { $EdgePath = "$AppsPath\Edge" }
|
||||
if (-not $DriversFolder) { $DriversFolder = "$FFUDevelopmentPath\Drivers" }
|
||||
if (-not $PPKGFolder) { $PPKGFolder = "$FFUDevelopmentPath\PPKG" }
|
||||
if (-not $UnattendFolder) { $UnattendFolder = "$FFUDevelopmentPath\Unattend" }
|
||||
if ([string]::IsNullOrWhiteSpace($UnattendX64FilePath)) { $UnattendX64FilePath = Join-Path $UnattendFolder 'unattend_x64.xml' }
|
||||
if ([string]::IsNullOrWhiteSpace($UnattendArm64FilePath)) { $UnattendArm64FilePath = Join-Path $UnattendFolder 'unattend_arm64.xml' }
|
||||
if (-not $AutopilotFolder) { $AutopilotFolder = "$FFUDevelopmentPath\Autopilot" }
|
||||
if (-not $PEDriversFolder) { $PEDriversFolder = "$FFUDevelopmentPath\PEDrivers" }
|
||||
if (-not $VHDXCacheFolder) { $VHDXCacheFolder = "$FFUDevelopmentPath\VHDXCache" }
|
||||
@@ -4397,11 +4427,31 @@ Function New-DeploymentUSB {
|
||||
function Get-LocalUnattendSourcePath {
|
||||
param(
|
||||
[string]$UnattendFolder,
|
||||
[string]$WindowsArch
|
||||
[string]$WindowsArch,
|
||||
[string]$UnattendX64FilePath,
|
||||
[string]$UnattendArm64FilePath
|
||||
)
|
||||
|
||||
$archSuffix = if ($WindowsArch -ieq 'arm64') { 'arm64' } else { 'x64' }
|
||||
return Join-Path $UnattendFolder "unattend_$archSuffix.xml"
|
||||
$resolvedArch = if ($WindowsArch -ieq 'arm64') { 'arm64' } else { 'x64' }
|
||||
$resolvedSourcePath = if ($resolvedArch -eq 'arm64') {
|
||||
if ([string]::IsNullOrWhiteSpace($UnattendArm64FilePath)) {
|
||||
Join-Path $UnattendFolder 'unattend_arm64.xml'
|
||||
}
|
||||
else {
|
||||
$UnattendArm64FilePath
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ([string]::IsNullOrWhiteSpace($UnattendX64FilePath)) {
|
||||
Join-Path $UnattendFolder 'unattend_x64.xml'
|
||||
}
|
||||
else {
|
||||
$UnattendX64FilePath
|
||||
}
|
||||
}
|
||||
|
||||
WriteLog "Resolved unattend source path for ${resolvedArch}: $resolvedSourcePath"
|
||||
return $resolvedSourcePath
|
||||
}
|
||||
|
||||
function Initialize-UnattendComputerNamePath {
|
||||
@@ -4587,7 +4637,7 @@ Function New-DeploymentUSB {
|
||||
$UnattendPathOnUSB = Join-Path $DeployPartitionDriveLetter "Unattend"
|
||||
WriteLog "Copying unattend file to $UnattendPathOnUSB"
|
||||
New-Item -Path $UnattendPathOnUSB -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
|
||||
$unattendSource = Get-LocalUnattendSourcePath -UnattendFolder $using:UnattendFolder -WindowsArch $using:WindowsArch
|
||||
$unattendSource = Get-LocalUnattendSourcePath -UnattendFolder $using:UnattendFolder -WindowsArch $using:WindowsArch -UnattendX64FilePath $using:UnattendX64FilePath -UnattendArm64FilePath $using:UnattendArm64FilePath
|
||||
$legacyPrefixesWillBeStaged = ($using:DeviceNamingMode -eq 'Legacy') -and (Test-Path -Path $using:resolvedDeviceNamePrefixesPath -PathType Leaf)
|
||||
Save-LocalStagedUnattendFile -SourcePath $unattendSource -DestinationPath (Join-Path $UnattendPathOnUSB 'Unattend.xml') -DeviceNamingMode $using:DeviceNamingMode -DeviceNameTemplate $using:normalizedDeviceNameTemplate -WindowsArch $using:WindowsArch -LegacyPrefixesWillBeStaged $legacyPrefixesWillBeStaged
|
||||
if ($using:DeviceNamingMode -eq 'Prefixes') {
|
||||
@@ -5850,21 +5900,23 @@ if ($CopyAutopilot) {
|
||||
WriteLog 'Autopilot validation complete'
|
||||
}
|
||||
|
||||
#Validate Unattend folder
|
||||
if ($CopyUnattend) {
|
||||
# Validate unattend source file
|
||||
if ($CopyUnattend -or $InjectUnattend) {
|
||||
WriteLog 'Doing Unattend validation'
|
||||
if (!(Test-Path -Path $UnattendFolder)) {
|
||||
WriteLog "-CopyUnattend is set to `$true, but the $UnattendFolder folder is missing"
|
||||
throw "-CopyUnattend is set to `$true, but the $UnattendFolder folder is missing"
|
||||
$selectedUnattendMode = if ($CopyUnattend) { 'CopyUnattend' } else { 'InjectUnattend' }
|
||||
$unattendSourcePath = Get-UnattendSourcePath -UnattendFolder $UnattendFolder -WindowsArch $WindowsArch -UnattendX64FilePath $UnattendX64FilePath -UnattendArm64FilePath $UnattendArm64FilePath
|
||||
if (!(Test-Path -Path $unattendSourcePath -PathType Leaf)) {
|
||||
WriteLog "-$selectedUnattendMode is set to `$true, but the selected unattend XML file is missing: $unattendSourcePath"
|
||||
throw "-$selectedUnattendMode is set to `$true, but the selected unattend XML file is missing: $unattendSourcePath"
|
||||
}
|
||||
#Check for .XML file
|
||||
if (!(Get-ChildItem -Path $UnattendFolder -Filter unattend_*.xml)) {
|
||||
WriteLog "-CopyUnattend is set to `$true, but the $UnattendFolder folder is missing a .XML file"
|
||||
throw "-CopyUnattend is set to `$true, but the $UnattendFolder folder is missing a .XML file"
|
||||
|
||||
$selectedUnattendFile = Get-Item -Path $unattendSourcePath -ErrorAction SilentlyContinue
|
||||
if (($null -eq $selectedUnattendFile) -or ($selectedUnattendFile.Length -le 0)) {
|
||||
WriteLog "-$selectedUnattendMode is set to `$true, but the selected unattend XML file is empty: $unattendSourcePath"
|
||||
throw "-$selectedUnattendMode is set to `$true, but the selected unattend XML file is empty: $unattendSourcePath"
|
||||
}
|
||||
|
||||
if ($DeviceNamingMode -ne 'None') {
|
||||
$unattendSourcePath = Get-UnattendSourcePath -UnattendFolder $UnattendFolder -WindowsArch $WindowsArch
|
||||
try {
|
||||
[xml]$validationUnattendXml = Get-Content -Path $unattendSourcePath
|
||||
$null = Initialize-UnattendComputerNamePath -UnattendXml $validationUnattendXml -WindowsArch $WindowsArch
|
||||
@@ -5877,19 +5929,6 @@ if ($CopyUnattend) {
|
||||
WriteLog 'Unattend validation complete'
|
||||
}
|
||||
|
||||
if ($InjectUnattend -and ($DeviceNamingMode -ne 'None')) {
|
||||
$injectUnattendSourcePath = Get-UnattendSourcePath -UnattendFolder $UnattendFolder -WindowsArch $WindowsArch
|
||||
if (Test-Path -Path $injectUnattendSourcePath -PathType Leaf) {
|
||||
try {
|
||||
[xml]$validationUnattendXml = Get-Content -Path $injectUnattendSourcePath
|
||||
$null = Initialize-UnattendComputerNamePath -UnattendXml $validationUnattendXml -WindowsArch $WindowsArch
|
||||
}
|
||||
catch {
|
||||
throw "DeviceNamingMode $DeviceNamingMode requires a valid specialize/Microsoft-Windows-Shell-Setup/ComputerName path in $injectUnattendSourcePath. $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Override $InstallApps value if using ESD to build FFU. This is due to a strange issue where building the FFU
|
||||
#from vhdx doesn't work (you get an older style OOBE screen and get stuck in an OOBE reboot loop when hitting next).
|
||||
#This behavior doesn't happen with WIM files.
|
||||
@@ -6787,7 +6826,7 @@ if ($InstallApps) {
|
||||
#Create Apps ISO
|
||||
# Inject Unattend.xml into Apps if requested and applicable
|
||||
if ($InstallApps -and $InjectUnattend) {
|
||||
$unattendSource = Get-UnattendSourcePath -UnattendFolder $UnattendFolder -WindowsArch $WindowsArch
|
||||
$unattendSource = Get-UnattendSourcePath -UnattendFolder $UnattendFolder -WindowsArch $WindowsArch -UnattendX64FilePath $UnattendX64FilePath -UnattendArm64FilePath $UnattendArm64FilePath
|
||||
|
||||
# Ensure target folder exists under Apps
|
||||
$targetFolder = Join-Path $AppsPath 'Unattend'
|
||||
|
||||
@@ -439,6 +439,38 @@ $script:uiState.Controls.btnRun.Add_Click({
|
||||
return
|
||||
}
|
||||
|
||||
if ($config.CopyUnattend -or $config.InjectUnattend) {
|
||||
$selectedUnattendArch = if ($config.WindowsArch -ieq 'arm64') { 'arm64' } else { 'x64' }
|
||||
$selectedUnattendSourcePath = if ($selectedUnattendArch -eq 'arm64') {
|
||||
[string]$config.UnattendArm64FilePath
|
||||
}
|
||||
else {
|
||||
[string]$config.UnattendX64FilePath
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($selectedUnattendSourcePath)) {
|
||||
[System.Windows.MessageBox]::Show("Select a valid $selectedUnattendArch unattend XML file before using Copy Unattend.xml or Inject Unattend.xml.", "Unattend File Required", "OK", "Warning") | Out-Null
|
||||
$btnRun.IsEnabled = $true
|
||||
$script:uiState.Controls.txtStatus.Text = "Build canceled: unattend file path required."
|
||||
return
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $selectedUnattendSourcePath -PathType Leaf)) {
|
||||
[System.Windows.MessageBox]::Show("The selected $selectedUnattendArch unattend XML file was not found:`n$selectedUnattendSourcePath", "Unattend File Missing", "OK", "Warning") | Out-Null
|
||||
$btnRun.IsEnabled = $true
|
||||
$script:uiState.Controls.txtStatus.Text = "Build canceled: unattend file missing."
|
||||
return
|
||||
}
|
||||
|
||||
$selectedUnattendFileInfo = Get-Item -Path $selectedUnattendSourcePath -ErrorAction SilentlyContinue
|
||||
if (($null -eq $selectedUnattendFileInfo) -or ($selectedUnattendFileInfo.Length -le 0)) {
|
||||
[System.Windows.MessageBox]::Show("The selected $selectedUnattendArch unattend XML file is empty:`n$selectedUnattendSourcePath", "Unattend File Empty", "OK", "Warning") | Out-Null
|
||||
$btnRun.IsEnabled = $true
|
||||
$script:uiState.Controls.txtStatus.Text = "Build canceled: unattend file empty."
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -836,11 +836,13 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Row 9: General Build Options Checkboxes -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Row 10: Device Naming -->
|
||||
<!-- Row 10: Unattend.xml Options -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Row 11: Build USB Drive Section -->
|
||||
<!-- Row 11: Device Naming -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Row 12: Post-Build Cleanup -->
|
||||
<!-- Row 12: Build USB Drive Section -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- Row 13: Post-Build Cleanup -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -900,13 +902,39 @@
|
||||
<CheckBox x:Name="chkOptimize" Content="Optimize" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will optimize the OS when building the FFU."/>
|
||||
<CheckBox x:Name="chkAllowVHDXCaching" Content="Allow VHDX Caching" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will cache the VHDX file to cache folder and create a config json file to track Windows build information."/>
|
||||
<CheckBox x:Name="chkCreateDeploymentMedia" Content="Create Deployment Media" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, this will create WinPE deployment media for use when deploying to a physical device."/>
|
||||
<CheckBox x:Name="chkInjectUnattend" Content="Inject Unattend.xml" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true and Install Apps is enabled, copies unattend_[arch].xml from $FFUDevelopmentPath\unattend into Apps\Unattend\Unattend.xml to be used by sysprep."/>
|
||||
<CheckBox x:Name="chkVerbose" Content="Verbose" Margin="0" VerticalAlignment="Center" Tag="When set to $true, will enable write-verbose output to the console for the build script."/>
|
||||
</StackPanel>
|
||||
</Expander>
|
||||
|
||||
<!-- Row 10: Device Naming -->
|
||||
<Expander Grid.Row="10" x:Name="deviceNamingSection" Header="Device Naming" IsExpanded="False" Margin="0,0,0,20" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<!-- Row 10: Unattend.xml Options -->
|
||||
<Expander Grid.Row="10" Header="Unattend.xml Options" IsExpanded="False" Margin="0,0,0,20" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<TextBlock Text="Choose how unattend content is staged and which architecture-specific source files are used." Margin="0,0,0,12" TextWrapping="Wrap"/>
|
||||
<TextBlock Text="x64 Unattend File Path" Margin="0,0,0,8" TextWrapping="Wrap"/>
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="txtUnattendX64FilePath" Grid.Column="0" VerticalAlignment="Center" ToolTip="Path to the x64 unattend XML source file. You can use any file name."/>
|
||||
<Button x:Name="btnBrowseUnattendX64FilePath" Grid.Column="1" Content="Browse..." Padding="12,4" Margin="8,0,0,0" VerticalAlignment="Center" ToolTip="Browse to the x64 unattend XML source file."/>
|
||||
</Grid>
|
||||
<TextBlock Text="arm64 Unattend File Path" Margin="0,0,0,8" TextWrapping="Wrap"/>
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox x:Name="txtUnattendArm64FilePath" Grid.Column="0" VerticalAlignment="Center" ToolTip="Path to the arm64 unattend XML source file. You can use any file name."/>
|
||||
<Button x:Name="btnBrowseUnattendArm64FilePath" Grid.Column="1" Content="Browse..." Padding="12,4" Margin="8,0,0,0" VerticalAlignment="Center" ToolTip="Browse to the arm64 unattend XML source file."/>
|
||||
</Grid>
|
||||
<CheckBox x:Name="chkInjectUnattend" Content="Inject Unattend.xml" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true and Install Apps is enabled, uses the selected architecture-specific unattend XML file and copies it into Apps\Unattend\Unattend.xml to be used by sysprep."/>
|
||||
<CheckBox x:Name="chkCopyUnattend" Content="Copy Unattend.xml" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, uses the selected architecture-specific unattend XML file and copies it to the USB drive as Unattend.xml."/>
|
||||
</StackPanel>
|
||||
</Expander>
|
||||
|
||||
<!-- Row 11: Device Naming -->
|
||||
<Expander Grid.Row="11" x:Name="deviceNamingSection" Header="Device Naming" IsExpanded="False" Margin="0,0,0,20" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<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."/>
|
||||
@@ -938,8 +966,8 @@
|
||||
</StackPanel>
|
||||
</Expander>
|
||||
|
||||
<!-- Row 11: Build USB Drive Section -->
|
||||
<Expander Grid.Row="11" x:Name="usbDriveSection" Header="Build USB Drive Options" IsExpanded="False" Margin="0,0,0,20" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<!-- Row 12: Build USB Drive Section -->
|
||||
<Expander Grid.Row="12" x:Name="usbDriveSection" Header="Build USB Drive Options" IsExpanded="False" Margin="0,0,0,20" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<CheckBox x:Name="chkBuildUSBDriveEnable" Content="Build USB Drive" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will partition and format a USB drive and copy the captured FFU to the drive."/>
|
||||
<CheckBox x:Name="chkAllowExternalHardDiskMedia" Content="Allow External Hard Disk Media" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will allow the use of external hard disk media."/>
|
||||
@@ -947,7 +975,6 @@
|
||||
<CheckBox x:Name="chkSelectSpecificUSBDrives" Content="Select Specific USB Drives" Margin="0,0,0,8" VerticalAlignment="Center" Tag="Enable to select specific USB drives for building"/>
|
||||
<!-- Added Missing Checkboxes -->
|
||||
<CheckBox x:Name="chkCopyAutopilot" Content="Copy Autopilot Profile" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will copy the Autopilot profile to the USB drive."/>
|
||||
<CheckBox x:Name="chkCopyUnattend" Content="Copy Unattend.xml" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will copy the Unattend.xml file to the USB drive."/>
|
||||
<CheckBox x:Name="chkCopyPPKG" Content="Copy Provisioning Package" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, will copy the provisioning package to the USB drive."/>
|
||||
<CheckBox x:Name="chkCopyAdditionalFFUFiles" Content="Copy Additional FFU Files" Margin="0,0,0,8" VerticalAlignment="Center" Tag="When set to $true, allows selecting existing FFU files in the capture folder to also copy to the USB drive."/>
|
||||
|
||||
@@ -1004,8 +1031,8 @@
|
||||
</StackPanel>
|
||||
</Expander>
|
||||
|
||||
<!-- Row 12: Post-Build Cleanup -->
|
||||
<Expander Grid.Row="12" Header="Post-Build Cleanup" IsExpanded="False" Margin="0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<!-- Row 13: Post-Build Cleanup -->
|
||||
<Expander Grid.Row="13" Header="Post-Build Cleanup" IsExpanded="False" Margin="0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<StackPanel Margin="0,8,0,0">
|
||||
<CheckBox x:Name="chkCleanupAppsISO" Content="Cleanup Apps ISO" Margin="0,0,0,8" VerticalAlignment="Center" Tag="Remove Apps ISO after FFU capture."/>
|
||||
<CheckBox x:Name="chkCleanupDeployISO" Content="Cleanup Deploy ISO" Margin="0,0,0,8" VerticalAlignment="Center" Tag="Remove WinPE deployment ISO after FFU capture."/>
|
||||
|
||||
@@ -43,6 +43,8 @@ function Get-UIConfig {
|
||||
CopyAdditionalFFUFiles = $State.Controls.chkCopyAdditionalFFUFiles.IsChecked
|
||||
CreateDeploymentMedia = $State.Controls.chkCreateDeploymentMedia.IsChecked
|
||||
InjectUnattend = $State.Controls.chkInjectUnattend.IsChecked
|
||||
UnattendX64FilePath = $State.Controls.txtUnattendX64FilePath.Text
|
||||
UnattendArm64FilePath = $State.Controls.txtUnattendArm64FilePath.Text
|
||||
CustomFFUNameTemplate = $State.Controls.txtCustomFFUNameTemplate.Text
|
||||
Disksize = [int64]$State.Controls.txtDiskSize.Text * 1GB
|
||||
DownloadDrivers = $State.Controls.chkDownloadDrivers.IsChecked
|
||||
@@ -454,8 +456,18 @@ function Update-UIFromConfig {
|
||||
Set-UIValue -ControlName 'chkCopyAdditionalFFUFiles' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CopyAdditionalFFUFiles' -State $State
|
||||
Set-UIValue -ControlName 'chkCreateDeploymentMedia' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CreateDeploymentMedia' -State $State
|
||||
Set-UIValue -ControlName 'chkInjectUnattend' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'InjectUnattend' -State $State
|
||||
Set-UIValue -ControlName 'txtUnattendX64FilePath' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'UnattendX64FilePath' -State $State
|
||||
Set-UIValue -ControlName 'txtUnattendArm64FilePath' -PropertyName 'Text' -ConfigObject $ConfigContent -ConfigKey 'UnattendArm64FilePath' -State $State
|
||||
Set-UIValue -ControlName 'chkVerbose' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'Verbose' -State $State
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($State.Controls.txtUnattendX64FilePath.Text)) {
|
||||
$State.Controls.txtUnattendX64FilePath.Text = Get-DefaultUnattendFilePath -FFUDevelopmentPath $State.Controls.txtFFUDevPath.Text -WindowsArch 'x64'
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($State.Controls.txtUnattendArm64FilePath.Text)) {
|
||||
$State.Controls.txtUnattendArm64FilePath.Text = Get-DefaultUnattendFilePath -FFUDevelopmentPath $State.Controls.txtFFUDevPath.Text -WindowsArch 'arm64'
|
||||
}
|
||||
|
||||
# USB Drive Modification group (Build Tab)
|
||||
Set-UIValue -ControlName 'chkCopyAutopilot' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CopyAutopilot' -State $State
|
||||
Set-UIValue -ControlName 'chkCopyUnattend' -PropertyName 'IsChecked' -ConfigObject $ConfigContent -ConfigKey 'CopyUnattend' -State $State
|
||||
|
||||
@@ -101,6 +101,21 @@ function Get-DefaultDeviceNamePrefixesPath {
|
||||
return Join-Path (Join-Path $FFUDevelopmentPath 'unattend') 'prefixes.txt'
|
||||
}
|
||||
|
||||
function Get-DefaultUnattendFilePath {
|
||||
param(
|
||||
[string]$FFUDevelopmentPath,
|
||||
[ValidateSet('x64', 'arm64')]
|
||||
[string]$WindowsArch
|
||||
)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($FFUDevelopmentPath)) {
|
||||
return $null
|
||||
}
|
||||
|
||||
$fileName = if ($WindowsArch -ieq 'arm64') { 'unattend_arm64.xml' } else { 'unattend_x64.xml' }
|
||||
return Join-Path (Join-Path $FFUDevelopmentPath 'unattend') $fileName
|
||||
}
|
||||
|
||||
function Import-DeviceNamePrefixesFromConfiguredPath {
|
||||
param(
|
||||
[PSCustomObject]$State,
|
||||
@@ -416,12 +431,24 @@ function Register-EventHandlers {
|
||||
$selectedPath = Invoke-BrowseAction -Type 'Folder' -Title "Select FFU Development Path"
|
||||
if ($selectedPath) {
|
||||
$currentPrefixesPath = $localState.Controls.txtDeviceNamePrefixesPath.Text
|
||||
$currentUnattendX64FilePath = $localState.Controls.txtUnattendX64FilePath.Text
|
||||
$currentUnattendArm64FilePath = $localState.Controls.txtUnattendArm64FilePath.Text
|
||||
$previousDefaultPrefixesPath = Get-DefaultDeviceNamePrefixesPath -FFUDevelopmentPath $localState.Controls.txtFFUDevPath.Text
|
||||
$previousDefaultUnattendX64FilePath = Get-DefaultUnattendFilePath -FFUDevelopmentPath $localState.Controls.txtFFUDevPath.Text -WindowsArch 'x64'
|
||||
$previousDefaultUnattendArm64FilePath = Get-DefaultUnattendFilePath -FFUDevelopmentPath $localState.Controls.txtFFUDevPath.Text -WindowsArch 'arm64'
|
||||
$localState.Controls.txtFFUDevPath.Text = $selectedPath
|
||||
$newDefaultPrefixesPath = Get-DefaultDeviceNamePrefixesPath -FFUDevelopmentPath $selectedPath
|
||||
$newDefaultUnattendX64FilePath = Get-DefaultUnattendFilePath -FFUDevelopmentPath $selectedPath -WindowsArch 'x64'
|
||||
$newDefaultUnattendArm64FilePath = Get-DefaultUnattendFilePath -FFUDevelopmentPath $selectedPath -WindowsArch 'arm64'
|
||||
if ([string]::IsNullOrWhiteSpace($currentPrefixesPath) -or $currentPrefixesPath -ieq $previousDefaultPrefixesPath) {
|
||||
$localState.Controls.txtDeviceNamePrefixesPath.Text = $newDefaultPrefixesPath
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($currentUnattendX64FilePath) -or $currentUnattendX64FilePath -ieq $previousDefaultUnattendX64FilePath) {
|
||||
$localState.Controls.txtUnattendX64FilePath.Text = $newDefaultUnattendX64FilePath
|
||||
}
|
||||
if ([string]::IsNullOrWhiteSpace($currentUnattendArm64FilePath) -or $currentUnattendArm64FilePath -ieq $previousDefaultUnattendArm64FilePath) {
|
||||
$localState.Controls.txtUnattendArm64FilePath.Text = $newDefaultUnattendArm64FilePath
|
||||
}
|
||||
Import-DeviceNamePrefixesFromConfiguredPath -State $localState
|
||||
Update-DeviceNamingControls -State $localState
|
||||
}
|
||||
@@ -484,6 +511,46 @@ function Register-EventHandlers {
|
||||
Update-DeviceNamingControls -State $localState
|
||||
}
|
||||
})
|
||||
$State.Controls.btnBrowseUnattendX64FilePath.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$currentUnattendX64FilePath = $localState.Controls.txtUnattendX64FilePath.Text
|
||||
if ([string]::IsNullOrWhiteSpace($currentUnattendX64FilePath)) {
|
||||
$currentUnattendX64FilePath = Get-DefaultUnattendFilePath -FFUDevelopmentPath $localState.Controls.txtFFUDevPath.Text -WindowsArch 'x64'
|
||||
}
|
||||
$initialDirectory = if ([string]::IsNullOrWhiteSpace($currentUnattendX64FilePath)) {
|
||||
$null
|
||||
}
|
||||
else {
|
||||
Split-Path $currentUnattendX64FilePath -Parent
|
||||
}
|
||||
$fileName = if ([string]::IsNullOrWhiteSpace($currentUnattendX64FilePath)) { 'unattend_x64.xml' } else { Split-Path $currentUnattendX64FilePath -Leaf }
|
||||
$selectedPath = Invoke-BrowseAction -Type 'OpenFile' -Title 'Select x64 unattend XML file' -Filter 'XML files (*.xml)|*.xml|All files (*.*)|*.*' -InitialDirectory $initialDirectory -FileName $fileName
|
||||
if (-not [string]::IsNullOrWhiteSpace($selectedPath)) {
|
||||
$localState.Controls.txtUnattendX64FilePath.Text = $selectedPath
|
||||
}
|
||||
})
|
||||
$State.Controls.btnBrowseUnattendArm64FilePath.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
$localState = $window.Tag
|
||||
$currentUnattendArm64FilePath = $localState.Controls.txtUnattendArm64FilePath.Text
|
||||
if ([string]::IsNullOrWhiteSpace($currentUnattendArm64FilePath)) {
|
||||
$currentUnattendArm64FilePath = Get-DefaultUnattendFilePath -FFUDevelopmentPath $localState.Controls.txtFFUDevPath.Text -WindowsArch 'arm64'
|
||||
}
|
||||
$initialDirectory = if ([string]::IsNullOrWhiteSpace($currentUnattendArm64FilePath)) {
|
||||
$null
|
||||
}
|
||||
else {
|
||||
Split-Path $currentUnattendArm64FilePath -Parent
|
||||
}
|
||||
$fileName = if ([string]::IsNullOrWhiteSpace($currentUnattendArm64FilePath)) { 'unattend_arm64.xml' } else { Split-Path $currentUnattendArm64FilePath -Leaf }
|
||||
$selectedPath = Invoke-BrowseAction -Type 'OpenFile' -Title 'Select arm64 unattend XML file' -Filter 'XML files (*.xml)|*.xml|All files (*.*)|*.*' -InitialDirectory $initialDirectory -FileName $fileName
|
||||
if (-not [string]::IsNullOrWhiteSpace($selectedPath)) {
|
||||
$localState.Controls.txtUnattendArm64FilePath.Text = $selectedPath
|
||||
}
|
||||
})
|
||||
$State.Controls.btnSaveDeviceNamePrefixes.Add_Click({
|
||||
param($eventSource, $routedEventArgs)
|
||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||
|
||||
@@ -220,6 +220,10 @@ function Initialize-UIControls {
|
||||
$State.Controls.chkAllowVHDXCaching = $window.FindName('chkAllowVHDXCaching')
|
||||
$State.Controls.chkCreateDeploymentMedia = $window.FindName('chkCreateDeploymentMedia')
|
||||
$State.Controls.chkInjectUnattend = $window.FindName('chkInjectUnattend')
|
||||
$State.Controls.txtUnattendX64FilePath = $window.FindName('txtUnattendX64FilePath')
|
||||
$State.Controls.btnBrowseUnattendX64FilePath = $window.FindName('btnBrowseUnattendX64FilePath')
|
||||
$State.Controls.txtUnattendArm64FilePath = $window.FindName('txtUnattendArm64FilePath')
|
||||
$State.Controls.btnBrowseUnattendArm64FilePath = $window.FindName('btnBrowseUnattendArm64FilePath')
|
||||
$State.Controls.rbDeviceNamingNone = $window.FindName('rbDeviceNamingNone')
|
||||
$State.Controls.rbDeviceNamingPrompt = $window.FindName('rbDeviceNamingPrompt')
|
||||
$State.Controls.rbDeviceNamingTemplate = $window.FindName('rbDeviceNamingTemplate')
|
||||
@@ -387,6 +391,8 @@ function Initialize-UIDefaults {
|
||||
$State.Controls.chkOptimize.IsChecked = $State.Defaults.generalDefaults.Optimize
|
||||
$State.Controls.chkAllowVHDXCaching.IsChecked = $State.Defaults.generalDefaults.AllowVHDXCaching
|
||||
$State.Controls.chkInjectUnattend.IsChecked = $State.Defaults.generalDefaults.InjectUnattend
|
||||
$State.Controls.txtUnattendX64FilePath.Text = $State.Defaults.generalDefaults.UnattendX64FilePath
|
||||
$State.Controls.txtUnattendArm64FilePath.Text = $State.Defaults.generalDefaults.UnattendArm64FilePath
|
||||
$State.Controls.chkCreateDeploymentMedia.IsChecked = $State.Defaults.generalDefaults.CreateDeploymentMedia
|
||||
$State.Controls.chkAllowExternalHardDiskMedia.IsChecked = $State.Defaults.generalDefaults.AllowExternalHardDiskMedia
|
||||
$State.Controls.chkPromptExternalHardDiskMedia.IsChecked = $State.Defaults.generalDefaults.PromptExternalHardDiskMedia
|
||||
|
||||
@@ -112,6 +112,8 @@ function Get-GeneralDefaults {
|
||||
$userAppListPath = Join-Path -Path $appsPath -ChildPath "UserAppList.json"
|
||||
$driversJsonPath = Join-Path -Path $driversPath -ChildPath "Drivers.json"
|
||||
$deviceNamePrefixesPath = Join-Path -Path $unattendPath -ChildPath "prefixes.txt"
|
||||
$unattendX64FilePath = Join-Path -Path $unattendPath -ChildPath "unattend_x64.xml"
|
||||
$unattendArm64FilePath = Join-Path -Path $unattendPath -ChildPath "unattend_arm64.xml"
|
||||
|
||||
return [PSCustomObject]@{
|
||||
# Build Tab Defaults
|
||||
@@ -134,6 +136,8 @@ function Get-GeneralDefaults {
|
||||
CopyUnattend = $false
|
||||
CopyPPKG = $false
|
||||
InjectUnattend = $false
|
||||
UnattendX64FilePath = $unattendX64FilePath
|
||||
UnattendArm64FilePath = $unattendArm64FilePath
|
||||
DeviceNamingMode = 'None'
|
||||
DeviceNameTemplate = ''
|
||||
DeviceNamePrefixesPath = $deviceNamePrefixesPath
|
||||
|
||||
Binary file not shown.
+23
-11
@@ -283,11 +283,23 @@ The deployment media is saved as an ISO file at `$FFUDevelopmentPath\WinPE_FFU_D
|
||||
>
|
||||
> If you just need to re-create deployment media, you can use the `Create-PEMedia.ps1` script to regenerate the deploy ISO without running a full build.
|
||||
|
||||
## Unattend.xml Options Expander
|
||||
|
||||
Use the **Unattend.xml Options** expander to choose how unattend content is staged and which source XML file FFU Builder should use for x64 and arm64 builds.
|
||||
|
||||
### x64 Unattend File Path
|
||||
|
||||
Use **x64 Unattend File Path** to browse to the source XML file for x64 builds. The default path is `.\FFUDevelopment\unattend\unattend_x64.xml`.
|
||||
|
||||
### arm64 Unattend File Path
|
||||
|
||||
Use **arm64 Unattend File Path** to browse to the source XML file for arm64 builds. The default path is `.\FFUDevelopment\unattend\unattend_arm64.xml`.
|
||||
|
||||
### Inject Unattend.xml
|
||||
|
||||
Controls the `-InjectUnattend` parameter. When checked, copies the architecture-specific unattend XML file from `.\FFUDevelopment\unattend` into the Apps ISO so it's baked into the FFU during the VM build process. The default is **unchecked**.
|
||||
Controls the `-InjectUnattend` parameter. When checked, stages the XML file selected for the current architecture in **Unattend.xml Options** into the Apps ISO so it's baked into the FFU during the VM build process. The default is **unchecked**.
|
||||
|
||||
This option is only available when **Install Apps** is checked.
|
||||
This option is used only when **Install Apps** is checked.
|
||||
|
||||
`Copy Unattend.xml` and `Inject Unattend.xml` are mutually exclusive. Select only one.
|
||||
|
||||
@@ -295,18 +307,16 @@ This option is only available when **Install Apps** is checked.
|
||||
|
||||
When enabled, the build process:
|
||||
|
||||
1. Determines the correct unattend file based on the target architecture:
|
||||
* **unattend_x64.xml** for x64 builds
|
||||
* **unattend_arm64.xml** for arm64 builds
|
||||
1. Uses the x64 or arm64 source file selected in **Unattend.xml Options** for the current build architecture
|
||||
2. Creates an `Unattend` folder inside `.\FFUDevelopment\Apps` if it doesn't exist
|
||||
3. Copies the architecture-specific unattend file to `.\FFUDevelopment\Apps\Unattend\Unattend.xml`
|
||||
3. Copies that file to `.\FFUDevelopment\Apps\Unattend\Unattend.xml`
|
||||
4. Includes the unattend file in the Apps ISO, making it available to sysprep during the VM build
|
||||
|
||||
The unattend file is then used by sysprep during the specialize phase and/or other OOBE phases when the FFU is deployed.
|
||||
|
||||
#### Creating Your Unattend Files
|
||||
|
||||
Modify the architecture-specific unattend file in the `.\FFUDevelopment\unattend` folder:
|
||||
You can keep the default architecture-specific files in the `.\FFUDevelopment\unattend` folder or browse to another XML file in the UI:
|
||||
|
||||
| File | Description |
|
||||
| ---------------------------- | ----------------------------------- |
|
||||
@@ -317,7 +327,7 @@ Modify the architecture-specific unattend file in the `.\FFUDevelopment\unattend
|
||||
|
||||
> Important
|
||||
>
|
||||
> Keep the file names with the architecture suffix (e.g., unattend_x64.xml). The script handles renaming the file to `Unattend.xml` when copying it to the Apps folder.
|
||||
> The default paths use the architecture suffix file names shown above. FFU Builder still renames the selected file to `Unattend.xml` when it stages it into the Apps folder.
|
||||
|
||||
#### When to Use This Option
|
||||
|
||||
@@ -516,15 +526,17 @@ This leverages the Autopilot for existing devices json file. It's not recommende
|
||||
|
||||
### Copy Unattend.xml
|
||||
|
||||
Controls the `-CopyUnattend` parameter. When checked, copies the architecture-appropriate unattend XML file from `.\FFUDevelopment\Unattend` to an `Unattend` folder on the Deployment partition of the USB drive. The default is **unchecked**.
|
||||
Controls the `-CopyUnattend` parameter. When checked, stages the XML file selected for the current architecture in **Unattend.xml Options** to an `Unattend` folder on the Deployment partition of the USB drive. The default is **unchecked**.
|
||||
|
||||
This option is only available when **Build USB Drive** is checked.
|
||||
Use this option when you plan to build deployment USB media.
|
||||
|
||||
When enabled, the build process copies:
|
||||
|
||||
- **unattend_x64.xml** (for x64 builds) or **unattend_arm64.xml** (for arm64 builds) → renamed to **Unattend.xml** on the USB drive
|
||||
- The selected x64 or arm64 unattend XML file → renamed to **Unattend.xml** on the USB drive
|
||||
- **prefixes.txt** → created from the **Device Naming** prefixes list when that mode is selected
|
||||
|
||||
If you keep the default file paths in place, FFU Builder uses `unattend_x64.xml` for x64 builds and `unattend_arm64.xml` for arm64 builds.
|
||||
|
||||
During deployment, `ApplyFFU.ps1` applies `Unattend.xml` whenever it is present. Device naming only happens when the **Device Naming** setting requires it, or when older media still uses the legacy prompt-based workflow.
|
||||
|
||||
See **Device Naming Expander** above for the available computer-name modes and prefixes-file behavior.
|
||||
|
||||
@@ -38,12 +38,14 @@ This table lists all top-level parameters in BuildFFUVM.ps1.
|
||||
| -CopyDrivers | bool | Copy Drivers to USB drive | When set to $true, will copy the drivers from the $FFUDevelopmentPath\Drivers folder to the Drivers folder on the deploy partition of the USB drive. Default is $false. |
|
||||
| -CopyPEDrivers | bool | Copy PE Drivers | When set to $true, enables adding WinPE drivers. By default copies drivers from $FFUDevelopmentPath\PEDrivers to the WinPE deployment media unless -UseDriversAsPEDrivers is also $true. |
|
||||
| -CopyPPKG | bool | Copy Provisioning Package | When set to $true, will copy the provisioning package from the $FFUDevelopmentPath\PPKG folder to the Deployment partition of the USB drive. Default is $false. |
|
||||
| -CopyUnattend | bool | Copy Unattend.xml | When set to $true, will copy the $FFUDevelopmentPath\Unattend folder to the Deployment partition of the USB drive. Cannot be used together with -InjectUnattend. Default is $false. |
|
||||
| -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. |
|
||||
| -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. |
|
||||
| -UnattendArm64FilePath | string | arm64 Unattend File Path | Path to the arm64 unattend XML source file used by Copy Unattend.xml and Inject Unattend.xml. Default is $FFUDevelopmentPath\Unattend\unattend_arm64.xml. |
|
||||
| -DeviceNamePrefixes | string[] | Specify a list of Prefixes | Sets the prefixes used when DeviceNamingMode is Prefixes. Each entry becomes a line in prefixes.txt on the deployment media. |
|
||||
| -Disksize | uint64 | Disk Size (GB) | Size of the virtual hard disk for the virtual machine. Default is a 50GB dynamic disk. |
|
||||
| -DriversFolder | string | Drivers Folder | Path to the drivers folder. Default is $FFUDevelopmentPath\Drivers. |
|
||||
@@ -54,7 +56,7 @@ This table lists all top-level parameters in BuildFFUVM.ps1.
|
||||
| -FFUDevelopmentPath | string | FFU Development Path | Path to the FFU development folder. Default is $PSScriptRoot. |
|
||||
| -FFUPrefix | string | VM Name Prefix | Prefix for the generated FFU file. Default is _FFU. |
|
||||
| -Headers | hashtable | CLI only (no UI control) | Headers to use when downloading files. Not recommended to modify. |
|
||||
| -InjectUnattend | bool | Inject Unattend.xml | When set to $true and InstallApps is also $true, copies unattend_[arch].xml from $FFUDevelopmentPath\unattend to $FFUDevelopmentPath\Apps\Unattend\Unattend.xml so sysprep can use it inside the VM. Cannot be used together with -CopyUnattend. Default is $false. |
|
||||
| -InjectUnattend | bool | Inject Unattend.xml | When set to $true and InstallApps is also $true, stages the selected architecture-specific unattend XML file to $FFUDevelopmentPath\Apps\Unattend\Unattend.xml so sysprep can use it inside the VM. Cannot be used together with -CopyUnattend. Default is $false. |
|
||||
| -InstallApps | bool | Install Applications | When set to $true, the script will create an Apps.iso file from the $FFUDevelopmentPath\Apps folder. It will also create a VM, mount the Apps.iso, install the apps, sysprep, and capture the VM. When set to $false, the FFU is created from a VHDX file, and no VM is created. |
|
||||
| -InstallDrivers | bool | Install Drivers to FFU | Install device drivers from the specified $FFUDevelopmentPath\Drivers folder if set to $true. Download the drivers and put them in the Drivers folder. The script will recurse the drivers folder and add the drivers to the FFU. |
|
||||
| -InstallOffice | bool | Install Office | Install Microsoft Office if set to $true. The script will download the latest ODT and Office files in the $FFUDevelopmentPath\Apps\Office folder and install Office in the FFU via VM. |
|
||||
|
||||
Reference in New Issue
Block a user