diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs
index 06e8b3f7c6..b624c6e08c 100644
--- a/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs
+++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/ResolvePathCommand.cs
@@ -22,8 +22,6 @@ namespace Microsoft.PowerShell.Commands
///
[Parameter(Position = 0, ParameterSetName = "Path",
Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
- [Parameter(Position = 0, ParameterSetName = "PathWithRelativeBase",
- Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
public string[] Path
{
get
@@ -42,8 +40,6 @@ namespace Microsoft.PowerShell.Commands
///
[Parameter(ParameterSetName = "LiteralPath",
Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)]
- [Parameter(ParameterSetName = "LiteralPathWithRelativeBase",
- Mandatory = true, ValueFromPipeline = false, ValueFromPipelineByPropertyName = true)]
[Alias("PSPath", "LP")]
public string[] LiteralPath
{
@@ -83,8 +79,7 @@ namespace Microsoft.PowerShell.Commands
///
/// Gets or sets the path the resolved relative path should be based off.
///
- [Parameter(Mandatory = true, ParameterSetName = "PathWithRelativeBase")]
- [Parameter(Mandatory = true, ParameterSetName = "LiteralPathWithRelativeBase")]
+ [Parameter]
public string RelativeBasePath
{
get
@@ -94,7 +89,6 @@ namespace Microsoft.PowerShell.Commands
set
{
- _relative = true;
_relativeBasePath = value;
}
}
@@ -121,52 +115,50 @@ namespace Microsoft.PowerShell.Commands
///
protected override void BeginProcessing()
{
- if (_relative)
+ if (!string.IsNullOrEmpty(RelativeBasePath))
{
- if (!string.IsNullOrEmpty(RelativeBasePath))
+ try
{
- try
- {
- _relativeBasePath = SessionState.Internal.Globber.GetProviderPath(RelativeBasePath, CmdletProviderContext, out _, out _relativeDrive);
- }
- catch (ProviderNotFoundException providerNotFound)
- {
- ThrowTerminatingError(
- new ErrorRecord(
- providerNotFound.ErrorRecord,
- providerNotFound));
- }
- catch (DriveNotFoundException driveNotFound)
- {
- ThrowTerminatingError(
- new ErrorRecord(
- driveNotFound.ErrorRecord,
- driveNotFound));
- }
- catch (ProviderInvocationException providerInvocation)
- {
- ThrowTerminatingError(
- new ErrorRecord(
- providerInvocation.ErrorRecord,
- providerInvocation));
- }
- catch (NotSupportedException notSupported)
- {
- ThrowTerminatingError(
- new ErrorRecord(notSupported, "ProviderIsNotNavigationCmdletProvider", ErrorCategory.InvalidArgument, RelativeBasePath));
- }
- catch (InvalidOperationException invalidOperation)
- {
- ThrowTerminatingError(
- new ErrorRecord(invalidOperation, "InvalidHomeLocation", ErrorCategory.InvalidOperation, RelativeBasePath));
- }
-
- return;
+ _relativeBasePath = SessionState.Internal.Globber.GetProviderPath(RelativeBasePath, CmdletProviderContext, out _, out _relativeDrive);
+ }
+ catch (ProviderNotFoundException providerNotFound)
+ {
+ ThrowTerminatingError(
+ new ErrorRecord(
+ providerNotFound.ErrorRecord,
+ providerNotFound));
+ }
+ catch (DriveNotFoundException driveNotFound)
+ {
+ ThrowTerminatingError(
+ new ErrorRecord(
+ driveNotFound.ErrorRecord,
+ driveNotFound));
+ }
+ catch (ProviderInvocationException providerInvocation)
+ {
+ ThrowTerminatingError(
+ new ErrorRecord(
+ providerInvocation.ErrorRecord,
+ providerInvocation));
+ }
+ catch (NotSupportedException notSupported)
+ {
+ ThrowTerminatingError(
+ new ErrorRecord(notSupported, "ProviderIsNotNavigationCmdletProvider", ErrorCategory.InvalidArgument, RelativeBasePath));
+ }
+ catch (InvalidOperationException invalidOperation)
+ {
+ ThrowTerminatingError(
+ new ErrorRecord(invalidOperation, "InvalidHomeLocation", ErrorCategory.InvalidOperation, RelativeBasePath));
}
+ return;
+ }
+ else if (_relative)
+ {
_relativeDrive = SessionState.Path.CurrentLocation.Drive;
_relativeBasePath = SessionState.Path.CurrentLocation.ProviderPath;
- return;
}
}
@@ -181,7 +173,25 @@ namespace Microsoft.PowerShell.Commands
Collection result = null;
try
{
- result = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
+ if (MyInvocation.BoundParameters.ContainsKey("RelativeBasePath"))
+ {
+ // Pushing and popping the location is done because GetResolvedPSPathFromPSPath uses the current path to resolve relative paths.
+ // It's important that we pop the location before writing an object to the pipeline to avoid affecting downstream commands.
+ try
+ {
+ SessionState.Path.PushCurrentLocation(string.Empty);
+ _ = SessionState.Path.SetLocation(_relativeBasePath);
+ result = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
+ }
+ finally
+ {
+ _ = SessionState.Path.PopLocation(string.Empty);
+ }
+ }
+ else
+ {
+ result = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
+ }
if (_relative)
{
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1
index 91a16eb507..efd2441e0a 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Resolve-Path.Tests.ps1
@@ -48,8 +48,70 @@ Describe "Resolve-Path returns proper path" -Tag "CI" {
Pop-Location
}
}
- It 'Resolve-Path should support user specified base paths' {
- $Expected = Join-Path -Path .\ -ChildPath fakeroot
- Resolve-Path -Path $fakeRoot -RelativeBasePath $testRoot | Should -BeExactly $Expected
+ It 'Resolve-Path RelativeBasePath should handle ' -TestCases @(
+ @{
+ Scenario = "Absolute Path, Absolute ReleativeBasePath"
+ Path = $root
+ Basepath = $testRoot
+ Expected = $root, ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
+ CD = $null
+ }
+ @{
+ Scenario = "Relative Path, Absolute ReleativeBasePath"
+ Path = ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
+ Basepath = $testRoot
+ Expected = $root, ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
+ CD = $null
+ }
+ @{
+ Scenario = "Relative Path, Relative ReleativeBasePath"
+ Path = ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
+ Basepath = ".$([System.IO.Path]::DirectorySeparatorChar)"
+ Expected = $root, ".$([System.IO.Path]::DirectorySeparatorChar)fakeroot"
+ CD = $testRoot
+ }
+ @{
+ Scenario = "Invalid Path, Absolute ReleativeBasePath"
+ Path = Join-Path $testRoot ThisPathDoesNotExist
+ Basepath = $root
+ Expected = $null
+ CD = $null
+ }
+ @{
+ Scenario = "Invalid Path, Invalid ReleativeBasePath"
+ Path = Join-Path $testRoot ThisPathDoesNotExist
+ Basepath = Join-Path $testRoot ThisPathDoesNotExist
+ Expected = $null
+ CD = $null
+ }
+ ) -Test {
+ param($Path, $BasePath, $Expected, $CD)
+
+ if ($null -eq $Expected)
+ {
+ {Resolve-Path -Path $Path -RelativeBasePath $BasePath -ErrorAction Stop} | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand"
+ {Resolve-Path -Path $Path -RelativeBasePath $BasePath -ErrorAction Stop -Relative} | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.ResolvePathCommand"
+ }
+ else
+ {
+ try
+ {
+ $OldLocation = if ($null -ne $CD)
+ {
+ $PWD
+ Set-Location $CD
+ }
+
+ (Resolve-Path -Path $Path -RelativeBasePath $BasePath).ProviderPath | Should -BeExactly $Expected[0]
+ Resolve-Path -Path $Path -RelativeBasePath $BasePath -Relative | Should -BeExactly $Expected[1]
+ }
+ finally
+ {
+ if ($null -ne $OldLocation)
+ {
+ Set-Location $OldLocation
+ }
+ }
+ }
}
}