Compare commits

..

2 Commits

Author SHA1 Message Date
rbalsleyMSFT 7b6b5efd8d Merge branch 'main' of https://github.com/rbalsleyMSFT/FFU 2025-01-10 13:50:03 -08:00
rbalsleyMSFT db62e05275 Bug fixes
- Fixed an issue with WinPE Drivers not being added to Deployment media
- Fixed an issue where Windows SKUs that include spaces in their names (e.g. Pro Education) and `$InstallApps $false`, FFU creation would fail due to the name including a space. Added a new function `Get-ShortenedWindowsSKU` to truncate the SKU for FFU name creation purposes. This required various changes throughout the script that relied on the Windows SKU for naming.
- Updated version 2412.3
2025-01-10 13:50:00 -08:00
2 changed files with 84 additions and 34 deletions
+83 -33
View File
@@ -361,7 +361,7 @@ param(
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[string]$ExportConfigFile [string]$ExportConfigFile
) )
$version = '2412.1' $version = '2412.3'
# If a config file is specified and it exists, load it # If a config file is specified and it exists, load it
if ($ConfigFile -and (Test-Path -Path $ConfigFile)) { if ($ConfigFile -and (Test-Path -Path $ConfigFile)) {
@@ -557,7 +557,7 @@ function Invoke-Process {
[Parameter()] [Parameter()]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[string]$ArgumentList, [string[]]$ArgumentList,
[Parameter()] [Parameter()]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
@@ -3053,7 +3053,7 @@ function New-PEMedia {
if ($CopyPEDrivers) { if ($CopyPEDrivers) {
WriteLog "Adding drivers to WinPE media" WriteLog "Adding drivers to WinPE media"
try { try {
Add-WindowsDriver -Path "$WinPEFFUPath\Mount" -Driver "$FFUDevelopmentPath\$PEDriversFolder" -Recurse -ErrorAction SilentlyContinue | Out-null Add-WindowsDriver -Path "$WinPEFFUPath\Mount" -Driver "$PEDriversFolder" -Recurse -ErrorAction SilentlyContinue | Out-null
} }
catch { catch {
WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.' WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.'
@@ -3126,14 +3126,57 @@ function Optimize-FFUCaptureDrive {
throw $_ throw $_
} }
} }
function Get-ShortenedWindowsSKU {
param (
[string]$WindowsSKU
)
$shortenedWindowsSKU = switch ($WindowsSKU) {
'Core' { 'Home' }
'CoreN' { 'Home_N' }
'CoreSingleLanguage' { 'Home_SL' }
'Education' { 'Edu' }
'EducationN' { 'Edu_N' }
'Professional' { 'Pro' }
'ProfessionalN' { 'Pro_N' }
'ProfessionalEducation' { 'Pro_Edu' }
'ProfessionalEducationN' { 'Pro_Edu_N' }
'ProfessionalWorkstation' { 'Pro_WKS' }
'ProfessionalWorkstationN' { 'Pro_WKS_N' }
'Enterprise' { 'Ent' }
'EnterpriseN' { 'Ent_N' }
'ServerStandard' { 'Srv_Std' }
'ServerDatacenter' { 'Srv_Dtc' }
'Home' { 'Home' }
'Home N' { 'Home_N' }
'Home Single Language' { 'Home_SL' }
'Education' { 'Edu' }
'Education N' { 'Edu_N' }
'Professional' { 'Pro' }
'Pro N' { 'Pro_N' }
'Pro Education' { 'Pro_Edu' }
'Pro Education N' { 'Pro_Edu_N' }
'Pro for Workstations' { 'Pro_WKS' }
'Pro N for Workstations' { 'Pro_WKS_N' }
'Enterprise' { 'Ent' }
'Enterprise N' { 'Ent_N' }
'Standard' { 'Srv_Std' }
'Standard (Desktop Experience)' { 'Srv_Std_DE' }
'Datacenter' { 'Srv_Dtc' }
'Datacenter (Desktop Experience)' { 'Srv_Dtc_DE' }
}
return $shortenedWindowsSKU
}
function New-FFUFileName { function New-FFUFileName {
$BuildDate = Get-Date -uformat %b%Y $BuildDate = Get-Date -uformat %b%Y
# Replace '{WindowsRelease}' with the Windows release (e.g., 10, 11, 2016, 2019, 2022, 2025) # Replace '{WindowsRelease}' with the Windows release (e.g., 10, 11, 2016, 2019, 2022, 2025)
$CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{WindowsRelease}', $WindowsRelease $CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{WindowsRelease}', $WindowsRelease
# Replace '{WindowsVersion}' with the Windows version (e.g., 1607, 1809, 21h2, 22h2, 23h2, 24h2, etc) # Replace '{WindowsVersion}' with the Windows version (e.g., 1607, 1809, 21h2, 22h2, 23h2, 24h2, etc)
$CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{WindowsVersion}', $WindowsVersion $CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{WindowsVersion}', $WindowsVersion
# Replace '{SKU}' with the SKU of the Windows image (e.g., Pro, Enterprise, etc.) # Replace '{SKU}' with the SKU of the Windows image (e.g., Pro, Enterprise, etc.)
$CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{SKU}', $SKU $CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{SKU}', $shortenedWindowsSKU
# Replace '{BuildDate}' with the current month and year (e.g., Jan2023) # Replace '{BuildDate}' with the current month and year (e.g., Jan2023)
$CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{BuildDate}', $BuildDate $CustomFFUNameTemplate = $CustomFFUNameTemplate -replace '{BuildDate}', $BuildDate
# Replace '{yyyy}' with the current year in 4-digit format (e.g., 2023) # Replace '{yyyy}' with the current year in 4-digit format (e.g., 2023)
@@ -3199,42 +3242,44 @@ function New-FFU {
} }
} }
elseif (-not $InstallApps -and (-not $AllowVHDXCaching)) { elseif (-not $InstallApps -and (-not $AllowVHDXCaching)) {
#Get Windows Version Information from the VHDX
$winverinfo = Get-WindowsVersionInfo
WriteLog 'Creating FFU File Name'
if ($CustomFFUNameTemplate) { if ($CustomFFUNameTemplate) {
$FFUFileName = New-FFUFileName $FFUFileName = New-FFUFileName
} }
else{ else{
#Get Windows Version Information from the VHDX $FFUFileName = "$($winverinfo.Name)`_$($winverinfo.DisplayVersion)`_$($shortenedWindowsSKU)`_$($winverinfo.BuildDate).ffu"
$winverinfo = Get-WindowsVersionInfo
$FFUFileName = "$($winverinfo.Name)`_$($winverinfo.DisplayVersion)`_$($winverinfo.SKU)`_$($winverinfo.BuildDate).ffu"
} }
WriteLog "FFU file name: $FFUFileName" WriteLog "FFU file name: $FFUFileName"
$FFUFile = "$FFUCaptureLocation\$FFUFileName" $FFUFile = "$FFUCaptureLocation\$FFUFileName"
#Capture the FFU #Capture the FFU
Invoke-Process cmd "/c ""$DandIEnv"" && dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($winverinfo.SKU) /Compress:Default" | Out-Null WriteLog 'Capturing FFU'
# Invoke-Process cmd "/c dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($winverinfo.SKU) /Compress:Default" | Out-Null Invoke-Process cmd "/c ""$DandIEnv"" && dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($shortenedWindowsSKU) /Compress:Default" | Out-Null
WriteLog 'FFU Capture complete' WriteLog 'FFU Capture complete'
Dismount-ScratchVhdx -VhdxPath $VHDXPath Dismount-ScratchVhdx -VhdxPath $VHDXPath
} }
elseif (-not $InstallApps -and $AllowVHDXCaching) { elseif (-not $InstallApps -and $AllowVHDXCaching) {
# Make $FFUFileName based on values in the config.json file # Make $FFUFileName based on values in the config.json file
WriteLog 'Creating FFU File Name'
if ($CustomFFUNameTemplate) { if ($CustomFFUNameTemplate) {
$FFUFileName = New-FFUFileName $FFUFileName = New-FFUFileName
} else { }
else {
$BuildDate = Get-Date -UFormat %b%Y $BuildDate = Get-Date -UFormat %b%Y
# Get Windows Information to make the FFU file name from the cachedVHDXInfo file # Get Windows Information to make the FFU file name from the cachedVHDXInfo file
if ($installationType -eq 'Client') { if ($installationType -eq 'Client') {
$FFUFileName = "Win$($cachedVHDXInfo.WindowsRelease)`_$($cachedVHDXInfo.WindowsVersion)`_$($cachedVHDXInfo.WindowsSKU)`_$BuildDate.ffu" $FFUFileName = "Win$($cachedVHDXInfo.WindowsRelease)`_$($cachedVHDXInfo.WindowsVersion)`_$($shortenedWindowsSKU)`_$BuildDate.ffu"
} else { }
$FFUFileName = "Server$($cachedVHDXInfo.WindowsRelease)`_$($cachedVHDXInfo.WindowsVersion)`_$($cachedVHDXInfo.WindowsSKU)`_$BuildDate.ffu" else {
$FFUFileName = "Server$($cachedVHDXInfo.WindowsRelease)`_$($cachedVHDXInfo.WindowsVersion)`_$($shortenedWindowsSKU)`_$BuildDate.ffu"
} }
} }
WriteLog "FFU file name: $FFUFileName" WriteLog "FFU file name: $FFUFileName"
$FFUFile = "$FFUCaptureLocation\$FFUFileName" $FFUFile = "$FFUCaptureLocation\$FFUFileName"
#Dismount the VHDX
#Capture the FFU #Capture the FFU
Invoke-Process cmd "/c ""$DandIEnv"" && dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($cachedVHDXInfo.WindowsRelease)$($cachedVHDXInfo.WindowsVersion)$($cachedVHDXInfo.WindowsSKU) /Compress:Default" | Out-Null WriteLog 'Capturing FFU'
# Invoke-Process cmd "/c dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($winverinfo.SKU) /Compress:Default" | Out-Null Invoke-Process cmd "/c ""$DandIEnv"" && dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($cachedVHDXInfo.WindowsRelease)$($cachedVHDXInfo.WindowsVersion)$($shortenedWindowsSKU) /Compress:Default" | Out-Null
WriteLog 'FFU Capture complete' WriteLog 'FFU Capture complete'
Dismount-ScratchVhdx -VhdxPath $VHDXPath Dismount-ScratchVhdx -VhdxPath $VHDXPath
} }
@@ -3356,8 +3401,8 @@ Function Get-WindowsVersionInfo {
Invoke-Process reg "load HKLM\FFU $Software" | Out-Null Invoke-Process reg "load HKLM\FFU $Software" | Out-Null
#Find Windows version values #Find Windows version values
$SKU = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'EditionID' # $WindowsSKU = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'EditionID'
WriteLog "Windows SKU: $SKU" # WriteLog "Windows SKU: $WindowsSKU"
[int]$CurrentBuild = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'CurrentBuild' [int]$CurrentBuild = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'CurrentBuild'
WriteLog "Windows Build: $CurrentBuild" WriteLog "Windows Build: $CurrentBuild"
#DisplayVersion does not exist for 1607 builds (RS1 and Server 2016) and Server 2019 #DisplayVersion does not exist for 1607 builds (RS1 and Server 2016) and Server 2019
@@ -3368,19 +3413,18 @@ Function Get-WindowsVersionInfo {
$BuildDate = Get-Date -uformat %b%Y $BuildDate = Get-Date -uformat %b%Y
$SKU = switch ($SKU) { # $WindowsSKU = switch ($WindowsSKU) {
Core { 'Home' } # Core { 'Home' }
Professional { 'Pro' } # Professional { 'Pro' }
ProfessionalEducation { 'Pro_Edu' } # ProfessionalEducation { 'Pro_Edu' }
Enterprise { 'Ent' } # Enterprise { 'Ent' }
Education { 'Edu' } # Education { 'Edu' }
ProfessionalWorkstation { 'Pro_Wks' } # ProfessionalWorkstation { 'Pro_Wks' }
ServerStandard { 'Srv_Std' } # ServerStandard { 'Srv_Std' }
ServerDatacenter { 'Srv_Dtc' } # ServerDatacenter { 'Srv_Dtc' }
} # }
WriteLog "Windows SKU Modified to: $SKU"
if ($SKU -notmatch "Srv") { if ($shortenedWindowsSKU -notmatch "Srv") {
if ($CurrentBuild -ge 22000) { if ($CurrentBuild -ge 22000) {
$Name = 'Win11' $Name = 'Win11'
} }
@@ -3409,7 +3453,7 @@ Function Get-WindowsVersionInfo {
DisplayVersion = $DisplayVersion DisplayVersion = $DisplayVersion
BuildDate = $buildDate BuildDate = $buildDate
Name = $Name Name = $Name
SKU = $SKU # SKU = $WindowsSKU
} }
} }
Function Get-USBDrive { Function Get-USBDrive {
@@ -4244,7 +4288,8 @@ if (($make -and $model) -and ($installdrivers -or $copydrivers)) {
try { try {
$adkPath = Get-ADK $adkPath = Get-ADK
#Need to use the Deployment and Imaging tools environment to use dism from the Sept 2023 ADK to optimize FFU #Need to use the Deployment and Imaging tools environment to use dism from the Sept 2023 ADK to optimize FFU
$DandIEnv = "$adkPath`Assessment and Deployment Kit\Deployment Tools\DandISetEnv.bat" $DandIEnv = Join-Path $adkPath "Assessment and Deployment Kit\Deployment Tools\DandISetEnv.bat"
} }
catch { catch {
WriteLog 'ADK not found' WriteLog 'ADK not found'
@@ -4896,6 +4941,11 @@ try {
New-FFU $FFUVM.Name New-FFU $FFUVM.Name
} }
else { else {
#Shorten Windows SKU for use in FFU file name to remove spaces and long names
WriteLog 'Shortening Windows SKU for FFU file name'
$shortenedWindowsSKU = Get-ShortenedWindowsSKU -WindowsSKU $WindowsSKU
WriteLog "Shortened Windows SKU: $shortenedWindowsSKU"
#Create FFU file
New-FFU New-FFU
} }
} }
@@ -135,7 +135,7 @@ $LogFileName = 'ScriptLog.txt'
$USBDrive = Get-USBDrive $USBDrive = Get-USBDrive
New-item -Path $USBDrive -Name $LogFileName -ItemType "file" -Force | Out-Null New-item -Path $USBDrive -Name $LogFileName -ItemType "file" -Force | Out-Null
$LogFile = $USBDrive + $LogFilename $LogFile = $USBDrive + $LogFilename
$version = '2412.1' $version = '2412.3'
WriteLog 'Begin Logging' WriteLog 'Begin Logging'
WriteLog "Script version: $version" WriteLog "Script version: $version"