From 4d8966d3a197d42c7c5dd3a09e945fcb1bf23641 Mon Sep 17 00:00:00 2001 From: rbalsleyMSFT Date: Mon, 18 Sep 2023 12:06:20 -0700 Subject: [PATCH 1/3] Added variables --- FFUDevelopment/BuildFFUVM.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 926b5e0..c412f69 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -200,7 +200,12 @@ param( [ValidateSet('consumer', 'business')] [string]$MediaType = 'consumer', [ValidateSet(512, 4096)] - [uint32]$LogicalSectorSizeBytes = 512 + [uint32]$LogicalSectorSizeBytes = 512, + #Will be used in future release + [bool]$CopyDrivers, + [bool]$CopyPPKG, + [bool]$CopyUnattend, + [bool]$RemoveFFU ) $version = '2309.2' From ed3fcf1a3d0731a988d2799bf2a9dee24b455b3f Mon Sep 17 00:00:00 2001 From: rbalsleyMSFT Date: Thu, 14 Dec 2023 15:32:14 -0800 Subject: [PATCH 2/3] Fixed bug with Windows Update failing to install updates for VHDX-only captures. --- FFUDevelopment/BuildFFUVM.ps1 | 19 ++++++++++++++++--- .../WinPECaptureFFUFiles/CaptureFFU.ps1 | 1 + .../WinPEDeployFFUFiles/ApplyFFU.ps1 | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index c412f69..a506855 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -207,7 +207,7 @@ param( [bool]$CopyUnattend, [bool]$RemoveFFU ) -$version = '2309.2' +$version = '2312.1' #Check if Hyper-V feature is installed (requires only checks the module) $osInfo = Get-WmiObject -Class Win32_OperatingSystem @@ -1067,6 +1067,7 @@ function Remove-FFUVM { WriteLog "Removing VM: $VMName" Remove-VM -Name $VMName -Force WriteLog 'Removal complete' + $VMPath = $FFUVM.Path WriteLog "Removing $VMPath" Remove-Item -Path $VMPath -Force -Recurse WriteLog 'Removal complete' @@ -1119,6 +1120,9 @@ Function Remove-FFUUserShare { } Function Get-WindowsVersionInfo { + #This sleep prevents CBS/CSI corruption which causes issues with Windows update after deployment. Capturing from very fast disks (NVME) can cause the capture to happen faster than Windows is ready for. This seems to affect VHDX-only captures, not VM captures. + WriteLog 'Sleep 60 seconds before opening registry to grab Windows version info ' + Start-sleep 60 WriteLog "Getting Windows Version info" #Load Registry Hive $Software = "$osPartitionDriveLetter`:\Windows\System32\config\software" @@ -1157,8 +1161,6 @@ Function Get-WindowsVersionInfo { WriteLog 'Sleep 60 seconds to allow registry to completely unload' Start-sleep 60 - - return @{ DisplayVersion = $DisplayVersion @@ -1283,6 +1285,17 @@ Function New-DeploymentUSB { function Get-FFUEnvironment { WriteLog 'Dirty.txt file detected. Last run did not complete succesfully. Will clean environment' + # Check for running VMs that start with '_FFU-' and are in the 'Off' state + $vms = Get-VM + + # Loop through each VM + foreach ($vm in $vms) { + # Check if the VM name starts with '_FFU-' and the state is 'Off' + if ($vm.Name.StartsWith("_FFU-") -and $vm.State -eq 'Off') { + # If conditions are met, delete the VM + Remove-FFUVM -VMName $vm.Name + } + } # Check for MSFT Virtual disks where location contains FFUDevelopment in the path $disks = Get-Disk -FriendlyName *virtual* foreach ($disk in $disks) { diff --git a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 index c0021c9..fb4b964 100644 --- a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 +++ b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 @@ -60,6 +60,7 @@ Remove-Variable DisplayVersion Remove-Variable Office reg unload "HKLM\FFU" #This prevents Critical Process Died errors you can have during deployment of the FFU - may not happen during capture from WinPE, but adding here to be consistent with VHDX capture +Write-Host "Sleeping for 60 seconds to allow registry to unload prior to capture" Start-sleep 60 Start-Process -FilePath dism.exe -ArgumentList $dismArgs -Wait -PassThru -ErrorAction Stop | Out-Null #Copy DISM log to Host diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 index 7284a4a..c6ba754 100644 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 +++ b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 @@ -117,7 +117,7 @@ $LogFileName = 'ScriptLog.txt' $USBDrive = Get-USBDrive New-item -Path $USBDrive -Name $LogFileName -ItemType "file" -Force | Out-Null $LogFile = $USBDrive + $LogFilename -$version = '2309.2' +$version = '2312.1' WriteLog 'Begin Logging' WriteLog "Script version: $version" From aee1aa1e9562e917293d36d1c25c2271aca6f199 Mon Sep 17 00:00:00 2001 From: rbalsleyMSFT Date: Fri, 26 Jan 2024 14:28:38 -0800 Subject: [PATCH 3/3] 2401.1 update --- FFUDevelopment/Apps/Office/DeployFFU.xml | 2 +- FFUDevelopment/Apps/Office/DownloadFFU.xml | 2 +- FFUDevelopment/BuildFFUVM.ps1 | 54 +++++++++++++++---- .../WinPEDeployFFUFiles/ApplyFFU.ps1 | 2 +- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/FFUDevelopment/Apps/Office/DeployFFU.xml b/FFUDevelopment/Apps/Office/DeployFFU.xml index 115876c..f1e26de 100644 --- a/FFUDevelopment/Apps/Office/DeployFFU.xml +++ b/FFUDevelopment/Apps/Office/DeployFFU.xml @@ -1,5 +1,5 @@ - + diff --git a/FFUDevelopment/Apps/Office/DownloadFFU.xml b/FFUDevelopment/Apps/Office/DownloadFFU.xml index 95fb4c5..edbd165 100644 --- a/FFUDevelopment/Apps/Office/DownloadFFU.xml +++ b/FFUDevelopment/Apps/Office/DownloadFFU.xml @@ -1,5 +1,5 @@ - + diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index a506855..a94fd5f 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -131,7 +131,7 @@ param( [Parameter(Mandatory = $false)] [ValidateScript({ if ($_ -and (!(Test-Path -Path '.\Drivers') -or ((Get-ChildItem -Path '.\Drivers' -Recurse | Measure-Object -Property Length -Sum).Sum -lt 1MB))) { - throw "InstallDrivers is set to `$true, but either the Drivers folder is missing or empty" + throw 'InstallDrivers is set to $true, but either the Drivers folder is missing or empty' } return $true })] @@ -201,13 +201,21 @@ param( [string]$MediaType = 'consumer', [ValidateSet(512, 4096)] [uint32]$LogicalSectorSizeBytes = 512, - #Will be used in future release + [bool]$Optimize = $true, + [Parameter(Mandatory = $false)] + [ValidateScript({ + if ($_ -and (!(Test-Path -Path '.\Drivers') -or ((Get-ChildItem -Path '.\Drivers' -Recurse | Measure-Object -Property Length -Sum).Sum -lt 1MB))) { + throw 'CopyDrivers is set to $true, but either the Drivers folder is missing or empty' + } + return $true + })] [bool]$CopyDrivers, + #Will be used in future release [bool]$CopyPPKG, [bool]$CopyUnattend, [bool]$RemoveFFU ) -$version = '2312.1' +$version = '2401.1' #Check if Hyper-V feature is installed (requires only checks the module) $osInfo = Get-WmiObject -Class Win32_OperatingSystem @@ -627,6 +635,7 @@ function New-ScratchVhdx { WriteLog "Creating new Scratch VHDX..." $newVHDX = New-VHD -Path $VhdxPath -SizeBytes $disksize -LogicalSectorSizeBytes $LogicalSectorSizeBytes -Dynamic:($Dynamic.IsPresent) + # $newVHDX = New-VHD -Path $VhdxPath -SizeBytes $disksize -LogicalSectorSizeBytes $LogicalSectorSizeBytes -Fixed $toReturn = $newVHDX | Mount-VHD -Passthru | Initialize-Disk -PassThru -PartitionStyle GPT #Remove auto-created partition so we can create the correct partition layout @@ -1035,7 +1044,12 @@ function New-FFU { Mount-WindowsImage -ImagePath $FFUFile -Index 1 -Path "$FFUDevelopmentPath\Mount" | Out-null WriteLog 'Mounting complete' WriteLog 'Adding drivers - This will take a few minutes, please be patient' - Add-WindowsDriver -Path "$FFUDevelopmentPath\Mount" -Driver "$FFUDevelopmentPath\Drivers" -Recurse | Out-null + try { + Add-WindowsDriver -Path "$FFUDevelopmentPath\Mount" -Driver "$FFUDevelopmentPath\Drivers" -Recurse -ErrorAction SilentlyContinue | Out-null + } + catch { + WriteLog 'Some drivers failed to be added to the FFU. This can be expected. Continuing.' + } WriteLog 'Adding drivers complete' WriteLog "Dismount $FFUDevelopmentPath\Mount" Dismount-WindowsImage -Path "$FFUDevelopmentPath\Mount" -Save | Out-Null @@ -1045,10 +1059,13 @@ function New-FFU { WriteLog 'Folder removed' } #Optimize FFU - WriteLog 'Optimizing FFU - This will take a few minutes, please be patient' - #Invoke-Process cmd "/c ""$DandIEnv"" && dism /optimize-ffu /imagefile:$FFUFile" - Invoke-Process cmd "/c dism /optimize-ffu /imagefile:$FFUFile" - WriteLog 'Optimizing FFU complete' + if($Optimize -eq $true){ + WriteLog 'Optimizing FFU - This will take a few minutes, please be patient' + #Invoke-Process cmd "/c ""$DandIEnv"" && dism /optimize-ffu /imagefile:$FFUFile" + Invoke-Process cmd "/c dism /optimize-ffu /imagefile:$FFUFile" + WriteLog 'Optimizing FFU complete' + } + } function Remove-FFUVM { @@ -1218,6 +1235,8 @@ Function New-DeploymentUSB { } else { WriteLog "No FFU files found in the current directory." + Write-Error "No FFU files found in the current directory." + Return } } @@ -1262,6 +1281,10 @@ Function New-DeploymentUSB { WriteLog ("Copying " + $SelectedFFUFile + " to $DeployPartitionDriveLetter. This could take a few minutes.") robocopy $(Split-Path $SelectedFFUFile -Parent) $DeployPartitionDriveLetter $(Split-Path $SelectedFFUFile -Leaf) /COPYALL /R:5 /W:5 /J } + if ($CopyDrivers -eq $true) { + WriteLog "Copying drivers to $DeployPartitionDriveLetter\Drivers" + robocopy "$FFUDevelopmentPath\Drivers" "$DeployPartitionDriveLetter\Drivers" /E /R:5 /W:5 /J + } } else { WriteLog "No FFU file selected. Skipping copy." @@ -1290,8 +1313,10 @@ function Get-FFUEnvironment { # Loop through each VM foreach ($vm in $vms) { - # Check if the VM name starts with '_FFU-' and the state is 'Off' - if ($vm.Name.StartsWith("_FFU-") -and $vm.State -eq 'Off') { + if ($vm.Name.StartsWith("_FFU-")) { + if ($vm.State -eq 'Running') { + Stop-VM -Name $vm.Name -TurnOff -Force + } # If conditions are met, delete the VM Remove-FFUVM -VMName $vm.Name } @@ -1400,6 +1425,12 @@ if (($InstallApps -and ($VMHostIPAddress -eq ''))) { if (-not ($ISOPath) -and ($OptionalFeatures -like '*netfx3*')) { throw "netfx3 specified as an optional feature, however Windows ISO isn't defined. Unable to get netfx3 source files from downloaded ESD media. Please specify a Windows ISO in the ISOPath parameter." } +if (($LogicalSectorSizeBytes -eq 4096) -and ($installdrivers -eq $true)){ + $installdrivers = $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 'We are investigating this issue and will update the script if/when we have a fix' +} #Get script variable values LogVariableValues @@ -1473,7 +1504,8 @@ try { $index = Get-Index -WindowsImagePath $wimPath -WindowsSKU $WindowsSKU } - $vhdxDisk = New-ScratchVhdx -VhdxPath $VHDXPath -SizeBytes $disksize -Dynamic -LogicalSectorSizeBytes $LogicalSectorSizeBytes + # $vhdxDisk = New-ScratchVhdx -VhdxPath $VHDXPath -SizeBytes $disksize -Dynamic:$false -LogicalSectorSizeBytes $LogicalSectorSizeBytes + $vhdxDisk = New-ScratchVhdx -VhdxPath $VHDXPath -SizeBytes $disksize -LogicalSectorSizeBytes $LogicalSectorSizeBytes $systemPartitionDriveLetter = New-SystemPartition -VhdxDisk $vhdxDisk diff --git a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 index c6ba754..63ff7b9 100644 --- a/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 +++ b/FFUDevelopment/WinPEDeployFFUFiles/ApplyFFU.ps1 @@ -117,7 +117,7 @@ $LogFileName = 'ScriptLog.txt' $USBDrive = Get-USBDrive New-item -Path $USBDrive -Name $LogFileName -ItemType "file" -Force | Out-Null $LogFile = $USBDrive + $LogFilename -$version = '2312.1' +$version = '2401.1' WriteLog 'Begin Logging' WriteLog "Script version: $version"