From e3cbcab6b2944404aec397c76078bd4453177a13 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 03:41:40 +0200 Subject: [PATCH 01/11] Update BuildFFUVM.ps1 - Add script parameters to allow Windows Server image creation --- FFUDevelopment/BuildFFUVM.ps1 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 7829a3f..0c3011b 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -201,7 +201,11 @@ param( [Parameter(Mandatory = $false, Position = 0)] [ValidateScript({ Test-Path $_ })] [string]$ISOPath, - [ValidateSet('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')] + [ValidateScript({ + $allowedSKUs = @('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', 'Standard', 'Standard (Desktop Experience)', 'Datacenter', 'Datacenter (Desktop Experience)') + if ($allowedSKUs -contains $_) { $true } else { throw "Invalid WindowsSKU value. Allowed values: $($allowedSKUs -join ', ')" } + return $true + })] [string]$WindowsSKU = 'Pro', [ValidateScript({ Test-Path $_ })] [string]$FFUDevelopmentPath = $PSScriptRoot, @@ -267,7 +271,7 @@ param( [string]$ProductKey, [bool]$BuildUSBDrive, [Parameter(Mandatory = $false)] - [ValidateSet(10, 11)] + [ValidateSet(10, 11, 2016, 2019, 2022, 2025)] [int]$WindowsRelease = 11, [Parameter(Mandatory = $false)] [string]$WindowsVersion = '23h2', From cafc45dbba49948b96eff8ff31dc8b34cbbcb11f Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 03:53:45 +0200 Subject: [PATCH 02/11] Update BuildFFUVM.ps1 - Add Dell driver download support for Windows Server 2016, 2022 and fall back to 2022 drivers for other Server versions. --- FFUDevelopment/BuildFFUVM.ps1 | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 0c3011b..aa1a1e6 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -1325,10 +1325,21 @@ function Get-DellDrivers { [string]$Model, [Parameter(Mandatory = $true)] [ValidateSet("x64", "x86", "ARM64")] - [string]$WindowsArch + [string]$WindowsArch, + [Parameter(Mandatory = $true)] + [string]$WindowsRelease ) - $catalogUrl = "http://downloads.dell.com/catalog/CatalogPC.cab" + if ($WindowsRelease -le 11) { + $catalogUrl = "http://downloads.dell.com/catalog/CatalogPC.cab" + $DellCabFile = "$DriversFolder\CatalogPC.cab" + $DellCatalogXML = "$DriversFolder\CatalogPC.XML" + } else { + $catalogUrl = "https://downloads.dell.com/catalog/Catalog.cab" + $DellCabFile = "$DriversFolder\Catalog.cab" + $DellCatalogXML = "$DriversFolder\Catalog.xml" + } + if (-not (Test-Url -Url $catalogUrl)) { WriteLog "Dell Catalog cab URL is not accessible: $catalogUrl Exiting" if ($VerbosePreference -ne 'Continue') { @@ -1348,12 +1359,10 @@ function Get-DellDrivers { New-Item -Path $DriversFolder -ItemType Directory -Force | Out-Null WriteLog "Dell Drivers folder created" - $DellCabFile = "$DriversFolder\CatalogPC.cab" WriteLog "Downloading Dell Catalog cab file: $catalogUrl to $DellCabFile" Start-BitsTransferWithRetry -Source $catalogUrl -Destination $DellCabFile WriteLog "Dell Catalog cab file downloaded" - $DellCatalogXML = "$DriversFolder\CatalogPC.XML" WriteLog "Extracting Dell Catalog cab file to $DellCatalogXML" Invoke-Process -FilePath Expand.exe -ArgumentList "$DellCabFile $DellCatalogXML" WriteLog "Dell Catalog cab file extracted" @@ -1367,7 +1376,19 @@ function Get-DellDrivers { $models = $component.SupportedSystems.Brand.Model foreach ($item in $models) { if ($item.Display.'#cdata-section' -match $Model) { - $validOS = $component.SupportedOperatingSystems.OperatingSystem | Where-Object { $_.osArch -eq $WindowsArch } + + if ($WindowsRelease -le 11) { + $validOS = $component.SupportedOperatingSystems.OperatingSystem | Where-Object { $_.osArch -eq $WindowsArch } + } elseif ($WindowsRelease -eq 2016) { + $validOS = $component.SupportedOperatingSystems.OperatingSystem | Where-Object { ($_.osArch -eq $WindowsArch) -and ($_.osCode -match "W14") } + } elseif ($WindowsRelease -eq 2019) { + $validOS = $component.SupportedOperatingSystems.OperatingSystem | Where-Object { ($_.osArch -eq $WindowsArch) -and ($_.osCode -match "W19") } + } elseif ($WindowsRelease -eq 2022) { + $validOS = $component.SupportedOperatingSystems.OperatingSystem | Where-Object { ($_.osArch -eq $WindowsArch) -and ($_.osCode -match "W22") } + } else { + $validOS = $component.SupportedOperatingSystems.OperatingSystem | Where-Object { ($_.osArch -eq $WindowsArch) -and ($_.osCode -match "W22") } + } + if ($validOS) { $driverPath = $component.path $downloadUrl = $baseLocation + $driverPath @@ -3952,7 +3973,7 @@ if (($make -and $model) -and ($installdrivers -or $copydrivers)) { if ($make -eq 'Dell'){ WriteLog 'Getting Dell drivers' #Dell mixes Win10 and 11 drivers, hence no WindowsRelease parameter - Get-DellDrivers -Model $Model -WindowsArch $WindowsArch + Get-DellDrivers -Model $Model -WindowsArch $WindowsArch -WindowsRelease $WindowsRelease WriteLog 'Getting Dell drivers completed successfully' } } From 0b151f90546b6b19d986f80164e3535c2aba9787 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 03:55:37 +0200 Subject: [PATCH 03/11] Update BuildFFUVM.ps1 - Throw error when trying to download Windows Server as it's not possible --- FFUDevelopment/BuildFFUVM.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index aa1a1e6..73f8a08 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -1767,8 +1767,10 @@ function Get-WindowsESD { $cabFileUrl = if ($WindowsRelease -eq 10) { 'https://go.microsoft.com/fwlink/?LinkId=841361' } - else { + elseif ($WindowsRelease -eq 11) { 'https://go.microsoft.com/fwlink/?LinkId=2156292' + } else { + throw "Can't download Windows Server. Please download the Windows setup media from your subscription homepage." } # Download cab file From 5acac4ba5bddbed139b8c5f06d36909e0f5f5eea Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:02:28 +0200 Subject: [PATCH 04/11] Update BuildFFUVM.ps1 - Update Get-LatestWindowsKB to support searching for Windows Server updates - Improve the HTML regex to return a more precise match by using the $WindowsRelease variable for lookbehind based searching --- FFUDevelopment/BuildFFUVM.ps1 | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 73f8a08..3fc1b59 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -2414,16 +2414,21 @@ function Get-KBLink { } function Get-LatestWindowsKB { param ( - [ValidateSet(10, 11)] - [int]$WindowsRelease + [Parameter(Mandatory)] + [ValidateSet(10, 11, 2016, 2019, 2022, 2025)] + [int]$WindowsRelease, + [Parameter(Mandatory)] + [string]$WindowsVersion ) # Define the URL of the update history page based on the Windows release if ($WindowsRelease -eq 11) { $updateHistoryUrl = 'https://learn.microsoft.com/en-us/windows/release-health/windows11-release-information' } - else { + elseif ($WindowsRelease -eq 10) { $updateHistoryUrl = 'https://learn.microsoft.com/en-us/windows/release-health/release-information' + } else { + $updateHistoryUrl = 'https://learn.microsoft.com/en-us/windows/release-health/windows-server-release-info' } # Use Invoke-WebRequest to fetch the content of the page @@ -2433,7 +2438,11 @@ function Get-LatestWindowsKB { $VerbosePreference = $OriginalVerbosePreference # Use a regular expression to find the KB article number - $kbArticleRegex = 'KB\d+' + if ($WindowsRelease -le 11) { + $kbArticleRegex = "(?:Version $WindowsRelease \(OS build d+\)(?!(KB)).)*?KB\d+" + } else { + $kbArticleRegex = "(?:Windows Server $WindowsRelease \(OS build d+\)(?!(KB)).)*?KB\d+" + } $kbArticle = [regex]::Match($response.Content, $kbArticleRegex).Value return $kbArticle From 3457aedf5d760b67da6039293c2953fb280184cd Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:04:13 +0200 Subject: [PATCH 05/11] Update BuildFFUVM.ps1 - Add support for searching Windows Server SKUs in images in Get-WimIndex --- FFUDevelopment/BuildFFUVM.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 3fc1b59..0035aa9 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -2563,9 +2563,13 @@ function Get-WimIndex { If ($ISOPath) { $wimindex = switch ($WindowsSKU) { 'Home' { 1 } + 'Standard' { 1 } 'Home_N' { 2 } + 'Standard (Desktop Experience)' { 1 } 'Home_SL' { 3 } + 'Datacenter' { 3 } 'EDU' { 4 } + 'Datacenter (Desktop Experience)' { 4 } 'EDU_N' { 5 } 'Pro' { 6 } 'Pro_N' { 7 } From af28624e2d4f5eeb6cd775ee39a07a799416d1fd Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:08:01 +0200 Subject: [PATCH 06/11] Update BuildFFUVM.ps1 - Update Get-Index to support processing Windows Server images --- FFUDevelopment/BuildFFUVM.ps1 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 0035aa9..cf9bfc3 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -2600,8 +2600,13 @@ function Get-Index { # 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) + if ($WindowsSKU -notmatch "Standard|Datacenter") { + $imageIndex = $imageIndexes | Where-Object ImageIndex -eq 1 + $WindowsImage = $imageIndex.ImageName.Substring(0, 10) + } else { + $imageIndex = $imageIndexes | Where-Object ImageIndex -eq 1 + $WindowsImage = $imageIndex.ImageName.Substring(0, 19) + } } else{ $imageIndex = $imageIndexes | Where-Object ImageIndex -eq 4 @@ -2619,8 +2624,8 @@ function Get-Index { return $matchingImageIndex.ImageIndex } else { - # Look for either the number 10 or 11 in the ImageName - $relevantImageIndexes = $imageIndexes | Where-Object { ($_.ImageName -like "*10*") -or ($_.ImageName -like "*11*") } + # Look for the numbers 10, 11, 2016, 2019, 2022+ in the ImageName + $relevantImageIndexes = $imageIndexes | Where-Object { ($_.ImageName -match "(10|11|2016|2019|202\d)") } while ($true) { # Present list of ImageNames to the end user if no matching ImageIndex is found From 4b33627d197fd5153e9f9a3a2d4d8aea92f2c22e Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:11:15 +0200 Subject: [PATCH 07/11] Update BuildFFUVM.ps1 - Fix bug in New-OSPartition - CompactOS is now avoided on Windows Server --- FFUDevelopment/BuildFFUVM.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index cf9bfc3..832949e 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -2737,7 +2737,7 @@ function New-OSPartition { if ((Get-CimInstance Win32_OperatingSystem).Caption -match "Server") { WriteLog (Expand-WindowsImage -ImagePath $WimPath -Index $WimIndex -ApplyPath "$($osPartition.DriveLetter):\") } - if ($CompactOS) { + elseif ($CompactOS) { WriteLog '$CompactOS is set to true, using -Compact switch to apply the WIM file to the OS partition.' WriteLog (Expand-WindowsImage -ImagePath $WimPath -Index $WimIndex -ApplyPath "$($osPartition.DriveLetter):\" -Compact) } From ac485f9c871695f90f7f2d6fb2ecc77978b71630 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:16:57 +0200 Subject: [PATCH 08/11] Update BuildFFUVM.ps1 - Update Get-WindowsVersionInfo - Server Standard is now called 'Srv_Std' - Server Datacenter is now called 'Srv_Dtc' - 17763 is matched as Windows Server 2019 - 20348 is matched as Windows Server 2022 - 26100 is matched as Windows Server 2025 - other versions are matched as $DisplayVersion as a fallback Please remember to update the Windows Server version of 2025 in case it changes until release. --- FFUDevelopment/BuildFFUVM.ps1 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 832949e..48bd118 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -3265,14 +3265,25 @@ Function Get-WindowsVersionInfo { Enterprise { 'Ent' } Education { 'Edu' } ProfessionalWorkstation { 'Pro_Wks' } + ServerStandard { 'Srv_Std' } + ServerDatacenter { 'Srv_Dtc' } } WriteLog "Windows SKU Modified to: $SKU" - if ($CurrentBuild -ge 22000) { - $Name = 'Win11' - } - else { - $Name = 'Win10' + if ($SKU -notmatch "Srv") { + if ($CurrentBuild -ge 22000) { + $Name = 'Win11' + } + else { + $Name = 'Win10' + } + } else { + $Name = switch ($CurrentBuild) { + 26100 { '2025' } + 20348 { '2022' } + 17763 { '2019' } + Default { $DisplayVersion } + } } WriteLog "Unloading registry" From b8bda93e8df60ef00f1f48028231f91c504e161d Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:26:30 +0200 Subject: [PATCH 09/11] Update BuildFFUVM.ps1 - Updated MU Catalog search - Search now includes searching for Windows Server updates Has been verified to work for Windows Server 2022 and Windows Server 2025 only. --- FFUDevelopment/BuildFFUVM.ps1 | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 48bd118..0dba935 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -4233,7 +4233,15 @@ try { #The Windows release info page is updated later than the MU Catalog if ($UpdateLatestCU -and -not $UpdatePreviewCU) { Writelog "`$UpdateLatestCU is set to true, checking for latest CU" - $Name = """Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch""" + if ($WindowsRelease -le 11) { + $Name = """Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch""" + } elseif ($WindowsRelease -eq 2022) { + $Name = """Cumulative Update for Microsoft server operating system, version $WindowsVersion for $WindowsArch""" + } elseif ($WindowsRelease -lt 2022) { + $Name = """Cumulative update for Windows 10 Version $WindowsVersion for $WindowsArch""" + } else { + $Name = """Cumulative update for Windows 11 Version $WindowsVersion for $WindowsArch""" + } #Check if $KBPath exists, if not, create it If (-not (Test-Path -Path $KBPath)) { WriteLog "Creating $KBPath" @@ -4248,7 +4256,15 @@ try { #will take Precendence over $UpdateLastestCU if both were set to $true if ($UpdatePreviewCU) { Writelog "`$UpdatePreviewCU is set to true, checking for latest Preview CU" - $Name = """Cumulative update Preview for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch""" + if ($WindowsRelease -le 11) { + $Name = """Cumulative update Preview for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch""" + } elseif ($WindowsRelease -eq 2022) { + $Name = """Cumulative Update Preview for Microsoft server operating system, version $WindowsVersion for $WindowsArch""" + } elseif ($WindowsRelease -lt 2022) { + $Name = """Cumulative update Preview for Windows 10 Version $WindowsVersion for $WindowsArch""" + } else { + $Name = """Cumulative update Preview for Windows 11 Version $WindowsVersion for $WindowsArch""" + } #Check if $KBPath exists, if not, create it If (-not (Test-Path -Path $KBPath)) { WriteLog "Creating $KBPath" From b6dda55a827306b1b5b619175ef342cf335af355 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:29:04 +0200 Subject: [PATCH 10/11] Update BuildFFUVM.ps1 - Updated the .NET Framework download code - Download the appropriate .NET Framework for Windows Server --- FFUDevelopment/BuildFFUVM.ps1 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 0dba935..67552ad 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -4278,7 +4278,13 @@ try { #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 $WindowsArch -preview" + if ($WindowsRelease -le 11) { + $Name = "Cumulative update for .net framework windows $WindowsRelease $WindowsVersion $WindowsArch -preview" + } elseif ($WindowsRelease -le 2022) { + $Name = "Cumulative update for .net framework windows 10 $WindowsVersion for $WindowsArch -preview" + } else { + $Name = "Cumulative update for .net framework windows 11 $WindowsVersion for $WindowsArch -preview" + } #Check if $KBPath exists, if not, create it If (-not (Test-Path -Path $KBPath)) { WriteLog "Creating $KBPath" From 412e3a078c7422975edb472bc007b1f163ea0be7 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 04:37:09 +0200 Subject: [PATCH 11/11] Update CaptureFFU.ps1 - Add Windows Server support like in BuildFFUVM.ps1 --- .../WinPECaptureFFUFiles/CaptureFFU.ps1 | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 index fb4b964..8a5cee8 100644 --- a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 +++ b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 @@ -28,13 +28,24 @@ $SKU = switch ($SKU) { EducationN { 'EduN'} ProfessionalWorkstation { 'Pro_Wks' } ProfessionalWorkstationN { 'Pro_WksN' } + ServerStandard { 'Srv_Std' } + ServerDatacenter { 'Srv_Dtc' } } -if($CurrentBuild -ge 22000){ - $Name = 'Win11' -} -else{ - $Name = 'Win10' +if ($SKU -notmatch "Srv") { + if ($CurrentBuild -ge 22000) { + $Name = 'Win11' + } + else { + $Name = 'Win10' + } +} else { + $Name = switch ($CurrentBuild) { + 26100 { '2025' } + 20348 { '2022' } + 17763 { '2019' } + Default { $DisplayVersion } + } } #If Office is installed, modify the file name of the FFU