mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
+183
-43
@@ -14,7 +14,7 @@ This script creates a Windows 10/11 FFU and USB drive to help quickly get a Wind
|
||||
Path to the Windows 10/11 ISO file.
|
||||
|
||||
.PARAMETER WindowsSKU
|
||||
Edition of Windows 10/11 to be installed, e.g., 'Home', 'Home_N', 'Home_SL', 'EDU', 'EDU_N', 'Pro', 'Pro_N', 'Pro_EDU', 'Pro_Edu_N', 'Pro_WKS', 'Pro_WKS_N'
|
||||
Edition of Windows 10/11 to be installed, e.g., accepted values are: 'Home', 'Home N', 'Home Single Language', 'Education', 'Education N', 'Pro', 'Pro N', 'Pro Education', 'Pro Education N', 'Pro for Workstations', 'Pro N for Workstations', 'Enterprise', 'Enterprise N'
|
||||
|
||||
.PARAMETER FFUDevelopmentPath
|
||||
Path to the FFU development folder (default is C:\FFUDevelopment).
|
||||
@@ -283,7 +283,7 @@ param(
|
||||
[bool]$CleanupDeployISO = $true,
|
||||
[bool]$CleanupAppsISO = $true
|
||||
)
|
||||
$version = '2403.1'
|
||||
$version = '2404.1'
|
||||
|
||||
#Check if Hyper-V feature is installed (requires only checks the module)
|
||||
$osInfo = Get-WmiObject -Class Win32_OperatingSystem
|
||||
@@ -531,29 +531,161 @@ function Install-ADK {
|
||||
throw $_
|
||||
}
|
||||
}
|
||||
Function Get-ADK {
|
||||
Writelog 'Get ADK Path'
|
||||
# Define the registry key and value name to query
|
||||
$adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots"
|
||||
$adkRegValueName = "KitsRoot10"
|
||||
function Get-InstalledProgramRegKey {
|
||||
param (
|
||||
[string]$DisplayName
|
||||
)
|
||||
|
||||
# Check if the registry value exists
|
||||
if ($null -ne (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName -ErrorAction SilentlyContinue)) {
|
||||
# Get the registry value for the Windows ADK installation path
|
||||
$adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName
|
||||
WriteLog "ADK located at $adkPath"
|
||||
return $adkPath
|
||||
$uninstallRegPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
|
||||
$uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse
|
||||
|
||||
foreach ($regKey in $uninstallRegKeys) {
|
||||
try {
|
||||
$regValue = $regKey.GetValue("DisplayName")
|
||||
if ($regValue -eq $DisplayName) {
|
||||
return $regKey
|
||||
}
|
||||
}
|
||||
catch {
|
||||
WriteLog $_
|
||||
throw "Error retrieving installed program info for $DisplayName : $_"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Uninstall-ADK {
|
||||
param (
|
||||
[ValidateSet("Windows ADK", "WinPE add-on")]
|
||||
[string]$ADKOption
|
||||
)
|
||||
|
||||
# Match name as it appears in the registry
|
||||
$displayName = switch ($ADKOption) {
|
||||
"Windows ADK" { "Windows Assessment and Deployment Kit" }
|
||||
"WinPE add-on" { "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons" }
|
||||
}
|
||||
|
||||
try {
|
||||
$adkRegKey = Get-InstalledProgramRegKey -DisplayName $displayName
|
||||
|
||||
if (-not $adkRegKey) {
|
||||
WriteLog "$ADKOption is not installed."
|
||||
return
|
||||
}
|
||||
|
||||
$adkBundleCachePath = $adkRegKey.GetValue("BundleCachePath")
|
||||
WriteLog "Uninstalling $ADKOption..."
|
||||
Invoke-Process $adkBundleCachePath "/uninstall /quiet"
|
||||
WriteLog "$ADKOption uninstalled successfully."
|
||||
}
|
||||
catch {
|
||||
WriteLog $_
|
||||
Write-Error "Error occurred while uninstalling $ADKOption. Please manually uninstall it."
|
||||
throw $_
|
||||
}
|
||||
}
|
||||
|
||||
function Confirm-ADKVersionIsLatest {
|
||||
param (
|
||||
[ValidateSet("Windows ADK", "WinPE add-on")]
|
||||
[string]$ADKOption
|
||||
)
|
||||
|
||||
$displayName = switch ($ADKOption) {
|
||||
"Windows ADK" { "Windows Assessment and Deployment Kit" }
|
||||
"WinPE add-on" { "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons" }
|
||||
}
|
||||
|
||||
try {
|
||||
$adkRegKey = Get-InstalledProgramRegKey -DisplayName $displayName
|
||||
|
||||
if (-not $adkRegKey) {
|
||||
return $false
|
||||
}
|
||||
|
||||
$installedADKVersion = $adkRegKey.GetValue("DisplayVersion")
|
||||
|
||||
# Retrieve content of Microsoft documentation page
|
||||
$adkWebPage = Invoke-RestMethod "https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install"
|
||||
# Specify regex pattern for ADK version
|
||||
$adkVersionPattern = 'ADK\s+(\d+(\.\d+)+)'
|
||||
# Check for regex pattern match
|
||||
$adkVersionMatch = [regex]::Match($adkWebPage, $adkVersionPattern)
|
||||
|
||||
if (-not $adkVersionMatch.Success) {
|
||||
WriteLog "Failed to retrieve latest ADK version from web page."
|
||||
return $false
|
||||
}
|
||||
|
||||
# Extract ADK version from the matched pattern
|
||||
$latestADKVersion = $adkVersionMatch.Groups[1].Value
|
||||
|
||||
if ($installedADKVersion -eq $latestADKVersion) {
|
||||
WriteLog "Installed $ADKOption version $installedADKVersion is the latest."
|
||||
return $true
|
||||
}
|
||||
else {
|
||||
WriteLog "ADK is not installed. Installing ADK now..."
|
||||
Install-ADK -ADKOption "Windows ADK"
|
||||
WriteLog "Installing WinPE add-on for Windows ADK..."
|
||||
Install-ADK -ADKOption "WinPE add-on"
|
||||
$adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName
|
||||
WriteLog "ADK located at $adkPath"
|
||||
return $adkPath
|
||||
# throw "Windows ADK is not installed or the installation path could not be found."
|
||||
WriteLog "Installed $ADKOption version $installedADKVersion is not the latest ($latestADKVersion)"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
catch {
|
||||
WriteLog "An error occurred while confirming the ADK version: $_"
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ADK {
|
||||
# Check if latest ADK and WinPE add-on are installed
|
||||
$latestADKInstalled = Confirm-ADKVersionIsLatest -ADKOption "Windows ADK"
|
||||
$latestWinPEInstalled = Confirm-ADKVersionIsLatest -ADKOption "WinPE add-on"
|
||||
|
||||
# Uninstall older versions and install latest versions if necessary
|
||||
if (-not $latestADKInstalled) {
|
||||
Uninstall-ADK -ADKOption "Windows ADK"
|
||||
Install-ADK -ADKOption "Windows ADK"
|
||||
}
|
||||
|
||||
if (-not $latestWinPEInstalled) {
|
||||
Uninstall-ADK -ADKOption "WinPE add-on"
|
||||
Install-ADK -ADKOption "WinPE add-on"
|
||||
}
|
||||
|
||||
# Define registry path
|
||||
$adkPathKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots"
|
||||
$adkPathName = "KitsRoot10"
|
||||
|
||||
# Check if ADK installation path exists in registry
|
||||
$adkPathNameExists = (Get-ItemProperty -Path $adkPathKey -Name $adkPathName -ErrorAction SilentlyContinue)
|
||||
|
||||
if ($adkPathNameExists) {
|
||||
# Get the ADK installation path
|
||||
WriteLog 'Get ADK Path'
|
||||
$adkPath = (Get-ItemProperty -Path $adkPathKey -Name $adkPathName).$adkPathName
|
||||
WriteLog "ADK located at $adkPath"
|
||||
}
|
||||
else {
|
||||
throw "Windows ADK installation path could not be found."
|
||||
}
|
||||
|
||||
# If ADK was already installed, then check if the Windows Deployment Tools feature is also installed
|
||||
$deploymentToolsRegKey = Get-InstalledProgramRegKey -DisplayName "Windows Deployment Tools"
|
||||
|
||||
if (-not $deploymentToolsRegKey) {
|
||||
WriteLog "ADK is installed, but the Windows Deployment Tools feature is not installed."
|
||||
$adkRegKey = Get-InstalledProgramRegKey -DisplayName "Windows Assessment and Deployment Kit"
|
||||
$adkBundleCachePath = $adkRegKey.GetValue("BundleCachePath")
|
||||
if ($adkBundleCachePath) {
|
||||
WriteLog "Installing Windows Deployment Tools..."
|
||||
$adkInstallPath = $adkPath.TrimEnd('\')
|
||||
Invoke-Process $adkBundleCachePath "/quiet /installpath ""$adkInstallPath"" /features OptionId.DeploymentTools"
|
||||
WriteLog "Windows Deployment Tools installed successfully."
|
||||
}
|
||||
else {
|
||||
throw "Failed to retrieve path to adksetup.exe to install the Windows Deployment Tools. Please manually install it."
|
||||
}
|
||||
}
|
||||
return $adkPath
|
||||
}
|
||||
function Get-WindowsESD {
|
||||
param(
|
||||
@@ -892,9 +1024,15 @@ function Get-Index {
|
||||
# Get the available indexes using Get-WindowsImage
|
||||
$imageIndexes = Get-WindowsImage -ImagePath $WindowsImagePath
|
||||
|
||||
# Get the ImageName of ImageIndex 4 - this is usually Home or Education SKU on ESD MCT media
|
||||
$imageIndex4 = $imageIndexes | Where-Object ImageIndex -eq 4
|
||||
$WindowsImage = $imageIndex4.ImageName.Substring(0, 10)
|
||||
# Get the ImageName of ImageIndex 1 if an ISO was specified, else use ImageIndex 4 - this is usually Home or Education SKU on ESD MCT media
|
||||
if($ISOPath){
|
||||
$imageIndex = $imageIndexes | Where-Object ImageIndex -eq 1
|
||||
$WindowsImage = $imageIndex.ImageName.Substring(0, 10)
|
||||
}
|
||||
else{
|
||||
$imageIndex = $imageIndexes | Where-Object ImageIndex -eq 4
|
||||
$WindowsImage = $imageIndex.ImageName.Substring(0, 10)
|
||||
}
|
||||
|
||||
# Concatenate $WindowsImage and $WindowsSKU (E.g. Windows 11 Pro)
|
||||
$ImageNameToFind = "$WindowsImage $WindowsSKU"
|
||||
@@ -950,7 +1088,6 @@ 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
|
||||
@@ -1055,10 +1192,12 @@ function New-RecoveryPartition {
|
||||
$winReWim = Get-ChildItem "$($OsPartition.DriveLetter):\Windows\System32\Recovery\Winre.wim"
|
||||
|
||||
if (($null -ne $winReWim) -and ($winReWim.Count -eq 1)) {
|
||||
# Wim size + 52MB is minimum WinRE partition size.
|
||||
# Wim size + 100MB is minimum WinRE partition size.
|
||||
# NTFS and other partitioning size differences account for about 17MB of space that's unavailable.
|
||||
# Adding 32MB as a buffer to ensure there's enough space.
|
||||
$calculatedRecoverySize = $winReWim.Length + 52MB + 32MB
|
||||
# Adding 32MB as a buffer to ensure there's enough space to account for NTFS file system overhead.
|
||||
# Adding 250MB as per recommendations from
|
||||
# https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-uefigpt-based-hard-drive-partitions?view=windows-11#recovery-tools-partition
|
||||
$calculatedRecoverySize = $winReWim.Length + 250MB + 32MB
|
||||
|
||||
WriteLog "Calculated space needed for recovery in bytes: $calculatedRecoverySize"
|
||||
|
||||
@@ -1348,10 +1487,9 @@ function New-FFU {
|
||||
WriteLog "FFU file name: $FFUFileName"
|
||||
$FFUFile = "$FFUCaptureLocation\$FFUFileName"
|
||||
#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"
|
||||
Invoke-Process cmd "/c dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($winverinfo.SKU) /Compress:Default"
|
||||
Invoke-Process cmd "/c ""$DandIEnv"" && dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($winverinfo.SKU) /Compress:Default"
|
||||
# Invoke-Process cmd "/c dism /Capture-FFU /ImageFile:$FFUFile /CaptureDrive:\\.\PhysicalDrive$($vhdxDisk.DiskNumber) /Name:$($winverinfo.Name)$($winverinfo.DisplayVersion)$($winverinfo.SKU) /Compress:Default"
|
||||
WriteLog 'FFU Capture complete'
|
||||
#WriteLog 'Sleeping 60 seconds before dismount of VHDX'
|
||||
Dismount-ScratchVhdx -VhdxPath $VHDXPath
|
||||
}
|
||||
|
||||
@@ -1386,8 +1524,9 @@ function New-FFU {
|
||||
#Optimize FFU
|
||||
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"
|
||||
#Need to use ADK version of DISM to address bug in DISM - perhaps Windows 11 24H2 will fix this
|
||||
Invoke-Process cmd "/c ""$DandIEnv"" && dism /optimize-ffu /imagefile:$FFUFile"
|
||||
#Invoke-Process cmd "/c dism /optimize-ffu /imagefile:$FFUFile"
|
||||
WriteLog 'Optimizing FFU complete'
|
||||
}
|
||||
|
||||
@@ -1856,7 +1995,7 @@ LogVariableValues
|
||||
#Get Windows ADK
|
||||
try {
|
||||
$adkPath = Get-ADK
|
||||
#Need to use the Deployment and Imaging tools environment to use dism from the Insider ADK to optimize the FFU. This is only needed until Windows 23H2
|
||||
#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"
|
||||
}
|
||||
catch {
|
||||
@@ -2034,7 +2173,6 @@ try {
|
||||
$index = Get-Index -WindowsImagePath $wimPath -WindowsSKU $WindowsSKU
|
||||
}
|
||||
|
||||
# $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
|
||||
@@ -2046,31 +2184,33 @@ try {
|
||||
$WindowsPartition = $osPartitionDriveLetter + ":\"
|
||||
|
||||
#$recoveryPartition = New-RecoveryPartition -VhdxDisk $vhdxDisk -OsPartition $osPartition[1] -RecoveryPartitionSize $RecoveryPartitionSize -DataPartition $dataPartition
|
||||
$recoveryPartition = New-RecoveryPartition -VhdxDisk $vhdxDisk -OsPartition $osPartition[1] -RecoveryPartitionSize $RecoveryPartitionSize -DataPartition $dataPartition
|
||||
|
||||
WriteLog "All necessary partitions created."
|
||||
|
||||
Add-BootFiles -OsPartitionDriveLetter $osPartitionDriveLetter -SystemPartitionDriveLetter $systemPartitionDriveLetter[1]
|
||||
|
||||
#Update latest Cumulative Update
|
||||
If ($UpdateLatestCU) {
|
||||
WriteLog "`$UpdateLatestCU is set to true, checking for latest CU"
|
||||
$LatestKB = Get-LatestWindowsKB -WindowsRelease $WindowsRelease
|
||||
WriteLog "Latest KB for Windows $WindowsRelease found: $LatestKB"
|
||||
$Name = $LatestKB + " " + $WindowsVersion
|
||||
#Changed to use MU Catalog instead of using Get-LatestWindowsKB
|
||||
#The Windows release info page is updated later than the MU Catalog
|
||||
if ($UpdateLatestCU) {
|
||||
Writelog "`$UpdateLatestCU is set to true, checking for latest CU"
|
||||
$Name = "Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch"
|
||||
#Check if $KBPath exists, if not, create it
|
||||
If (-not (Test-Path -Path $KBPath)) {
|
||||
WriteLog "Creating $KBPath"
|
||||
New-Item -Path $KBPath -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
WriteLog "Searching for $Name from Microsoft Update Catalog and saving to $KBPath"
|
||||
WriteLog "Searching for $name from Microsoft Update Catalog and saving to $KBPath"
|
||||
$KBFilePath = Save-KB -Name $Name -Path $KBPath
|
||||
WriteLog "$LatestKB saved to $KBPath\$KBFilePath"
|
||||
WriteLog "Latest CU saved to $KBPath\$KBFilePath"
|
||||
}
|
||||
|
||||
|
||||
#Update Latest .NET Framework
|
||||
if ($UpdateLatestNet) {
|
||||
Writelog "`$UpdateLatestNet is set to true, checking for latest .NET Framework"
|
||||
$Name = "Cumulative update for .net framework windows $WindowsRelease $WindowsVersion $Architecture"
|
||||
$Name = "Cumulative update for .net framework windows $WindowsRelease $WindowsVersion $WindowsArch"
|
||||
#Check if $KBPath exists, if not, create it
|
||||
If (-not (Test-Path -Path $KBPath)) {
|
||||
WriteLog "Creating $KBPath"
|
||||
|
||||
@@ -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 = '2403.1'
|
||||
$version = '2404.1'
|
||||
WriteLog 'Begin Logging'
|
||||
WriteLog "Script version: $version"
|
||||
|
||||
@@ -130,26 +130,26 @@ $DiskID = $PhysicalDeviceID.substring($PhysicalDeviceID.length - 1,1)
|
||||
WriteLog "DiskID is $DiskID"
|
||||
|
||||
#COMMENT THIS WHOLE BLOCK OUT ONCE FFUPROVIDER FIX IS IN
|
||||
#Modify diskpart answer files if DiskID not 0
|
||||
# $UEFIFFUPartitions = 'x:\CreateUEFI-FFU-Partitions.txt'
|
||||
$ExtendPartition = 'x:\ExtendPartition-UEFI.txt'
|
||||
# #Modify diskpart answer files if DiskID not 0
|
||||
# # $UEFIFFUPartitions = 'x:\CreateUEFI-FFU-Partitions.txt'
|
||||
# $ExtendPartition = 'x:\ExtendPartition-UEFI.txt'
|
||||
|
||||
If ($DiskID -ne '0'){
|
||||
WriteLog 'DiskID is not 0. Need to modify diskpart answer files'
|
||||
# try {
|
||||
# Set-DiskpartAnswerFiles $UEFIFFUPartitions $DiskID
|
||||
# }
|
||||
# catch {
|
||||
# WriteLog "Modifying $UEFIFFUPartitions failed with error: $_"
|
||||
# }
|
||||
# If ($DiskID -ne '0'){
|
||||
# WriteLog 'DiskID is not 0. Need to modify diskpart answer files'
|
||||
# # try {
|
||||
# # Set-DiskpartAnswerFiles $UEFIFFUPartitions $DiskID
|
||||
# # }
|
||||
# # catch {
|
||||
# # WriteLog "Modifying $UEFIFFUPartitions failed with error: $_"
|
||||
# # }
|
||||
|
||||
try {
|
||||
Set-DiskpartAnswerFiles $ExtendPartition $DiskID
|
||||
}
|
||||
catch {
|
||||
WriteLog "Modifying $ExtendPartition failed with error: $_"
|
||||
}
|
||||
}
|
||||
# try {
|
||||
# Set-DiskpartAnswerFiles $ExtendPartition $DiskID
|
||||
# }
|
||||
# catch {
|
||||
# WriteLog "Modifying $ExtendPartition failed with error: $_"
|
||||
# }
|
||||
# }
|
||||
|
||||
#Find FFU Files
|
||||
[array]$FFUFiles = @(Get-ChildItem -Path $USBDrive*.ffu)
|
||||
@@ -265,7 +265,7 @@ if ($Unattend -and $UnattendPrefix){
|
||||
#Get serial number to append. This can make names longer than 15 characters. Trim any leading or trailing whitespace
|
||||
$serial = (Get-CimInstance -ClassName win32_bios).SerialNumber.Trim()
|
||||
#Combine prefix with serial
|
||||
$computername = $PrefixToUse + $serial
|
||||
$computername = ($PrefixToUse + $serial) -replace "\s","" # Remove spaces because windows does not support spaces in the computer names
|
||||
#If computername is longer than 15 characters, reduce to 15. Sysprep/unattend doesn't like ComputerName being longer than 15 characters even though Windows accepts it
|
||||
If ($computername.Length -gt 15){
|
||||
$computername = $computername.substring(0,15)
|
||||
@@ -476,19 +476,19 @@ else{
|
||||
# }
|
||||
|
||||
#COMMENT THIS WHOLE BLOCK OUT AFTER FFUPROVIDER FIX IS IN
|
||||
# Extend Windows partition and create recovery partition
|
||||
Writelog 'Extending Windows partition'
|
||||
Invoke-Process diskpart.exe "/S $ExtendPartition"
|
||||
if($LASTEXITCODE -eq 0){
|
||||
WriteLog 'Successfully extended Windows partition and created recovery partition'
|
||||
}
|
||||
else{
|
||||
Writelog "Failed to extend Windows partition and/or create recovery partition - LastExitCode = $LASTEXITCODE"
|
||||
}
|
||||
# # Extend Windows partition and create recovery partition
|
||||
# Writelog 'Extending Windows partition'
|
||||
# Invoke-Process diskpart.exe "/S $ExtendPartition"
|
||||
# if($LASTEXITCODE -eq 0){
|
||||
# WriteLog 'Successfully extended Windows partition and created recovery partition'
|
||||
# }
|
||||
# else{
|
||||
# Writelog "Failed to extend Windows partition and/or create recovery partition - LastExitCode = $LASTEXITCODE"
|
||||
# }
|
||||
|
||||
#UNCOMMENT THIS AFTER FFUPROVIDER FIX IS IN
|
||||
#Set W: drive letter to Windows partition
|
||||
#Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object PartitionNumber -eq 3 | Set-Partition -NewDriveLetter W
|
||||
# Set W: drive letter to Windows partition
|
||||
Get-Disk | Where-Object Number -eq $DiskID | Get-Partition | Where-Object PartitionNumber -eq 3 | Set-Partition -NewDriveLetter W
|
||||
|
||||
#Copy modified WinRE if folder exists, else copy inbox WinRE
|
||||
$WinRE = $USBDrive + "WinRE\winre.wim"
|
||||
|
||||
@@ -8,6 +8,16 @@ While we use this in Education at Microsoft, other industries can use it as well
|
||||
|
||||
# Updates
|
||||
|
||||
**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.
|
||||
|
||||
- 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)
|
||||
- Revert code back to allow optimized FFUs to be applied via ApplyFFU.ps1 now that Sept 2023 ADK release has FFUProvider.dll fix. [Commit](https://github.com/rbalsleyMSFT/FFU/commit/79364e334d6d09ff150e70dab7bfb2637d0ad8a8)
|
||||
- Changed how the script searches for the latest CU. Instead of relying on the Windows release info page to grab the KB number, will just use the MU Catalog, the same as what we do for the .NET Framework. Windows release info page is updated manually and is unknown as to when it will be updated. [Commit](https://github.com/rbalsleyMSFT/FFU/commit/6fd5a4a41fd9ce2f842f43dc3a69bda264c29fa6)
|
||||
- Added fix to not allow computer names with spaces. Thanks to [JoeMama54 (Rob)](https://github.com/JoeMama54) [PR 20](https://github.com/rbalsleyMSFT/FFU/pull/20)
|
||||
|
||||
**2403.1**
|
||||
|
||||
Fixed an issue with the SecurityHealthSetup.exe file giving an error when building the VM if -UpdateLatestDefender was set to $true. A new update for this came out on 3/21 which included a x64 and ARM64 binary. This file doesn't have an architecture designation to it, so it's impossible to know which file is for which architecture. Investigating to see if we can fix this in the Microsoft Update catalog. There is a web site to pull this from, but the support article is out of date.
|
||||
|
||||
Reference in New Issue
Block a user