From e3cbcab6b2944404aec397c76078bd4453177a13 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 23 Sep 2024 03:41:40 +0200 Subject: [PATCH 01/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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/17] 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 From 15c0478710dc463b3c1bf3e0b6ee94a2ac476956 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Thu, 26 Sep 2024 17:15:17 +0200 Subject: [PATCH 12/17] Update BuildFFUVM.ps1 1/2 - Add parameter $AppsScriptVariablesvariable - Allow value based behavior changes during the app install phase in InstallAppsandSysprep.cmd --- FFUDevelopment/BuildFFUVM.ps1 | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 3d98155..d97fd16 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -210,6 +210,7 @@ param( [ValidateScript({ Test-Path $_ })] [string]$FFUDevelopmentPath = $PSScriptRoot, [bool]$InstallApps, + [hashtable]$AppsScriptVariables, [bool]$InstallOffice, [ValidateSet('Microsoft', 'Dell', 'HP', 'Lenovo')] [string]$Make, @@ -4028,6 +4029,31 @@ if ($InstallApps) { Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $UpdatedcmdContent WriteLog "Update complete" } + + if (-not $AppsScriptVariables) { + #Modify InstallAppsandSysprep.cmd to remove the script variables + $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" + $StartIndex = $CmdContent.IndexOf("REM START Batch variables placeholder") + $EndIndex = $CmdContent.IndexOf("REM END Batch variables placeholder") + if (($StartIndex + 1) -lt $EndIndex) { + for ($i = ($StartIndex + 1); $i -lt $EndIndex; $i++) { + $CmdContent[$i] = $null + } + } + Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $CmdContent + } + + if ($AppsScriptVariables) { + #Modify InstallAppsandSysprep.cmd to add the script variables + $CmdContent = [System.Collections.ArrayList](Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd") + $ScriptIndex = $CmdContent.IndexOf("REM START Batch variables placeholder") + 1 + foreach ($VariableKey in $AppsScriptVariables.Keys) { + $CmdContent.Insert($ScriptIndex, ("set {0}={1}" -f $VariableKey, $AppsScriptVariables[$VariableKey])) + $ScriptIndex++ + } + Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $CmdContent + } + #Create Apps ISO WriteLog "Creating $AppsISO file" New-AppsISO From 6a0faa958ec8dc9674abaade6b2a1446629af271 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Thu, 26 Sep 2024 17:16:22 +0200 Subject: [PATCH 13/17] Update InstallAppsandSysprep.cmd 2/2 - Add parameter $AppsScriptVariablesvariable - Allow value based behavior changes during the app install phase in InstallAppsandSysprep.cmd --- FFUDevelopment/Apps/InstallAppsandSysprep.cmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FFUDevelopment/Apps/InstallAppsandSysprep.cmd b/FFUDevelopment/Apps/InstallAppsandSysprep.cmd index aba7da8..ba69335 100644 --- a/FFUDevelopment/Apps/InstallAppsandSysprep.cmd +++ b/FFUDevelopment/Apps/InstallAppsandSysprep.cmd @@ -8,6 +8,8 @@ REM Install Windows Security Platform Update REM Install OneDrive Per Machine REM Install Edge Stable REM Winget Win32 Apps +REM START Batch variables placeholder +REM END Batch variables placeholder REM Add additional apps below here REM Contoso App (Example) REM msiexec /i d:\Contoso\setup.msi /qn /norestart From 5545554d7e07a57e2cdd2e9e57a782c2ba558bc4 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Thu, 26 Sep 2024 20:08:47 +0200 Subject: [PATCH 14/17] Update BuildFFUVM.ps1 - Fix accidental variable accumulation in InstallAppsandSysprep.cmd --- FFUDevelopment/BuildFFUVM.ps1 | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index d97fd16..5e2f5b6 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -4030,18 +4030,16 @@ if ($InstallApps) { WriteLog "Update complete" } - if (-not $AppsScriptVariables) { - #Modify InstallAppsandSysprep.cmd to remove the script variables - $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" - $StartIndex = $CmdContent.IndexOf("REM START Batch variables placeholder") - $EndIndex = $CmdContent.IndexOf("REM END Batch variables placeholder") - if (($StartIndex + 1) -lt $EndIndex) { - for ($i = ($StartIndex + 1); $i -lt $EndIndex; $i++) { - $CmdContent[$i] = $null - } + #Modify InstallAppsandSysprep.cmd to remove old script variables + $CmdContent = Get-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" + $StartIndex = $CmdContent.IndexOf("REM START Batch variables placeholder") + $EndIndex = $CmdContent.IndexOf("REM END Batch variables placeholder") + if (($StartIndex + 1) -lt $EndIndex) { + for ($i = ($StartIndex + 1); $i -lt $EndIndex; $i++) { + $CmdContent[$i] = $null } - Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $CmdContent } + Set-Content -Path "$AppsPath\InstallAppsandSysprep.cmd" -Value $CmdContent if ($AppsScriptVariables) { #Modify InstallAppsandSysprep.cmd to add the script variables From 6e5d634af65796aad3ec7dbfcd99103184d41bc5 Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Fri, 27 Sep 2024 02:15:25 +0200 Subject: [PATCH 15/17] Update BuildFFUVM.ps1 - Bypass VMSwitchIPAddress to VMHostAddress check on systems with a configured NAT setup --- FFUDevelopment/BuildFFUVM.ps1 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index dadc8cf..2e6e681 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -3805,7 +3805,19 @@ if (($VMHostIPAddress) -and ($VMSwitchName)){ throw "IP address for -VMSwitchName $VMSwitchName not found. Please check the -VMSwitchName parameter and try again." } if ($VMSwitchIPAddress -ne $VMHostIPAddress) { - throw "IP address for -VMSwitchName $VMSwitchName is $VMSwitchIPAddress, which does not match the -VMHostIPAddress $VMHostIPAddress. Please check the -VMHostIPAddress parameter and try again." + try { + # Bypass the check for systems that could have a Hyper-V NAT switch + $null = Get-NetNat -ErrorAction Stop + $NetNat = @(Get-NetNat -ErrorAction Stop); + } catch { + throw "IP address for -VMSwitchName $VMSwitchName is $VMSwitchIPAddress, which does not match the -VMHostIPAddress $VMHostIPAddress. Please check the -VMHostIPAddress parameter and try again." + } + if ($NetNat.Count -gt 0) { + WriteLog "IP address for -VMSwitchName $VMSwitchName is $VMSwitchIPAddress, which does not match the -VMHostIPAddress $VMHostIPAddress!" + WriteLog "NAT setup detected, remember to configure NATing if the FFU image can't be captured to the network share on the host." + } else { + throw "IP address for -VMSwitchName $VMSwitchName is $VMSwitchIPAddress, which does not match the -VMHostIPAddress $VMHostIPAddress. Please check the -VMHostIPAddress parameter and try again." + } } WriteLog '-VMSwitchName and -VMHostIPAddress validation complete' } From 5194133a78eaafc0f4e6aa626f680651e9f2133a Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Fri, 27 Sep 2024 18:34:41 +0200 Subject: [PATCH 16/17] Update BuildFFUVM.ps1 - Add help for parameter AppsScriptVariables --- FFUDevelopment/BuildFFUVM.ps1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 2e6e681..3dcf517 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -169,6 +169,9 @@ Make of the device to download drivers. Accepted values are: 'Microsoft', 'Dell' .PARAMETER Model Model of the device to download drivers. This is required if Make is set. +.PARAMETER AppsScriptVariables +When passed a hashtable, the script will alter the $FFUDevelopmentPath\Apps\InstallAppsandSysprep.cmd file to set variables with the hashtable keys as variable names and the hashtable values their content. + .EXAMPLE Command line for most people who want to download the latest Windows 11 Pro x64 media in English (US) with the latest Windows Cumulative Update, .NET Framework, Defender platform and definition updates, Edge, OneDrive, and Office/M365 Apps. It will also copy drivers to the FFU. This can take about 40 minutes to create the FFU due to the time it takes to download and install the updates. .\BuildFFUVM.ps1 -WindowsSKU 'Pro' -Installapps $true -InstallOffice $true -InstallDrivers $true -VMSwitchName 'Name of your VM Switch in Hyper-V' -VMHostIPAddress 'Your IP Address' -CreateCaptureMedia $true -CreateDeploymentMedia $true -BuildUSBDrive $true -UpdateLatestCU $true -UpdateLatestNet $true -UpdateLatestDefender $true -UpdateEdge $true -UpdateOneDrive $true -verbose From f144f1d71c64f4a4561548202f1750120df3c7aa Mon Sep 17 00:00:00 2001 From: JonasKloseBW Date: Mon, 30 Sep 2024 16:52:15 +0200 Subject: [PATCH 17/17] Update CaptureFFU.ps1 - Add support for Server Core in SKU name --- FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 index 8a5cee8..81a7907 100644 --- a/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 +++ b/FFUDevelopment/WinPECaptureFFUFiles/CaptureFFU.ps1 @@ -12,6 +12,7 @@ reg load "HKLM\FFU" $Software $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' $DisplayVersion = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'DisplayVersion' +$InstallationType = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'InstallationType' $BuildDate = Get-Date -uformat %b%Y $SKU = switch ($SKU) { @@ -32,7 +33,7 @@ $SKU = switch ($SKU) { ServerDatacenter { 'Srv_Dtc' } } -if ($SKU -notmatch "Srv") { +if ($InstallationType -eq "Client") { if ($CurrentBuild -ge 22000) { $Name = 'Win11' } @@ -46,6 +47,9 @@ if ($SKU -notmatch "Srv") { 17763 { '2019' } Default { $DisplayVersion } } + if ($InstallationType -eq "Server Core") { + $SKU += "_Core" + } } #If Office is installed, modify the file name of the FFU