Merge pull request #116 from zehadialam/win-ltsc

Support for Windows LTSC
This commit is contained in:
rbalsleyMSFT
2025-05-19 11:04:51 -07:00
committed by GitHub
2 changed files with 158 additions and 43 deletions
+134 -21
View File
@@ -224,14 +224,12 @@ param(
[Parameter(Mandatory = $false, Position = 0)] [Parameter(Mandatory = $false, Position = 0)]
[ValidateScript({ Test-Path $_ })] [ValidateScript({ Test-Path $_ })]
[string]$ISOPath, [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', 'Standard', 'Standard (Desktop Experience)', 'Datacenter', 'Datacenter (Desktop Experience)')] [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', 'Enterprise LTSC', 'Enterprise N LTSC', 'IoT Enterprise LTSC', 'IoT Enterprise N LTSC', 'Standard', 'Standard (Desktop Experience)', 'Datacenter', 'Datacenter (Desktop Experience)')]
[string]$WindowsSKU = 'Pro', [string]$WindowsSKU = 'Pro',
[ValidateScript({ Test-Path $_ })] [ValidateScript({ Test-Path $_ })]
[string]$FFUDevelopmentPath = $PSScriptRoot, [string]$FFUDevelopmentPath = $PSScriptRoot,
[bool]$InstallApps, [bool]$InstallApps,
[string]$AppListPath, [string]$AppListPath,
[hashtable]$AppsScriptVariables, [hashtable]$AppsScriptVariables,
[bool]$InstallOffice, [bool]$InstallOffice,
[ValidateSet('Microsoft', 'Dell', 'HP', 'Lenovo')] [ValidateSet('Microsoft', 'Dell', 'HP', 'Lenovo')]
@@ -285,7 +283,7 @@ param(
[string]$ProductKey, [string]$ProductKey,
[bool]$BuildUSBDrive, [bool]$BuildUSBDrive,
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[ValidateSet(10, 11, 2016, 2019, 2022, 2025)] [ValidateSet(10, 11, 2016, 2019, 2021, 2022, 2024, 2025)]
[int]$WindowsRelease = 11, [int]$WindowsRelease = 11,
[Parameter(Mandatory = $false)] [Parameter(Mandatory = $false)]
[string]$WindowsVersion = '24h2', [string]$WindowsVersion = '24h2',
@@ -401,6 +399,26 @@ if ($ConfigFile -and (Test-Path -Path $ConfigFile)) {
} }
} }
$clientSKUs = @('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')
$LTSCSKUs = @('Enterprise LTSC', 'Enterprise N LTSC', 'IoT Enterprise LTSC', 'IoT Enterprise N LTSC')
$ServerSKUs = @('Standard', 'Standard (Desktop Experience)', 'Datacenter', 'Datacenter (Desktop Experience)')
$releaseToSKUMapping = @{
10 = $clientSKUs
11 = $clientSKUs
2016 = $LTSCSKUs + $ServerSKUs
2019 = $LTSCSKUs + $ServerSKUs
2021 = $LTSCSKUs
2022 = $ServerSKUs
2024 = $LTSCSKUs
2025 = $ServerSKUs
}
if ($releaseToSKUMapping.ContainsKey($WindowsRelease) -and $WindowsSKU -notin $releaseToSKUMapping[$WindowsRelease]) {
throw "Selected SKU is $WindowsSKU. Windows $WindowsRelease requires one of these SKUs: $($releaseToSKUMapping[$WindowsRelease] -join ', ')"
}
if ($WindowsRelease -notin 10, 11 -and -not $ISOPath) {
throw "Windows $WindowsRelease cannot automatically be downloaded. Please specify your own ISO using the -ISOPath parameter."
}
#Class definition for vhdx cache #Class definition for vhdx cache
class VhdxCacheUpdateItem { class VhdxCacheUpdateItem {
[string]$Name [string]$Name
@@ -462,7 +480,7 @@ if (-not $UnattendFolder) { $UnattendFolder = "$FFUDevelopmentPath\Unattend" }
if (-not $AutopilotFolder) { $AutopilotFolder = "$FFUDevelopmentPath\Autopilot" } if (-not $AutopilotFolder) { $AutopilotFolder = "$FFUDevelopmentPath\Autopilot" }
if (-not $PEDriversFolder) { $PEDriversFolder = "$FFUDevelopmentPath\PEDrivers" } if (-not $PEDriversFolder) { $PEDriversFolder = "$FFUDevelopmentPath\PEDrivers" }
if (-not $VHDXCacheFolder) { $VHDXCacheFolder = "$FFUDevelopmentPath\VHDXCache" } if (-not $VHDXCacheFolder) { $VHDXCacheFolder = "$FFUDevelopmentPath\VHDXCache" }
if (-not $installationType) { $installationType = if ($WindowsRelease.ToString().Length -eq 2) { 'Client' } else { 'Server' } } if (-not $installationType) { $installationType = if ($WindowsSKU -like "Standard*" -or $WindowsSKU -like "Datacenter*") { 'Server' } else { 'Client' } }
if ($installationType -eq 'Server'){ if ($installationType -eq 'Server'){
#Map $WindowsRelease to $WindowsVersion for Windows Server #Map $WindowsRelease to $WindowsVersion for Windows Server
switch ($WindowsRelease) { switch ($WindowsRelease) {
@@ -474,6 +492,15 @@ if ($installationType -eq 'Server'){
} }
if (-not $AppListPath) { $AppListPath = "$AppsPath\AppList.json" } if (-not $AppListPath) { $AppListPath = "$AppsPath\AppList.json" }
if ($WindowsSKU -like "*LTSC") {
switch ($WindowsRelease) {
2016 { $WindowsVersion = '1607' }
2019 { $WindowsVersion = '1809' }
2021 { $WindowsVersion = '21H2' }
2024 { $WindowsVersion = '24H2' }
}
}
#FUNCTIONS #FUNCTIONS
function WriteLog($LogText) { function WriteLog($LogText) {
Add-Content -path $LogFile -value "$((Get-Date).ToString()) $LogText" -Force -ErrorAction SilentlyContinue Add-Content -path $LogFile -value "$((Get-Date).ToString()) $LogText" -Force -ErrorAction SilentlyContinue
@@ -1813,7 +1840,7 @@ function Get-WindowsESD {
elseif ($WindowsRelease -eq 11) { elseif ($WindowsRelease -eq 11) {
'https://go.microsoft.com/fwlink/?LinkId=2156292' 'https://go.microsoft.com/fwlink/?LinkId=2156292'
} else { } else {
throw "Downloading Windows Server is not supported. Please use the -ISOPath parameter to specify the path to the Windows Server ISO file." throw "Downloading Windows $WindowsRelease is not supported. Please use the -ISOPath parameter to specify the path to the Windows $WindowsRelease ISO file."
} }
# Download cab file # Download cab file
@@ -2627,6 +2654,10 @@ function Get-WimIndex {
'Pro_Edu_N' { 9 } 'Pro_Edu_N' { 9 }
'Pro_WKS' { 10 } 'Pro_WKS' { 10 }
'Pro_WKS_N' { 11 } 'Pro_WKS_N' { 11 }
'Enterprise' { 3 }
'Enterprise N' { 4 }
'Enterprise LTSC' { 1 }
'Enterprise N LTSC' { 2 }
Default { 6 } Default { 6 }
} }
} }
@@ -3417,6 +3448,20 @@ Function Get-WindowsVersionInfo {
$BuildDate = Get-Date -uformat %b%Y $BuildDate = Get-Date -uformat %b%Y
$SKU = switch ($SKU) {
Core { 'Home' }
Professional { 'Pro' }
ProfessionalEducation { 'Pro_Edu' }
Enterprise { 'Ent' }
EnterpriseS { 'Ent_LTSC' }
IoTEnterpriseS { 'IoT_Ent_LTSC' }
Education { 'Edu' }
ProfessionalWorkstation { 'Pro_Wks' }
ServerStandard { 'Srv_Std' }
ServerDatacenter { 'Srv_Dtc' }
}
WriteLog "Windows SKU Modified to: $SKU"
# $WindowsSKU = switch ($WindowsSKU) { # $WindowsSKU = switch ($WindowsSKU) {
# Core { 'Home' } # Core { 'Home' }
# Professional { 'Pro' } # Professional { 'Pro' }
@@ -4407,9 +4452,15 @@ if ($InstallApps) {
if ($UpdateLatestMSRT) { if ($UpdateLatestMSRT) {
WriteLog "`$UpdateLatestMSRT is set to true." WriteLog "`$UpdateLatestMSRT is set to true."
if ($WindowsArch -eq 'x64') { if ($WindowsArch -eq 'x64') {
if ($installationType -eq 'client') { if ($WindowsRelease -in 10, 11) {
$Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows $WindowsRelease""" $Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows $WindowsRelease"""
} }
elseif ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC") {
$Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows 10"""
}
elseif ($WindowsRelease -in 2024 -and $WindowsSKU -like "*LTSC") {
$Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows 11"""
}
#Windows Server 2025 isn't listed as a product in the Microsoft Update Catalog, so we'll use the 2019 version #Windows Server 2025 isn't listed as a product in the Microsoft Update Catalog, so we'll use the 2019 version
elseif ($installationType -eq 'server' -and $WindowsRelease -eq '24H2') { elseif ($installationType -eq 'server' -and $WindowsRelease -eq '24H2') {
$Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows Server 2019""" $Name = """Windows Malicious Software Removal Tool x64""" + " " + """Windows Server 2019"""
@@ -4546,7 +4597,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 -and -not $UpdatePreviewCU) { if ($UpdateLatestCU -and -not $UpdatePreviewCU) {
Writelog "`$UpdateLatestCU is set to true, checking for latest CU" Writelog "`$UpdateLatestCU is set to true, checking for latest CU"
if ($installationType -eq 'Client') { if ($WindowsRelease -in 10, 11) {
$Name = """Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch""" $Name = """Cumulative update for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch"""
} }
if ($WindowsRelease -eq 2025) { if ($WindowsRelease -eq 2025) {
@@ -4555,9 +4606,20 @@ try {
if ($WindowsRelease -eq 2022) { if ($WindowsRelease -eq 2022) {
$Name = """Cumulative Update for Microsoft server operating system, version 21h2 for $WindowsArch""" $Name = """Cumulative Update for Microsoft server operating system, version 21h2 for $WindowsArch"""
} }
if ($WindowsRelease -in 2016, 2019) { if ($WindowsRelease -in 2016, 2019 -and $installationType -eq "Server") {
$Name = """Cumulative update for Windows Server $WindowsRelease for $WindowsArch""" $Name = """Cumulative update for Windows Server $WindowsRelease for $WindowsArch"""
} }
if ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC") {
$today = Get-Date
$firstDayOfMonth = Get-Date -Year $today.Year -Month $today.Month -Day 1
$secondTuesday = $firstDayOfMonth.AddDays(((2 - [int]$firstDayOfMonth.DayOfWeek + 7) % 7) + 7)
$updateDate = if ($today -gt $secondTuesday) { $today } else { $today.AddMonths(-1) }
# More precise search to prevent Dynamic cumulative update from being chosen.
$Name = """$($updateDate.ToString('yyyy-MM')) Cumulative update for Windows 10 Version $WindowsVersion for $WindowsArch"""
}
if ($WindowsRelease -eq 2024 -and $WindowsSKU -like "*LTSC") {
$Name = """Cumulative update for Windows 11 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"
@@ -4571,6 +4633,13 @@ try {
$SSUFilePath = "$KBPath\$SSUFile" $SSUFilePath = "$KBPath\$SSUFile"
WriteLog "Latest SSU saved to $SSUFilePath" WriteLog "Latest SSU saved to $SSUFilePath"
} }
if ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC") {
$SSUName = """Servicing Stack Update for Windows 10 Version $WindowsVersion for $WindowsArch"""
WriteLog "Searching for $SSUName from Microsoft Update Catalog and saving to $KBPath"
$SSUFile = Save-KB -Name $SSUName -Path $KBPath
$SSUFilePath = "$KBPath\$SSUFile"
WriteLog "Latest SSU saved to $SSUFilePath"
}
WriteLog "Searching for $name from Microsoft Update Catalog and saving to $KBPath" WriteLog "Searching for $name from Microsoft Update Catalog and saving to $KBPath"
$CUFileName = Save-KB -Name $Name -Path $KBPath $CUFileName = Save-KB -Name $Name -Path $KBPath
# Check if $CUFileName contains the string in $global:LastKBArticleID # Check if $CUFileName contains the string in $global:LastKBArticleID
@@ -4597,7 +4666,7 @@ try {
#Update Latest Preview Cumlative Update for Client OS only #Update Latest Preview Cumlative Update for Client OS only
#will take Precendence over $UpdateLatestCU if both were set to $true #will take Precendence over $UpdateLatestCU if both were set to $true
if ($UpdatePreviewCU -and $installationType -eq 'Client') { if ($UpdatePreviewCU -and $installationType -eq 'Client' -and $WindowsSKU -notlike "*LTSC") {
Writelog "`$UpdatePreviewCU is set to true, checking for latest Preview CU" Writelog "`$UpdatePreviewCU is set to true, checking for latest Preview CU"
$Name = """Cumulative update Preview for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch""" $Name = """Cumulative update Preview for Windows $WindowsRelease Version $WindowsVersion for $WindowsArch"""
#Check if $KBPath exists, if not, create it #Check if $KBPath exists, if not, create it
@@ -4632,8 +4701,20 @@ 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"
if ($installationType -eq 'Client') { #Check if $KBPath exists, if not, create it
$Name = "Cumulative update for .net framework windows $WindowsRelease $WindowsVersion $WindowsArch -preview" if (-not (Test-Path -Path $KBPath)) {
WriteLog "Creating $KBPath"
New-Item -Path $KBPath -ItemType Directory -Force | Out-Null
}
if ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC") {
$SSUName = """Servicing Stack Update for Windows 10 Version $WindowsVersion for $WindowsArch"""
WriteLog "Searching for $SSUName from Microsoft Update Catalog and saving to $KBPath"
$SSUFile = Save-KB -Name $SSUName -Path $KBPath
$SSUFilePath = "$KBPath\$SSUFile"
WriteLog "Latest SSU saved to $SSUFilePath"
}
if ($WindowsRelease -in 10, 11) {
$Name = "Cumulative update for .NET framework windows $WindowsRelease $WindowsVersion $WindowsArch -preview"
} }
if ($WindowsRelease -eq 2025) { if ($WindowsRelease -eq 2025) {
$Name = """Cumulative Update for .NET Framework"" ""3.5 and 4.8.1"" for Windows 11 24H2 x64 -preview" $Name = """Cumulative Update for .NET Framework"" ""3.5 and 4.8.1"" for Windows 11 24H2 x64 -preview"
@@ -4641,18 +4722,41 @@ try {
if ($WindowsRelease -eq 2022) { if ($WindowsRelease -eq 2022) {
$Name = """Cumulative Update for .NET Framework 3.5, 4.8 and 4.8.1"" ""operating system version 21H2 for x64""" $Name = """Cumulative Update for .NET Framework 3.5, 4.8 and 4.8.1"" ""operating system version 21H2 for x64"""
} }
if ($WindowsRelease -eq 2019) { if ($WindowsRelease -eq 2019 -and $installationType -eq "Server") {
$Name = """Cumulative Update for .NET Framework 3.5, 4.7.2 and 4.8 for Windows Server 2019 for x64""" $Name = """Cumulative Update for .NET Framework 3.5, 4.7.2 and 4.8 for Windows Server 2019 for x64"""
} }
if ($WindowsRelease -eq 2016) { if ($WindowsRelease -eq 2016 -and $installationType -eq "Server") {
$Name = """Cumulative Update for .NET Framework 4.8 for Windows Server 2016 for x64""" $Name = """Cumulative Update for .NET Framework 4.8 for Windows Server 2016 for x64"""
} }
#Check if $KBPath exists, if not, create it if ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC") {
If (-not (Test-Path -Path $KBPath)) { $Name = "Cumulative update for .net framework windows 10 $WindowsVersion $WindowsArch"
WriteLog "Creating $KBPath" $NETPath = Join-Path -Path $KBPath -ChildPath "NET"
New-Item -Path $KBPath -ItemType Directory -Force | Out-Null # These LTSC editions include multiple .NET updates, so a separate directory is created and specified to allow DISM
# to install them all, instead of specifying each .NET update individually.
if (-not (Test-Path -Path $NETPath)) {
WriteLog "Creating $NETPath"
New-Item -Path $NETPath -ItemType Directory -Force | Out-Null
}
$NETFileName = Save-KB -Name $Name -Path $NETPath
WriteLog "Latest .NET Framework cumulative update saved to $NETPath\$NETFileName"
}
if ($WindowsRelease -eq 2024) {
$Name = "Cumulative update for .NET framework windows 11 $WindowsVersion $WindowsArch"
} }
WriteLog "Searching for $name from Microsoft Update Catalog and saving to $KBPath" WriteLog "Searching for $name from Microsoft Update Catalog and saving to $KBPath"
if ($WindowsRelease -eq 2021) {
WriteLog "Checking for latest .NET Framework feature pack for Windows $WindowsRelease $WindowsSKU"
$NETFeatureName = """Microsoft .NET Framework 4.8.1 for Windows 10 Version 21H2 for x64"""
$NETFeaturePackFile = Save-KB -Name $NETFeatureName -Path $NETPath
WriteLog "Latest .NET Framework Feature pack saved to $NETPath\$NETFeaturePackFile"
}
if ($WindowsRelease -in 2016, 2019) {
WriteLog "Checking for latest .NET Framework feature pack for Windows $WindowsRelease $WindowsSKU"
$NETFeatureName = """Microsoft .NET Framework 4.8 for Windows 10 Version $WindowsVersion and Windows Server $WindowsRelease for x64"""
$NETFeaturePackFile = Save-KB -Name $NETFeatureName -Path $NETPath
WriteLog "Latest .NET Framework Feature pack saved to $NETPath\$NETFeaturePackFile"
}
if (-not ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC")) {
$NETFileName = Save-KB -Name $Name -Path $KBPath $NETFileName = Save-KB -Name $Name -Path $KBPath
# Check if $NETFileName contains the string in $global:LastKBArticleID # Check if $NETFileName contains the string in $global:LastKBArticleID
# If it does not, look in $KBPath for the file that contains the string in $global:LastKBArticleID # If it does not, look in $KBPath for the file that contains the string in $global:LastKBArticleID
@@ -4674,6 +4778,7 @@ try {
$NETPath = "$KBPath\$NETFileName" $NETPath = "$KBPath\$NETFileName"
WriteLog "Latest .NET Framework saved to $NETPath" WriteLog "Latest .NET Framework saved to $NETPath"
} }
}
#Search for cached VHDX and skip VHDX creation if there's a cached version #Search for cached VHDX and skip VHDX creation if there's a cached version
if ($AllowVHDXCaching) { if ($AllowVHDXCaching) {
@@ -4779,7 +4884,7 @@ try {
WriteLog "Adding KBs to $WindowsPartition" WriteLog "Adding KBs to $WindowsPartition"
WriteLog 'This can take 10+ minutes depending on how old the media is and the size of the KB. Please be patient' WriteLog 'This can take 10+ minutes depending on how old the media is and the size of the KB. Please be patient'
# If WindowsRelease is 2016, we need to add the SSU first # If WindowsRelease is 2016, we need to add the SSU first
if ($WindowsRelease -eq 2016) { if ($WindowsRelease -eq 2016 -and $installationType -eq "Server") {
WriteLog 'WindowsRelease is 2016, adding SSU first' WriteLog 'WindowsRelease is 2016, adding SSU first'
WriteLog "Adding SSU to $WindowsPartition" WriteLog "Adding SSU to $WindowsPartition"
# Add-WindowsPackage -Path $WindowsPartition -PackagePath $SSUFilePath -PreventPending | Out-Null # Add-WindowsPackage -Path $WindowsPartition -PackagePath $SSUFilePath -PreventPending | Out-Null
@@ -4790,9 +4895,16 @@ try {
WriteLog "Removing $SSUFilePath" WriteLog "Removing $SSUFilePath"
Remove-Item -Path $SSUFilePath -Force | Out-Null Remove-Item -Path $SSUFilePath -Force | Out-Null
WriteLog 'SSU removed' WriteLog 'SSU removed'
WriteLog "Adding CU to $WindowsPartition"
} }
if ($WindowsRelease -in 2016, 2019, 2021 -and $WindowsSKU -like "*LTSC") {
WriteLog "WindowsRelease is $WindowsRelease and is $WindowsSKU, adding SSU first"
WriteLog "Adding SSU to $WindowsPartition"
Add-WindowsPackage -Path $WindowsPartition -PackagePath $SSUFilePath | Out-Null
WriteLog "SSU added to $WindowsPartition"
WriteLog "Removing $SSUFilePath"
Remove-Item -Path $SSUFilePath -Force | Out-Null
WriteLog 'SSU removed'
}
# Break out CU and NET updates to be added separately to abide by Checkpoint Update recommendations # Break out CU and NET updates to be added separately to abide by Checkpoint Update recommendations
if ($UpdateLatestCU) { if ($UpdateLatestCU) {
WriteLog "Adding $CUPath to $WindowsPartition" WriteLog "Adding $CUPath to $WindowsPartition"
@@ -4823,6 +4935,7 @@ try {
WriteLog 'Clean Up the WinSxS Folder' WriteLog 'Clean Up the WinSxS Folder'
WriteLog 'This can take 10+ minutes depending on how old the media is and the size of the KB. Please be patient' WriteLog 'This can take 10+ minutes depending on how old the media is and the size of the KB. Please be patient'
Dism /Image:$WindowsPartition /Cleanup-Image /StartComponentCleanup /ResetBase | Out-Null Dism /Image:$WindowsPartition /Cleanup-Image /StartComponentCleanup /ResetBase | Out-Null
# Repair-WindowsImage -Path $WindowsPartition -StartComponentCleanup -ResetBase | Out-Null
WriteLog 'Clean Up the WinSxS Folder completed' 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 $_"
@@ -12,10 +12,10 @@ reg load "HKLM\FFU" $Software
$SKU = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'EditionID' $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' [int]$CurrentBuild = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'CurrentBuild'
if ($CurrentBuild -notin 14393, 17763) { $InstallationType = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'InstallationType'
if ($CurrentBuild -notin 14393, 17763 -and $InstallationType -ne "Server") {
$WindowsVersion = Get-ItemPropertyValue -Path 'HKLM:\FFU\Microsoft\Windows NT\CurrentVersion\' -Name 'DisplayVersion' $WindowsVersion = 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 $BuildDate = Get-Date -uformat %b%Y
$SKU = switch ($SKU) { $SKU = switch ($SKU) {
@@ -27,7 +27,9 @@ $SKU = switch ($SKU) {
ProfessionalEducation { 'Pro_Edu' } ProfessionalEducation { 'Pro_Edu' }
ProfessionalEducationN { 'Pro_EduN' } ProfessionalEducationN { 'Pro_EduN' }
Enterprise { 'Ent' } Enterprise { 'Ent' }
EnterpriseN { 'EntN' } EnterpriseN { 'EntN'}
EnterpriseS { 'Ent_LTSC' }
IoTEnterpriseS { 'IoT_Ent_LTSC' }
Education { 'Edu' } Education { 'Edu' }
EducationN { 'EduN' } EducationN { 'EduN' }
ProfessionalWorkstation { 'Pro_Wks' } ProfessionalWorkstation { 'Pro_Wks' }