mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 10:19:36 -06:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e95ff92b1 | |||
| d4274d54d2 | |||
| aee33a6a4b | |||
| 25a0928195 | |||
| d809fc021f | |||
| 582df6e3a8 | |||
| d5a4f96482 | |||
| d2fc9cf558 | |||
| b530ac5a5c | |||
| 2659336ee9 | |||
| c32a09bfc1 | |||
| f7ff415374 | |||
| 9cac674d7b | |||
| 2cf7da9c91 | |||
| 0d1d3a1ed5 | |||
| 7e2ebe8013 | |||
| 0606a1278c | |||
| 7c9f24f695 | |||
| 227fb4fa94 | |||
| 77ef154941 | |||
| a00aa3ee02 | |||
| 7b6b5efd8d | |||
| db62e05275 | |||
| e25a890946 | |||
| bc4a181182 |
@@ -1,5 +1,58 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
# 2505.1
|
||||||
|
|
||||||
|
Highly recommended that you upgrade to this release. Fixes the issue with the May 2025 cumulative update and some SKU naming issues for SKUs other than Pro.
|
||||||
|
|
||||||
|
# Support for Windows LTSB/LTSC
|
||||||
|
Thanks to @zehadialam for the code to allow support for LTSB and LTSC. This has been a requested feature from a number of customers and some might be opting for LTSC when Windows 10 support ends in October. We support LTSB 2016, LTSC 2019, 2021, 2024 including the N and IoT variants. Extensive testing has gone into validating CU and .net support. File an issue if you see any weird behavior.
|
||||||
|
|
||||||
|
# Support for automating computer naming via CSV
|
||||||
|
Thanks to @JonasKloseBW for PR #150
|
||||||
|
- Allows setting the computer name with a predefined list (SerialComputerNames.csv) of serial numbers and matching computer names
|
||||||
|
- Defaults to FFU-{Random} if no matching serial number is found in list so FFU deployment can continue without user input
|
||||||
|
|
||||||
|
# Fixes
|
||||||
|
- Thanks to @JonasKloseBW for PR #129 for adding the -AppListPath parameter
|
||||||
|
- Fixed an issue where if AppsScriptVariables was configured in a config file, the hashtable wasn't being created by the script when setting the variable.
|
||||||
|
- Fixed a crash where shortening the Windows SKU was creating duplicate shortened names for certain SKUs (EDU mainly, but others too)
|
||||||
|
- Fix an issue with checkpoint CUs and May 2025-05B CU. Should future proof new checkpoint CUs in the future.
|
||||||
|
|
||||||
|
# Additional Fixes
|
||||||
|
BuildFFUVM.ps1
|
||||||
|
- Added parameter definitions that were missing:
|
||||||
|
- AppListPath - Path to a JSON file containing a list of applications to install using WinGet. Default is $FFUDevelopmentPath\Apps\AppList.json.
|
||||||
|
- PEDriversFolder - Path to the folder containing drivers to be injected into the WinPE deployment media. Default is $FFUDevelopmentPath\PEDrivers.
|
||||||
|
- Added two new parameters:
|
||||||
|
- UpdateLatestMicrocode - This is used for Windows 10/Server. When set to $true, will download and install the latest microcode updates for applicable Windows releases (e.g., Windows Server 2016/2019, Windows 10 LTSC 2016/2019) into the FFU. Default is $false.
|
||||||
|
- UpdateADK - Added for airgapped scenarios where you've manually updated the ADK and don't need it to continually check. When set to $true, the script will check for and install the latest Windows ADK and WinPE add-on if they are not already installed or up-to-date. Default is $true.
|
||||||
|
- Reorganized the WindowsSKU validateset to make it easier to read and added in 2016 LTSB releases
|
||||||
|
- Changed version to 2505.1
|
||||||
|
- Reorganized the releasetoMapping SKUs to make it easier to read
|
||||||
|
- Omitted Defender/Edge from reporting KB ID since neither includes it
|
||||||
|
- Updated Save-KB with some enhancements from the UI branch which will handle KBs that don't have an architecture defined in their file name that will leverage a new function Get-PEArchitecture that can interrogate the file name and determine the correct architecture
|
||||||
|
- Updated Get-ShortenedWindowsSKU with LTSB/LTSC SKUs
|
||||||
|
- Updated New-FFUFileName to use $winverinfo.Name for $WindowsRelease for client OSes to which will set $WindowsRelease to using Win10 or Win11. This fixes a bug where you might see 10 or 11 instead of Win10 or Win11 for FFU builds that use only the VHDX (e.g. `-InstallApps $false`. This keeps the naming consistent with FFUs built via VM.
|
||||||
|
- Updated Get-WindowsVersionInfo to fix an issue with naming LTSC 2019
|
||||||
|
- Added Get-PEArchitecture function
|
||||||
|
- Commented out the Windows Security Platform Update code since the URL is dead for the content. This is fixed in the UI branch and will be reintroduced in Dev and Main at a later date when the UI work is complete.
|
||||||
|
- Created a new variable `$isLTSC`
|
||||||
|
- Modified and reorganized the search strings for the various .net framework components. LTSC introduced some complexity with handling the various .net releases.
|
||||||
|
- VHDXCaching will now recurse the KBPath folder when finding downloaded KBs to include in its config file
|
||||||
|
|
||||||
|
Sample_default.json
|
||||||
|
- Added new/missing parameters
|
||||||
|
- ApplistPath
|
||||||
|
- UpdateADK
|
||||||
|
- UpdateLatestMicrocode
|
||||||
|
|
||||||
|
CaptureFFU.ps1
|
||||||
|
- `$WindowsVersion` 2016 and 2019 for LTSC releases
|
||||||
|
- Changed some SKU spacing to make things more consistent and included Enterprise N LTSC
|
||||||
|
|
||||||
|
ApplyFFU.ps1
|
||||||
|
- Updated version to 2505.1
|
||||||
|
|
||||||
# 2412.1
|
# 2412.1
|
||||||
|
|
||||||
This is a major release with a number of quality-of-life improvements that will reduce the time it takes to create FFUs. I highly recommend you update to this release.
|
This is a major release with a number of quality-of-life improvements that will reduce the time it takes to create FFUs. I highly recommend you update to this release.
|
||||||
|
|||||||
+583
-133
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
|||||||
#Modify the net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user ddb1f077-3eed-433c-b4d9-7b8cd54ce727
|
#Modify the net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user ddb1f077-3eed-433c-b4d9-7b8cd54ce727
|
||||||
net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user ddb1f077-3eed-433c-b4d9-7b8cd54ce727
|
net use W: \\192.168.1.158\FFUCaptureShare /user:ffu_user ddb1f077-3eed-433c-b4d9-7b8cd54ce727
|
||||||
#Custom naming placeholder
|
#Custom naming placeholder
|
||||||
|
|
||||||
$AssignDriveLetter = 'x:\AssignDriveLetter.txt'
|
$AssignDriveLetter = 'x:\AssignDriveLetter.txt'
|
||||||
Start-Process -FilePath diskpart.exe -ArgumentList "/S $AssignDriveLetter" -Wait -ErrorAction Stop | Out-Null
|
Start-Process -FilePath diskpart.exe -ArgumentList "/S $AssignDriveLetter" -Wait -ErrorAction Stop | Out-Null
|
||||||
#Load Registry Hive
|
#Load Registry Hive
|
||||||
@@ -12,26 +11,39 @@ reg load "HKLM\FFU" $Software
|
|||||||
|
|
||||||
$SKU = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'EditionID'
|
$SKU = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'EditionID'
|
||||||
[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'
|
||||||
if ($CurrentBuild -notin 14393, 17763) {
|
$InstallationType = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'InstallationType'
|
||||||
|
if ($CurrentBuild -notin 14393, 17763 -and $InstallationType -ne "Server") {
|
||||||
$WindowsVersion = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'DisplayVersion'
|
$WindowsVersion = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'DisplayVersion'
|
||||||
}
|
}
|
||||||
$InstallationType = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'InstallationType'
|
# For Windows 10 LTSB 2016, set WindowsVersion to 2016
|
||||||
|
if ($CurrentBuild -eq 14393 -and $InstallationType -eq "Client") {
|
||||||
|
$WindowsVersion = '2016'
|
||||||
|
}
|
||||||
|
# For Windows 10 LTSC 2019, set WindowsVersion to 2019
|
||||||
|
if ($CurrentBuild -eq 17763 -and $InstallationType -eq "Client") {
|
||||||
|
$WindowsVersion = '2019'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$BuildDate = Get-Date -uformat %b%Y
|
$BuildDate = Get-Date -uformat %b%Y
|
||||||
|
|
||||||
$SKU = switch ($SKU) {
|
$SKU = switch ($SKU) {
|
||||||
Core { 'Home' }
|
Core { 'Home' }
|
||||||
CoreN { 'HomeN' }
|
CoreN { 'Home_N' }
|
||||||
CoreSingleLanguage { 'HomeSL' }
|
CoreSingleLanguage { 'Home_SL' }
|
||||||
Professional { 'Pro' }
|
Professional { 'Pro' }
|
||||||
ProfessionalN { 'ProN' }
|
ProfessionalN { 'Pro_N' }
|
||||||
ProfessionalEducation { 'Pro_Edu' }
|
ProfessionalEducation { 'Pro_Edu' }
|
||||||
ProfessionalEducationN { 'Pro_EduN' }
|
ProfessionalEducationN { 'Pro_Edu_N' }
|
||||||
Enterprise { 'Ent' }
|
Enterprise { 'Ent' }
|
||||||
EnterpriseN { 'EntN' }
|
EnterpriseN { 'Ent_N' }
|
||||||
|
EnterpriseS { 'Ent_LTSC' }
|
||||||
|
EnterpriseSN { 'Ent_N_LTSC' }
|
||||||
|
IoTEnterpriseS { 'IoT_Ent_LTSC' }
|
||||||
Education { 'Edu' }
|
Education { 'Edu' }
|
||||||
EducationN { 'EduN' }
|
EducationN { 'Edu_N' }
|
||||||
ProfessionalWorkstation { 'Pro_Wks' }
|
ProfessionalWorkstation { 'Pro_Wks' }
|
||||||
ProfessionalWorkstationN { 'Pro_WksN' }
|
ProfessionalWorkstationN { 'Pro_Wks_N' }
|
||||||
ServerStandard { 'Srv_Std' }
|
ServerStandard { 'Srv_Std' }
|
||||||
ServerDatacenter { 'Srv_Dtc' }
|
ServerDatacenter { 'Srv_Dtc' }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 = '2505.2'
|
||||||
WriteLog 'Begin Logging'
|
WriteLog 'Begin Logging'
|
||||||
WriteLog "Script version: $version"
|
WriteLog "Script version: $version"
|
||||||
|
|
||||||
@@ -222,6 +222,7 @@ if (Test-Path -Path $PPKGFolder){
|
|||||||
$UnattendFolder = $USBDrive + "unattend\"
|
$UnattendFolder = $USBDrive + "unattend\"
|
||||||
$UnattendFilePath = $UnattendFolder + "unattend.xml"
|
$UnattendFilePath = $UnattendFolder + "unattend.xml"
|
||||||
$UnattendPrefixPath = $UnattendFolder + "prefixes.txt"
|
$UnattendPrefixPath = $UnattendFolder + "prefixes.txt"
|
||||||
|
$UnattendComputerNamePath = $UnattendFolder + "SerialComputerNames.csv"
|
||||||
If (Test-Path -Path $UnattendFilePath){
|
If (Test-Path -Path $UnattendFilePath){
|
||||||
$UnattendFile = Get-ChildItem -Path $UnattendFilePath
|
$UnattendFile = Get-ChildItem -Path $UnattendFilePath
|
||||||
If ($UnattendFile){
|
If ($UnattendFile){
|
||||||
@@ -234,6 +235,12 @@ If (Test-Path -Path $UnattendPrefixPath){
|
|||||||
$UnattendPrefix = $true
|
$UnattendPrefix = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
If (Test-Path -Path $UnattendComputerNamePath){
|
||||||
|
$UnattendComputerNameFile = Get-ChildItem -Path $UnattendComputerNamePath
|
||||||
|
If ($UnattendComputerNameFile){
|
||||||
|
$UnattendComputerName = $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#Ask for device name if unattend exists
|
#Ask for device name if unattend exists
|
||||||
if ($Unattend -and $UnattendPrefix){
|
if ($Unattend -and $UnattendPrefix){
|
||||||
@@ -278,7 +285,25 @@ if ($Unattend -and $UnattendPrefix){
|
|||||||
$computername = Set-Computername($computername)
|
$computername = Set-Computername($computername)
|
||||||
Writelog "Computer name set to $computername"
|
Writelog "Computer name set to $computername"
|
||||||
}
|
}
|
||||||
elseif($Unattend){
|
elseif($Unattend -and $UnattendComputerName){
|
||||||
|
Writelog 'Unattend file found with SerialComputerNames.csv. Getting name for current computer.'
|
||||||
|
$SerialComputerNames = Import-Csv -Path $UnattendComputerNameFile.FullName -Delimiter ","
|
||||||
|
|
||||||
|
$SerialNumber = (Get-CimInstance -Class Win32_Bios).SerialNumber
|
||||||
|
$SCName = $SerialComputerNames | Where-Object { $_.SerialNumber -eq $SerialNumber }
|
||||||
|
|
||||||
|
If ($SCName) {
|
||||||
|
[string]$computername = $SCName.ComputerName
|
||||||
|
$computername = Set-Computername($computername)
|
||||||
|
Writelog "Computer name set to $computername"
|
||||||
|
} else {
|
||||||
|
Writelog 'No matching serial number found in SerialComputerNames.csv. Setting random computer name to complete setup.'
|
||||||
|
[string]$computername = ("FFU-" + (-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 11 | ForEach-Object { [char]$_ })))
|
||||||
|
$computername = Set-Computername($computername)
|
||||||
|
Writelog "Computer name set to $computername"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($Unattend) {
|
||||||
Writelog 'Unattend file found with no prefixes.txt, asking for name'
|
Writelog 'Unattend file found with no prefixes.txt, asking for name'
|
||||||
[string]$computername = Read-Host 'Enter device name'
|
[string]$computername = Read-Host 'Enter device name'
|
||||||
Set-Computername($computername)
|
Set-Computername($computername)
|
||||||
|
|||||||
Binary file not shown.
@@ -1,3 +1,5 @@
|
|||||||
|
**Update 2025-08-01:** [2507.2 UI Preview is now available](https://github.com/rbalsleyMSFT/FFU/releases) - click the link to get the build and check out the Youtube walk-through.
|
||||||
|
|
||||||
# Using Full Flash Update (FFU) files to speed up Windows deployment
|
# Using Full Flash Update (FFU) files to speed up Windows deployment
|
||||||
|
|
||||||
What if you could have a Windows image (Windows 10/11 or Server) that has:
|
What if you could have a Windows image (Windows 10/11 or Server) that has:
|
||||||
@@ -18,10 +20,6 @@ And the best part: it takes less than two minutes to apply the image, even with
|
|||||||
|
|
||||||
The Full-Flash update (FFU) process can automatically download the latest release of Windows 11, the updates mentioned above, and creates a USB drive that can be used to quickly reimage a machine.
|
The Full-Flash update (FFU) process can automatically download the latest release of Windows 11, the updates mentioned above, and creates a USB drive that can be used to quickly reimage a machine.
|
||||||
|
|
||||||
# Updates
|
|
||||||
|
|
||||||
2412.1 has been released! Check out the changes in the [Change Log](ChangeLog.md)
|
|
||||||
|
|
||||||
# Getting Started
|
# Getting Started
|
||||||
|
|
||||||
- Download the latest [release](https://github.com/rbalsleyMSFT/FFU/releases)
|
- Download the latest [release](https://github.com/rbalsleyMSFT/FFU/releases)
|
||||||
|
|||||||
Reference in New Issue
Block a user