Compare commits

...

19 Commits

Author SHA1 Message Date
rbalsleyMSFT e8ba334732 Merge pull request #26 from rbalsleyMSFT/2405.1
2405.1
2024-05-24 18:24:07 -07:00
rbalsleyMSFT ff46c10d79 Update README.md 2024-05-24 18:22:21 -07:00
rbalsleyMSFT 4d9e1c1f88 Update README.md 2024-05-24 18:21:08 -07:00
rbalsleyMSFT d5b81bc482 Update README.md 2024-05-24 18:18:39 -07:00
rbalsleyMSFT 8f81e69159 Modify Resetbase command to use DandIEnv 2024-05-24 18:12:43 -07:00
rbalsleyMSFT 4932777f4f syntax cleanup 2024-05-24 18:06:06 -07:00
rbalsleyMSFT 12edabf213 Changed version to 2405.1 2024-05-24 15:29:05 -07:00
rbalsleyMSFT 1978736133 Merge pull request #25 from zehadialam/feature-reduce-ffu-size
Reducing FFU Size
2024-05-24 15:20:14 -07:00
rbalsleyMSFT a3faa89ada Merge branch '2405.1' into feature-reduce-ffu-size 2024-05-24 15:19:31 -07:00
rbalsleyMSFT fc8648eb65 Merge pull request #24 from MKellyCBSD/Move-location-of-Clean-Up-the-WinSxS-Folder-command
Move location of command that cleans up the WinSXS folder
2024-05-24 15:15:31 -07:00
Zehadi Alam 49a9fd49c1 Add Optimize-FFUCaptureDrive function and disk cleanup to InstallAppsandSysprep.cmd file 2024-05-20 20:09:26 -04:00
MKellyCBSD 3f4836b478 Update BuildFFUVM.ps1
Adding "-PreventPending" to the "add-windowspackage" command allows the dism cleanup of the winsxs folder command to be moved from the InstallAppsandSysprep.cmd script to right after the updates are added to the vhdx. The end result: 

FFU image size before: 11.836GB
FFU image size after: 11.190GB
2024-05-15 15:52:38 -04:00
MKellyCBSD 1921809c30 Update InstallAppsandSysprep.cmd
Remove this command because moving it up right after updates are applied to the scratch VHDX saves ~650MB on the final .ffu file.
2024-05-15 15:42:00 -04:00
rbalsleyMSFT 56f3e9d856 Update README.md 2024-05-03 15:35:31 -07:00
rbalsleyMSFT ae59183a19 update issue with downloading latest Windows CU 2024-05-03 15:32:11 -07:00
rbalsleyMSFT bfa1ea7d9f Update README.md 2024-04-18 16:17:17 -07:00
rbalsleyMSFT 5564473c3b Merge branch 'main' of https://github.com/rbalsleyMSFT/FFU 2024-04-18 16:11:58 -07:00
rbalsleyMSFT 393de977f2 2404.2 when imaging devices with 4096 logical sector sizes, will set $copydrivers to $true if $installdrivers set to $true 2024-04-18 16:10:16 -07:00
rbalsleyMSFT c051963ed5 Update README.md 2024-04-15 13:41:30 -07:00
4 changed files with 70 additions and 13 deletions
+17 -3
View File
@@ -15,8 +15,22 @@ del c:\windows\panther\unattend\unattend.xml /F /Q
del c:\windows\panther\unattend.xml /F /Q del c:\windows\panther\unattend.xml /F /Q
taskkill /IM sysprep.exe taskkill /IM sysprep.exe
timeout /t 10 timeout /t 10
REM Run Component Cleanup since dism /online /cleanup-image /analyzecomponentcleanup recommends it REM Run disk cleanup (cleanmgr.exe) with all options enabled: https://learn.microsoft.com/en-us/troubleshoot/windows-server/backup-and-storage/automating-disk-cleanup-tool
REM If adding latest CU, definitely need to do this to keep FFU size smaller set rootkey=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches
dism /online /cleanup-image /startcomponentcleanup /resetbase REM Per above doc, the Offline Pages Files subkey does not have stateflags value
for /f "tokens=*" %%K in ('reg query "%rootkey%"') do (
echo %%K | findstr /i /c:"Offline Pages Files"
if errorlevel 1 (
reg add "%%K" /v StateFlags0000 /t REG_DWORD /d 2 /f
)
)
cleanmgr.exe /sagerun:0
REM Remove the StateFlags0000 registry value
for /f "tokens=*" %%K in ('reg query "%rootkey%"') do (
echo %%K | findstr /i /c:"Offline Pages Files"
if errorlevel 1 (
reg delete "%%K" /v StateFlags0000 /f
)
)
REM Sysprep/Generalize REM Sysprep/Generalize
c:\windows\system32\sysprep\sysprep.exe /quiet /generalize /oobe c:\windows\system32\sysprep\sysprep.exe /quiet /generalize /oobe
+38 -8
View File
@@ -283,7 +283,7 @@ param(
[bool]$CleanupDeployISO = $true, [bool]$CleanupDeployISO = $true,
[bool]$CleanupAppsISO = $true [bool]$CleanupAppsISO = $true
) )
$version = '2404.1' $version = '2405.1'
#Check if Hyper-V feature is installed (requires only checks the module) #Check if Hyper-V feature is installed (requires only checks the module)
$osInfo = Get-WmiObject -Class Win32_OperatingSystem $osInfo = Get-WmiObject -Class Win32_OperatingSystem
@@ -1438,6 +1438,31 @@ function New-PEMedia {
Remove-Item -Path "$WinPEFFUPath" -Recurse -Force Remove-Item -Path "$WinPEFFUPath" -Recurse -Force
WriteLog 'Cleanup complete' WriteLog 'Cleanup complete'
} }
function Optimize-FFUCaptureDrive {
param (
[string]$VhdxPath
)
try {
WriteLog 'Mounting VHDX for volume optimization'
Mount-VHD -Path $VhdxPath
WriteLog 'Defragmenting Windows partition...'
Optimize-Volume -DriveLetter W -Defrag -NormalPriority -Verbose
WriteLog 'Performing slab consolidation on Windows partition...'
Optimize-Volume -DriveLetter W -SlabConsolidate -NormalPriority -Verbose
WriteLog 'Dismounting VHDX'
Dismount-ScratchVhdx -VhdxPath $VhdxPath
WriteLog 'Mounting VHDX as read-only for optimization'
Mount-VHD -Path $VhdxPath -NoDriveLetter -ReadOnly
WriteLog 'Optimizing VHDX in full mode...'
Optimize-VHD -Path $VhdxPath -Mode Full
WriteLog 'Dismounting VHDX'
Dismount-ScratchVhdx -VhdxPath $VhdxPath
} catch {
throw $_
}
}
function New-FFU { function New-FFU {
param ( param (
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
@@ -1977,8 +2002,9 @@ if (-not ($ISOPath) -and ($OptionalFeatures -like '*netfx3*')) {
} }
if (($LogicalSectorSizeBytes -eq 4096) -and ($installdrivers -eq $true)) { if (($LogicalSectorSizeBytes -eq 4096) -and ($installdrivers -eq $true)) {
$installdrivers = $false $installdrivers = $false
$CopyDrivers = $true
WriteLog 'LogicalSectorSizeBytes is set to 4096, which is not supported for driver injection. Setting $installdrivers to $false' WriteLog 'LogicalSectorSizeBytes is set to 4096, which is not supported for driver injection. Setting $installdrivers to $false'
WriteLog 'As a workaround, set -copydrivers $true to copy drivers to the deploy partition drivers folder' WriteLog 'As a workaround, setting -copydrivers $true to copy drivers to the deploy partition drivers folder'
WriteLog 'We are investigating this issue and will update the script if/when we have a fix' WriteLog 'We are investigating this issue and will update the script if/when we have a fix'
} }
if ($BuildUSBDrive -eq $true) { if ($BuildUSBDrive -eq $true) {
@@ -2038,7 +2064,7 @@ if ($InstallApps) {
#Update Latest Defender Platform and Definitions - these can't be serviced into the VHDX, will be saved to AppsPath #Update Latest Defender Platform and Definitions - these can't be serviced into the VHDX, will be saved to AppsPath
if ($UpdateLatestDefender) { if ($UpdateLatestDefender) {
WriteLog "`$UpdateLatestDefender is set to true, checking for latest Defender Platform and Definitions" WriteLog "`$UpdateLatestDefender is set to true, checking for latest Defender Platform and Definitions"
$Name = 'Update for Microsoft Defender Antivirus antimalware platform' $Name = "Update for Microsoft Defender Antivirus antimalware platform"
#Check if $DefenderPath exists, if not, create it #Check if $DefenderPath exists, if not, create it
If (-not (Test-Path -Path $DefenderPath)) { If (-not (Test-Path -Path $DefenderPath)) {
WriteLog "Creating $DefenderPath" WriteLog "Creating $DefenderPath"
@@ -2103,7 +2129,7 @@ if ($InstallApps) {
$OneDriveURL = 'https://go.microsoft.com/fwlink/?linkid=844652' $OneDriveURL = 'https://go.microsoft.com/fwlink/?linkid=844652'
try { try {
Start-BitsTransfer -Source $OneDriveURL -Destination "$OneDrivePath\OneDriveSetup.exe" Start-BitsTransfer -Source $OneDriveURL -Destination "$OneDrivePath\OneDriveSetup.exe"
WriteLog "Defender Definitions downloaded to $OneDrivePath\OneDriveSetup.exe" WriteLog "OneDrive client downloaded to $OneDrivePath\OneDriveSetup.exe"
} }
catch { catch {
Write-Host "Downloading OneDrive client Failed" Write-Host "Downloading OneDrive client Failed"
@@ -2195,7 +2221,7 @@ try {
#The Windows release info page is updated later than the MU Catalog #The Windows release info page is updated later than the MU Catalog
if ($UpdateLatestCU) { if ($UpdateLatestCU) {
Writelog "`$UpdateLatestCU is set to true, checking for latest CU" Writelog "`$UpdateLatestCU is set to true, checking for latest CU"
$Name = "Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch" $Name = """Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch"""
#Check if $KBPath exists, if not, create it #Check if $KBPath exists, if not, create it
If (-not (Test-Path -Path $KBPath)) { If (-not (Test-Path -Path $KBPath)) {
WriteLog "Creating $KBPath" WriteLog "Creating $KBPath"
@@ -2210,7 +2236,7 @@ try {
#Update Latest .NET Framework #Update Latest .NET Framework
if ($UpdateLatestNet) { if ($UpdateLatestNet) {
Writelog "`$UpdateLatestNet is set to true, checking for latest .NET Framework" Writelog "`$UpdateLatestNet is set to true, checking for latest .NET Framework"
$Name = "Cumulative update for .net framework windows $WindowsRelease $WindowsVersion $WindowsArch" $Name = "Cumulative update for .net framework windows $WindowsRelease $WindowsVersion $WindowsArch -preview"
#Check if $KBPath exists, if not, create it #Check if $KBPath exists, if not, create it
If (-not (Test-Path -Path $KBPath)) { If (-not (Test-Path -Path $KBPath)) {
WriteLog "Creating $KBPath" WriteLog "Creating $KBPath"
@@ -2239,10 +2265,13 @@ try {
if ($UpdateLatestCU -or $UpdateLatestNet) { if ($UpdateLatestCU -or $UpdateLatestNet) {
try { try {
WriteLog "Adding KBs to $WindowsPartition" WriteLog "Adding KBs to $WindowsPartition"
Add-WindowsPackage -Path $WindowsPartition -PackagePath $KBPath | Out-Null Add-WindowsPackage -Path $WindowsPartition -PackagePath $KBPath -PreventPending | Out-Null
WriteLog "KBs added to $WindowsPartition" WriteLog "KBs added to $WindowsPartition"
WriteLog "Removing $KBPath" WriteLog "Removing $KBPath"
Remove-Item -Path $KBPath -Recurse -Force | Out-Null Remove-Item -Path $KBPath -Recurse -Force | Out-Null
WriteLog "Clean Up the WinSxS Folder"
Invoke-Process cmd "/c ""$DandIEnv"" && Dism /Image:$WindowsPartition /Cleanup-Image /StartComponentCleanup /ResetBase" | Out-Null
WriteLog "Clean Up the WinSxS Folder completed"
} }
catch { catch {
Write-Host "Adding KB to VHDX failed with error $_" Write-Host "Adding KB to VHDX failed with error $_"
@@ -2363,6 +2392,7 @@ try {
WriteLog 'Waiting for VM to shutdown' WriteLog 'Waiting for VM to shutdown'
} while ($FFUVM.State -ne 'Off') } while ($FFUVM.State -ne 'Off')
WriteLog 'VM Shutdown' WriteLog 'VM Shutdown'
Optimize-FFUCaptureDrive -VhdxPath $VHDXPath
#Capture FFU file #Capture FFU file
New-FFU $FFUVM.Name New-FFU $FFUVM.Name
} }
@@ -2497,4 +2527,4 @@ If ($CleanupAppsISO) {
#Clean up dirty.txt file #Clean up dirty.txt file
Remove-Item -Path .\dirty.txt -Force | out-null Remove-Item -Path .\dirty.txt -Force | out-null
Write-Host "Script complete" Write-Host "Script complete"
WriteLog "Script complete" WriteLog "Script complete"
@@ -117,7 +117,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 = '2404.1' $version = '2405.1'
WriteLog 'Begin Logging' WriteLog 'Begin Logging'
WriteLog "Script version: $version" WriteLog "Script version: $version"
+14 -1
View File
@@ -7,10 +7,23 @@ This process will copy Windows in about 2-3 minutes to the target device, option
While we use this in Education at Microsoft, other industries can use it as well. We esepcially see a need for something like this with partners who do re-imaging on behalf of customers. The difference in Education is that they typically have large deployments that tend to happen at the beginning of the school year and any amount of time saved is helpful. Microsoft Deployment Toolkit, Configuration Manager, and other community solutions are all great solutions, but are typically slower due to WIM deployments being file-based while FFU files are sector-based. While we use this in Education at Microsoft, other industries can use it as well. We esepcially see a need for something like this with partners who do re-imaging on behalf of customers. The difference in Education is that they typically have large deployments that tend to happen at the beginning of the school year and any amount of time saved is helpful. Microsoft Deployment Toolkit, Configuration Manager, and other community solutions are all great solutions, but are typically slower due to WIM deployments being file-based while FFU files are sector-based.
# Updates # Updates
**2405.1**
- Moved the resetbase command from within the VM to after servicing the VHDX. This will make it so the FFU size is smaller after the latest CU or .NET framework are installed. (Thanks to Mike Kelly for the PR [Commit](https://github.com/rbalsleyMSFT/FFU/pull/24))
- Some additional FFU size reduction enhancements (Thanks Zehadi Alam [Commit](https://github.com/rbalsleyMSFT/FFU/pull/25)):
- Disk cleanup is now run before sysprep to help reduce FFU file size
- Before FFU capture, Optimize-FFU is run to defrag and slabconsolidate the VHDX
**2404.3**
- Fixed an issue where the latest Windows CU wasn't downloading properly [Commit](https://github.com/rbalsleyMSFT/FFU/commit/ae59183a199f39b310c79b31c9b4980fafdeb79b)
**2404.2**
- If setting -installdrivers to $true and -logicalsectorsizebytes to 4096, the script will now set $copyDrivers to $true. This will create a drivers folder on the deploy partition of the USB drive with the drivers that were supposed to be added to the FFU. There's currently a bug with servicing FFUs with 4096 logical sector byte sizes. Prior to this fix, the script would tell the user to manually set -copydrivers to $true as workaround. This fix just does the workaround automatically.
**2404.1** **2404.1**
There's a big change with this release related to the ADK. The ADK will now be automatically updated to the latest ADK release. This is required in order to fix an issue with optimized FFUs not applying due to an issue with DISM/FFUProvider.dll. The FFUProvider.dll fix was added to the Sept 2023 ADK. Since we now have the ability to auto upgrade the ADK, I'm more confident in having the BuildFFUVM script creating a complete FFU now (prior it was only creating 3 partitions instead of 4 with the recovery partition - at deployment time, the ApplyFFU.ps1 script would create an empty recovery parition). Please open an issue if this creates a problem for you. I do realize that any new ADK release can have it's own challenges and issues and I do suspect we'll see a new ADK released later this year. There's a big change with this release related to the ADK. The ADK will now be automatically updated to the latest ADK release. This is required in order to fix an issue with optimized FFUs not applying due to an issue with DISM/FFUProvider.dll. The FFUProvider.dll fix was added to the Sept 2023 ADK. Since we now have the ability to auto upgrade the ADK, I'm more confident in having the BuildFFUVM script creating a complete FFU now (prior it was only creating 3 partitions instead of 4 with the recovery partition - at deployment time, the ApplyFFU.ps1 script would create an empty recovery partition and Windows would populate it on first boot). Please open an issue if this creates a problem for you. I do realize that any new ADK release can have it's own challenges and issues and I do suspect we'll see a new ADK released later this year.
- Allow for ISOs with single index WIMs to work [Issue 10](https://github.com/rbalsleyMSFT/FFU/issues/10) - [Commit](https://github.com/rbalsleyMSFT/FFU/commit/9e2da741d53652e6e600ca19cfd38f507bd01fde) - Allow for ISOs with single index WIMs to work [Issue 10](https://github.com/rbalsleyMSFT/FFU/issues/10) - [Commit](https://github.com/rbalsleyMSFT/FFU/commit/9e2da741d53652e6e600ca19cfd38f507bd01fde)
- Added more robust ADK handling. Will now check for the latest ADK and download it if not installed. Thanks to [Zehadi Alam](https://github.com/zehadialam) [PR 18](https://github.com/rbalsleyMSFT/FFU/pull/18) - Added more robust ADK handling. Will now check for the latest ADK and download it if not installed. Thanks to [Zehadi Alam](https://github.com/zehadialam) [PR 18](https://github.com/rbalsleyMSFT/FFU/pull/18)