diff --git a/src/System.Management.Automation/namespaces/FileSystemProvider.cs b/src/System.Management.Automation/namespaces/FileSystemProvider.cs
index b62454ac5..733b12eb0 100644
--- a/src/System.Management.Automation/namespaces/FileSystemProvider.cs
+++ b/src/System.Management.Automation/namespaces/FileSystemProvider.cs
@@ -98,7 +98,46 @@ namespace Microsoft.PowerShell.Commands
///
private static string NormalizePath(string path)
{
- return path.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator);
+ return GetCorrectCasedPath(path.Replace(StringLiterals.AlternatePathSeparator, StringLiterals.DefaultPathSeparator));
+ }
+
+ ///
+ /// Get the correct casing for a path. This method assumes it's being called by NormalizePath()
+ /// so that the path is already normalized.
+ ///
+ ///
+ /// The path to retrieve.
+ ///
+ ///
+ /// The path with accurate casing if item exists, otherwise it returns path that was passed in.
+ ///
+ private static string GetCorrectCasedPath(string path)
+ {
+ string exactPath = string.Empty;
+ if (File.Exists(path) || Directory.Exists(path))
+ {
+ foreach (string item in path.Split(StringLiterals.DefaultPathSeparator))
+ {
+ if (string.IsNullOrEmpty(exactPath))
+ {
+ exactPath = item + StringLiterals.DefaultPathSeparator;
+ }
+ else if (string.IsNullOrEmpty(item))
+ {
+ // This handles the trailing slash case
+ continue;
+ }
+ else
+ {
+ exactPath = Directory.GetFileSystemEntries(exactPath, item).First();
+ }
+ }
+ return exactPath;
+ }
+ else
+ {
+ return path;
+ }
}
///
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1
index 5824419f3..c401003c2 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Location.Tests.ps1
@@ -70,6 +70,12 @@ Describe "Set-Location" -Tags "CI" {
Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand"
}
+ It "Should use actual casing of folder on case-insensitive filesystem" -Skip:($IsLinux) {
+ $testPath = New-Item -ItemType Directory -Path testdrive:/teST
+ Set-Location $testPath.FullName.ToUpper()
+ $(Get-Location).Path | Should -BeExactly $testPath.FullName
+ }
+
Context 'Set-Location with no arguments' {
It 'Should go to $env:HOME when Set-Location run with no arguments from FileSystem provider' {