Skip to content

Instantly share code, notes, and snippets.

@dancing-groot
Last active February 15, 2024 20:43
Show Gist options
  • Save dancing-groot/af52d6e2fea46704f67ffa324c58d2c2 to your computer and use it in GitHub Desktop.
Save dancing-groot/af52d6e2fea46704f67ffa324c58d2c2 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Check that the Windows OS version is supported
.DESCRIPTION
Build a list based on the Windows OS, Edition and Build Number with a pre-defined 'end of life' date
to assess if the OS on this machine is still supported
.LINK
https://gist.github.com/dancing-groot/af52d6e2fea46704f67ffa324c58d2c2
.NOTES
Version: 2024.02.15
Author: @dancing-groot
References:
https://en.wikipedia.org/wiki/Windows_10_version_history#Channels
https://learn.microsoft.com/en-us/lifecycle/products/windows-10-enterprise-and-education
https://en.wikipedia.org/wiki/Windows_11_version_history#Channels
https://learn.microsoft.com/en-us/lifecycle/products/windows-11-enterprise-and-education
https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions#Server_versions
#>
[cmdletBinding()]
param()
#region FUNCTIONS
function Get-WindowsOSList
{
[CmdletBinding()]
param()
$windowsOSList = @()
# Put in this format so it's easier to add new entries without relying on an external file
$rawData = @(
("Windows 10 Education", "1507", "10240", "2017.05.09"),
("Windows 10 Enterprise", "1507", "10240", "2017.05.09"),
("Windows 10 LTSC", "1507", "10240", "2025.10.14"),
("Windows 10 Pro", "1507", "10240", "2017.05.09"),
("Windows 10 Education", "1511", "10586", "2017.10.10"),
("Windows 10 Enterprise", "1511", "10586", "2017.10.10"),
("Windows 10 Pro", "1511", "10586", "2017.10.10"),
("Windows 10 Education", "1607", "14393", "2019.04.09"),
("Windows 10 Enterprise", "1607", "14393", "2019.04.09"),
("Windows 10 LTSC", "1607", "14393", "2026.10.13"),
("Windows 10 Pro", "1607", "14393", "2018.04.10"),
("Windows 10 Education", "1703", "15063", "2019.10.08"),
("Windows 10 Enterprise", "1703", "15063", "2019.10.08"),
("Windows 10 Pro", "1703", "15063", "2018.10.09"),
("Windows 10 Education", "1709", "16299", "2020.10.13"),
("Windows 10 Enterprise", "1709", "16299", "2020.10.13"),
("Windows 10 Pro", "1709", "16299", "2019.04.09"),
("Windows 10 Education", "1803", "17134", "2021.05.11"),
("Windows 10 Enterprise", "1803", "17134", "2021.05.11"),
("Windows 10 Pro", "1803", "17134", "2019.11.12"),
("Windows 10 Education", "1809", "17763", "2021.05.11"),
("Windows 10 Enterprise", "1809", "17763", "2021.05.11"),
("Windows 10 LTSC", "1809", "17763", "2029.01.09"),
("Windows 10 Pro", "1809", "17763", "2020.11.10"),
("Windows 10 Education", "1903", "18362", "2020.12.08"),
("Windows 10 Enterprise", "1903", "18362", "2020.12.08"),
("Windows 10 Pro", "1903", "18362", "2020.12.08"),
("Windows 10 Education", "1909", "18363", "2022.05.10"),
("Windows 10 Enterprise", "1909", "18363", "2022.05.10"),
("Windows 10 Pro", "1909", "18363", "2021.05.11"),
("Windows 10 Education", "2004", "19041", "2021.12.14"),
("Windows 10 Enterprise", "2004", "19041", "2021.12.14"),
("Windows 10 Pro", "2004", "19041", "2021.12.14"),
("Windows 10 Education", "20H2", "19042", "2023.05.09"),
("Windows 10 Enterprise", "20H2", "19042", "2023.05.09"),
("Windows 10 Pro", "20H2", "19042", "2022.05.10"),
("Windows 10 Education", "21H1", "19043", "2022.12.13"),
("Windows 10 Enterprise", "21H1", "19043", "2022.12.13"),
("Windows 10 Pro", "21H1", "19043", "2022.12.13"),
("Windows 10 Education", "21H2", "19044", "2024.06.11"),
("Windows 10 Enterprise", "21H2", "19044", "2024.06.11"),
("Windows 10 LTSC", "21H2", "19044", "2027.01.12"),
("Windows 10 Pro", "21H2", "19044", "2023.06.13"),
("Windows 10 Education", "22H2", "19045", "2025.10.14"),
("Windows 10 Enterprise", "22H2", "19045", "2025.10.14"),
("Windows 10 Pro", "22H2", "19045", "2025.10.14"),
("Windows 11 Education", "21H2", "22000", "2024.10.08"),
("Windows 11 Enterprise", "21H2", "22000", "2024.10.08"),
("Windows 11 Pro", "21H2", "22000", "2023.10.10"),
("Windows 11 Education", "22H2", "22621", "2025.10.14"),
("Windows 11 Enterprise", "22H2", "22621", "2025.10.14"),
("Windows 11 Pro", "22H2", "22621", "2024.10.08"),
("Windows 11 Education", "23H2", "22631", "2026.11.10"),
("Windows 11 Enterprise", "23H2", "22631", "2026.11.10"),
("Windows 11 Pro", "23H2", "22631", "2025.11.25"),
("Windows Server", "2008 R2", "7601", "2020.01.14"),
("Windows Server", "2012 R2", "9600", "2020.01.14"),
("Windows Server", "2016", "14393", "2027.01.12"),
("Windows Server", "2019", "17763", "2029.01.09"),
("Windows Server", "2022", "20348", "2031.10.14")
)
$rawData | ForEach-Object { $windowsOSList += [PSCustomObject]@{Type = $_[0]; Version = $_[1]; Build = $_[2]; EOL = $_[3] } }
return $windowsOSList
} # Get-WindowsOSList
function Format-Date
{
[CmdletBinding()]
param(
[ValidatePattern("\d{4}\.\d{1,2}\.\d{1,2}")][string]$Date
)
return [DateTime]$Date
} # Format-Date
function Test-OS
{
[CmdletBinding(DefaultParameterSetName = "Supported")]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'Supported')][switch]$Supported,
[Parameter(Mandatory = $true, ParameterSetName = 'DaysLeft')][switch]$DaysLeft,
[Parameter(Mandatory = $true, ParameterSetName = 'Detailed')][switch]$Detailed
)
try
{
$windowsInfo = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object Caption, BuildNumber, @{Name = "Type"; Expression = "." }
}
catch
{
$windowsInfo = Get-WmiObject -Class Win32_OperatingSystem | Select-Object Caption, BuildNumber, @{Name = "Type"; Expression = "." }
}
switch -Wildcard ($windowsInfo.Caption)
{
"*Windows 10*"
{
switch -Wildcard ($windowsInfo.Caption)
{
"*LTSC" { $WindowsInfo.Type = "Windows 10 LTSC"; break }
"*Pro*" { $WindowsInfo.Type = "Windows 10 Pro"; break }
"*Education" { $WindowsInfo.Type = "Windows 10 Education"; break }
"*Enterprise" { $WindowsInfo.Type = "Windows 10 Enterprise"; break }
}
}
"*Windows 11*" { $WindowsInfo.Type = "Windows 11"; break }
"*Windows Server*" { $WindowsInfo.Type = "Windows Server"; break }
}
$deviceInfo = $Script:Support | Where-Object { $_.Type -eq $windowsInfo.Type -and $_.Build -eq $windowsInfo.BuildNumber }
if ($null -eq $deviceInfo) { $deviceInfo = @{Type = "NOT DETECTED OR ANCIENT"; Version = "0"; EOL = "0001.01.01"}}
switch ($true)
{
$Supported
{
if ((Format-Date -Date $deviceInfo.EOL) -lt (Get-Date)) { return $false } else { return $true }
}
$DaysLeft
{
return ((Format-Date -Date $deviceInfo.EOL) - (Get-Date)).Days
}
$Detailed
{
return $deviceInfo | Select-Object Type, Version, @{ Name = "End Of Life"; Expression = { (Format-Date -Date $_.EOL).ToString('dd MMMM yyyy') } }, @{ Name = "Days Remaining"; Expression = { ((Format-Date -Date $_.EOL) - (Get-Date)).Days } }
}
}
} # Test-OS
#endregion FUNCTIONS
#region DECLARATION
$Support = Get-WindowsOSList
#endregion DECLARATION
#region MAIN
Test-OS -Supported
Test-OS -DaysLeft
Test-OS -Detailed
#endregion MAIN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment