diff --git a/src/System.Management.Automation/engine/PSVersionInfo.cs b/src/System.Management.Automation/engine/PSVersionInfo.cs index be711e0c4..3eca5b296 100644 --- a/src/System.Management.Automation/engine/PSVersionInfo.cs +++ b/src/System.Management.Automation/engine/PSVersionInfo.cs @@ -21,7 +21,7 @@ namespace System.Management.Automation internal const string PSVersionName = "PSVersion"; internal const string SerializationVersionName = "SerializationVersion"; internal const string WSManStackVersionName = "WSManStackVersion"; - private static Hashtable s_psVersionTable = null; + private static PSVersionHashTable s_psVersionTable = null; /// /// A constant to track current PowerShell Version. @@ -54,7 +54,7 @@ namespace System.Management.Automation // Static Constructor. static PSVersionInfo() { - s_psVersionTable = new Hashtable(StringComparer.OrdinalIgnoreCase); + s_psVersionTable = new PSVersionHashTable(StringComparer.OrdinalIgnoreCase); s_psVersionTable[PSVersionInfo.PSVersionName] = s_psV6Version; s_psVersionTable["PSEdition"] = PSEditionValue; @@ -71,7 +71,7 @@ namespace System.Management.Automation #endif } - internal static Hashtable GetPSVersionTable() + internal static PSVersionHashTable GetPSVersionTable() { return s_psVersionTable; } @@ -315,6 +315,43 @@ namespace System.Management.Automation #endregion } + /// + /// Represents an implementation of '$PSVersionTable' variable. + /// The implementation contains ordered 'Keys' and 'GetEnumerator' to get user-friendly output. + /// + public sealed class PSVersionHashTable : Hashtable, IEnumerable + { + internal PSVersionHashTable(IEqualityComparer equalityComparer) : base(equalityComparer) + { + } + + /// + /// Returns ordered collection with Keys of 'PSVersionHashTable' + /// + public override ICollection Keys + { + get + { + Array arr = new string[base.Keys.Count]; + base.Keys.CopyTo(arr, 0); + Array.Sort(arr, StringComparer.OrdinalIgnoreCase); + return arr; + } + } + + /// + /// Returns an enumerator for 'PSVersionHashTable'. + /// The enumeration is ordered (based on ordered version of 'Keys'). + /// + IEnumerator IEnumerable.GetEnumerator() + { + foreach (string key in Keys) + { + yield return new System.Collections.DictionaryEntry(key, this[key]); + } + } + } + /// /// An implementation of semantic versioning (http://semver.org) /// that can be converted to/from . diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Variable.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Variable.Tests.ps1 index 3528643af..31bad4cf0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Variable.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Variable.Tests.ps1 @@ -115,4 +115,14 @@ Describe "Validate special variables" -Tags "CI" { It "Verify `$PSVersionTable.PSEdition" { $PSVersionTable["PSEdition"] | Should Be "Core" } + + It "Verify `$PSVersionTable is ordered" { + $keys1 = $PSVersionTable.Keys + $keys1sorted = $keys1 | Sort-Object + $keys2 = ($PSVersionTable | Format-Table -HideTableHeaders -Property Name | Out-String) -split [System.Environment]::NewLine | Where-Object {$_} + $keys2sorted = $keys2 | Sort-Object + + Compare-Object -ReferenceObject $keys1 -DifferenceObject $keys1sorted -SyncWindow 0 | Should Be $null + Compare-Object -ReferenceObject $keys2 -DifferenceObject $keys2sorted -SyncWindow 0 | Should Be $null + } }