Public/Schema/Get-ADSchemaVersion.ps1
|
<#
.SYNOPSIS Return the Active Directory schema version of the forest, and the Windows Server release it corresponds to. .DESCRIPTION Reads the 'objectVersion' attribute of the schema partition and maps it to the Windows Server release that introduced it. The version tells you the highest release whose schema extensions have been applied to the forest. It says nothing about the operating system of the domain controllers, nor about the functional levels. A forest can run on Windows Server 2025 domain controllers with a schema still at 88, if adprep was never run for 2025. Reference: https://learn.microsoft.com/troubleshoot/windows-server/identity/find-current-schema-version Both the number and its meaning are returned. An unknown number is reported as such and kept in the output, rather than collapsed into the string 'Unknown', so a schema newer than this table can still be identified. .PARAMETER Server Domain controller or domain to query. Defaults to the one selected by the ActiveDirectory module. .EXAMPLE Get-ADSchemaVersion Returns the schema version of the current forest. .EXAMPLE (Get-ADSchemaVersion).ObjectVersion -ge 88 Tests whether the schema has at least the Windows Server 2019 extensions, for instance before deploying something that depends on them. .OUTPUTS System.Management.Automation.PSCustomObject with ObjectVersion, WindowsServerRelease, IsKnown and SchemaNamingContext. .NOTES Version : 2.0 - August 2026. Migrated from the ActiveDirectory-Toolbox repository. Author : Bastien Perez - ITPro-Tips (https://itpro-tips.com) .LINK https://itpro-tips.com #> function Get-ADSchemaVersion { [CmdletBinding()] [OutputType([PSCustomObject])] param ( [string]$Server ) $ErrorActionPreference = 'Stop' # Common parameters forwarded to every ActiveDirectory cmdlet call $adParameters = @{ ErrorAction = 'Stop' } if ($PSBoundParameters.ContainsKey('Server')) { $adParameters.Add('Server', $Server) } $adSchemaVersions = @{ 13 = 'Windows 2000 Server' 30 = 'Windows Server 2003 RTM, Service Pack 1, Service Pack 2' 31 = 'Windows Server 2003 R2' 44 = 'Windows Server 2008 RTM' 47 = 'Windows Server 2008 R2' 56 = 'Windows Server 2012' 69 = 'Windows Server 2012 R2' 87 = 'Windows Server 2016' 88 = 'Windows Server 2019 or 2022' 90 = 'Windows Server 2025' } try { $schemaNamingContext = (Get-ADRootDSE @adParameters).schemaNamingContext $schemaObject = Get-ADObject -Identity $schemaNamingContext -Properties 'objectVersion' @adParameters } catch { Write-Error "Unable to read the schema partition: $($_.Exception.Message)" return } $objectVersion = $schemaObject.objectVersion if ($adSchemaVersions.ContainsKey($objectVersion)) { $windowsServerRelease = $adSchemaVersions[$objectVersion] $isKnown = $true } else { # A schema newer than this table is not an error, it just means the table needs an entry $windowsServerRelease = 'Unknown, this version is not in the reference table' $isKnown = $false Write-Warning "Schema objectVersion $objectVersion is not in the reference table" } return [PSCustomObject][ordered]@{ ObjectVersion = $objectVersion WindowsServerRelease = $windowsServerRelease IsKnown = $isKnown SchemaNamingContext = $schemaNamingContext } } |