I posted before about using repadmin to get the Active Directory schema version and the Exchange schema version, but it is messier than I would like.
Here I use the native AD Commandlet Get-ADObject to get the AD & Exchange schema versions from Active Directory. I also use a single hashtable to track both AD & Exchange schema versions enabling me to only have to perform a single type of hashtable lookup. I also included the hashtable add method for the most recent additions, so adding items later are simple as copy-paste.
This is the first time I used a hashtable and found it very useful for these types of lookups. The post linked here demonstrates the use of a hashtable for performing schema version lookups. Since Active Directory schema versions are double digit and Exchange schema version numbers are 5 digits, there are no collisions. Thus I used a single hashtable. The command that gets the schema version is repadmin, though I could have used Get-ADObject.
Here’s a method to get the AD & Exchange Schema Versions using a hashtable:
Import-module ActiveDirectory ############################################# # Get Active Directory Forest & Domain Info # ############################################# # Get Forest Info write-output "Gathering Active Directory Forest Information... `r " Write-Verbose "Running Get-ADForest Powershell command `r" $ADForestInfo = Get-ADForest $ADForestApplicationPartitions = $ADForestInfo.ApplicationPartitions $ADForestCrossForestReferences = $ADForestInfo.CrossForestReferences $ADForestDomainNamingMaster = $ADForestInfo.DomainNamingMaster $ADForestDomains = $ADForestInfo.Domains $ADForestForestMode = $ADForestInfo.ForestMode $ADForestGlobalCatalogs = $ADForestInfo.GlobalCatalogs $ADForestName = $ADForestInfo.Name $ADForestPartitionsContainer = $ADForestInfo.PartitionsContainer $ADForestRootDomain = $ADForestInfo.RootDomain $ADForestSchemaMaster = $ADForestInfo.SchemaMaster $ADForestSites = $ADForestInfo.Sites $ADForestSPNSuffixes = $ADForestInfo.SPNSuffixes $ADForestUPNSuffixes = $ADForestInfo.UPNSuffixes # Get Domain Info write-output "Gathering Active Directory Domain Information... `r" Write-Verbose "Performing Get-ADDomain powershell command `r" $ADDomainInfo = Get-ADDomain $ADDomainAllowedDNSSuffixes = $ADDomainInfo.ADDomainAllowedDNSSuffixes $ADDomainChildDomains = $ADDomainInfo.ChildDomains $ADDomainComputersContainer = $ADDomainInfo.ComputersContainer $ADDomainDeletedObjectsContainer = $ADDomainInfo.DeletedObjectsContainer $ADDomainDistinguishedName = $ADDomainInfo.DistinguishedName $ADDomainDNSRoot = $ADDomainInfo.DNSRoot $ADDomainDomainControllersContainer = $ADDomainInfo.DomainControllersContainer $ADDomainDomainMode = $ADDomainInfo.DomainMode $ADDomainDomainSID = $ADDomainInfo.DomainSID $ADDomainForeignSecurityPrincipalsContainer = $ADDomainInfo.ForeignSecurityPrincipalsContainer $ADDomainForest = $ADDomainInfo.Forest $ADDomainInfrastructureMaster = $ADDomainInfo.InfrastructureMaster $ADDomainLastLogonReplicationInterval = $ADDomainInfo.LastLogonReplicationInterval $ADDomainLinkedGroupPolicyObjects = $ADDomainInfo.LinkedGroupPolicyObjects $ADDomainLostAndFoundContainer = $ADDomainInfo.LostAndFoundContainer $ADDomainName = $ADDomainInfo.Name $ADDomainNetBIOSName = $ADDomainInfo.NetBIOSName $ADDomainObjectClass = $ADDomainInfo.ObjectClass $ADDomainObjectGUID = $ADDomainInfo.ObjectGUID $ADDomainParentDomain = $ADDomainInfo.ParentDomain $ADDomainPDCEmulator = $ADDomainInfo.PDCEmulator $ADDomainQuotasContainer = $ADDomainInfo.QuotasContainer $ADDomainReadOnlyReplicaDirectoryServers = $ADDomainInfo.ReadOnlyReplicaDirectoryServers $ADDomainReplicaDirectoryServers = $ADDomainInfo.ReplicaDirectoryServers $ADDomainRIDMaster = $ADDomainInfo.RIDMaster $ADDomainSubordinateReferences = $ADDomainInfo.SubordinateReferences $ADDomainSystemsContainer = $ADDomainInfo.SystemsContainer $ADDomainUsersContainer = $ADDomainInfo.UsersContainer $DomainDNS = $ADDomainDNSRoot ################################### # Create Schema Version Hashtable # ################################### Write-Verbose "Create Schema Version hashtable `r " $SchemaVersionTable = @{ "13" = "Windows 2000 Forest Functional Mode"; "30" = "Windows 2003 Forest Functional Mode"; "31" = "Windows 2003 R2 Forest Functional Mode" ;` "44" = "Windows 2008 Forest Functional Mode" ; "4397" = "Exchange 2000 RTM Schema" ; "4406" = "Exchange 2000 SP3 Schema" ;` "6870" = "Exchange 2003 RTM Schema" ; "6936" = "Exchange 2003 SP3 Schema" ; "10628" = "Exchange 2007 RTM Schema" ;` "11116" = "Exchange 2007 RTM Schema" ; "14622" = "Exchange 2007 SP3 & Exchange 2010 RTM Schema" } # Use Add method to add updates to Schema Version Hashtable (SVH) $SchemaVersionTable.Add("47", "Windows 2008 R2 Forest Functional Mode") $SchemaVersionTable.Add("14726", "Exchange 2010 SP1 Schema") $SchemaVersionTable.Add("51", "Windows Server 8 BETA Forest Functional Mode") Write-Output " `r "################################ # Get AD Schema Version Number # 20111030-14 ################################ write-Verbose "Checking Schema version on the PDC Emulator ($ADDomainPDCEmulator) `r " $ADSchemaInfo = Get-ADObject "cn=schema,cn=configuration,$ADDomainDistinguishedName" -properties objectversion $ADSchemaVersion = $ADSchemaInfo.objectversion $ADSchemaVersionName = $SchemaVersionTable.Get_Item("$ADSchemaVersion") Write-Verbose "The current AD Schema Version is $ADSchemaVersion which is $ADSchemaVersionName `r " Write-Verbose " `r "###################################### # Get Exchange Schema Version Number # 20111030-14 ###################################### write-Verbose "Checking Exchange Schema version on the PDC Emulator ($ADDomainPDCEmulator) `r " $ExchangeSchemaInfo = Get-ADObject "cn=ms-exch-schema-version-pt,cn=Schema,cn=Configuration,$ADDomainDistinguishedName" -properties rangeupper $ExchangeSchemaVersion = $ExchangeSchemaInfo.rangeupper $ExchangeSchemaVersionName = $SchemaVersionTable.Get_Item("$ExchangeSchemaVersion") Write-Verbose "The current Exchange Schema Version is $ExchangeSchemaVersion which is $ExchangeSchemaVersionName `r " Write-Verbose " `r "