You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Passing a provider-name-prefixed path to Set-Location makes $PWD retain the prefix #10522
Run the following on Windows (works analogously on Unix):
Set-Location Microsoft.PowerShell.Core\FileSystem::C:\Windows
"$PWD"| Should -Be C:\Windows
Note: A real-life scenario in which this could occur is if you pipe the output from a New-Item -Type Directory call to Set-Location, e.g.:
New-Item-Type Directory $HOME-Force |Set-Location
Expected behavior
The test should pass.
Actual behavior
The test fails:
Expected strings to be the same, but they were different.
Expected length: 10
Actual length: 48
Strings differ at index 0.
Expected: 'C:\Windows'
But was: 'Microsoft....'
That is, $PWD stringified (via .Path) to 'Microsoft.PowerShell.Core\FileSystem::C:\Windows', not the expected C:\Windows, as also reflected in the prompt string afterwards (via $executionContext.SessionState.Path.CurrentLocation).
While $PWD.ProviderPath does reflect the unprefixed (but always native) fileysystem path, relying on "$PWD" or $PWD.Path to do that too is very common.
They return [PathInfo] and it is PathInfo.ToString() behavior.
Changing this would be a breaking change.
Also it is not clear why path without prefix is expected behavior.
Also it is not clear why path without prefix is expected behavior.
To quote from the OP, emphasis added:
While $PWD.ProviderPath does reflect the unprefixed (but always native) fileysystem path, relying on "$PWD" or $PWD.Path to do that [show the unprefixed full path] too is very common.
I don't think anyone expects - nor should they - that the way they specify the location determines how that location is reported.
E.g, if I do Set-Location ./tmp in order to change to, say, C:\foo\tmp, I expect both the prompt string and Get-Location to reflect C:\foo\tmp, not ./tmp.
The same applies to passing a provider-prefixed path: it is just a way to identify the target item on input, which is unrelated to the presentation on output, which should be standardized.
This is a breaking change in the same way that any bug fix is a breaking change: it corrects unexpected behavior.
Reacted by Rain Sallow (/u/ta11ow) and Flavien MICHALECZEK
I don't think anyone expects - nor should they - that the way they specify the location determines how that location is reported.
If I want to work with native filesystem paths I use native filesystem paths. If I want provider prefixes I expect that they will be preserved, including completions.
In this case you're not working with one path form of the other.
Instead, you're using acceptable variations in the syntactic form of an argument to target a known item.
To put it in concrete terms:
Set-Location ./tmp # from C:\foo
Set-Location C:\foo\tmp
Set-Location Microsoft.PowerShell.Core\FileSystem::C:\foo\tmp
These are 3 different ways to target the same location - the variations in how you identified that location to Set-Location should have no impact whatsoever on the cmdlet's output / behavior (or on related cmdlets, such as Get-Location).
Best to extend Resolve-Path with -SimplifyProvider and -SimplifyHome and use them in default prompt. That way there is no breaking change and you opt into the replacement in a script if you want.
New-Item (mkdir) and Get-Item / Get-ChildItem add a PSPath property to System.IO.DirectoryInfo objects (it isn't added via type data so the .GetDirectories() method yields objects without it)
When object with a PSPath property is piped to set-location, that is used in preference to converting the object to string (ToString() gives the fullname property)
Therefore: if $d is a directory obtained by a cmdlet cd $d converts $d to a string and uses the full name as a path, but $d | cd uses the PSPath as a literal path.
Dominik Kowalski (@dkaszews) Changing the prompt to hide that his happened is NOT a good idea
Try this (on Windows)
Get-Item $HOME | Set-Location
Set-location \
On linux / or \ is considered to be a drive so it doesn't have the same problem but on windows \ or anything specified relative to \ fails.
There are cases where Set-Location cannot reliably and uniquely choose a drive (e.g. should changing into the temp directory, go to Temp: or the path within the native file file system. Or should HKEY_CLASSES_ROOT go to HKEY_LOCAL_MACHINE\SOFTWARE\Classes)
Note that for the registry get-item hklm: | cd allows cd '..\HKEY_Classes_root' which isn't possible with cd HKLM: (but again breaks cd \)
So I think
If the user / script author takes the trouble to use a PSPath they want to the location to be set to a PS path. And in the case of something like Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT there is no default drive to use,
If the user passes a file system object via the pipeline selecting the PSPath is a surprise. Making Fullname an alias for path would solve this problem. Where changing an explicit PSPath is making a dangerous assumption, in the case of Set-Location assuming the user wants to use the PSPath and not the fullName for the filesystem is making a wrong one.
Dominik Kowalski (@dkaszews) Changing the prompt to hide that his happened is NOT a good idea
Try this (on Windows)
It is not "hide". It is fundamentally follow PowerShell provider conceptions. We should use these fundamental conceptions right.
Set-location \ is not a prove. It demonstrate a bug we should fix.
we might need to accept an amicable disagreement :-)
Set-location \does demonstrate that current location is set to different places, one impacted by a bug, one not
And (on windows at least) a path starting \ means "from the root of the current drive" but PowerShell lets us set the current location to somewhere with no drive like Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT or Microsoft.PowerShell.Core\FileSystem::\MachineName\c$\Windows` what does "" or "root of the drive" mean then ?
Your comment above
If I want to work with native filesystem paths I use native filesystem paths. If I want provider prefixes I expect that they will be preserved, including completions.
Is what I think, although you might have changed your mind since then :-) Having the location using the provider and the prompt showing path as the provider sees it seems like masking a problem to me and there are places where it doesn't give the right answer - if I connect a PS Drive to a network share...
new-psdrive S -PSProvider FileSystem -Root "\\MachineName\c$"
S:
get-item windows | cd
I end up connected to Microsoft.PowerShell.Core\FileSystem::\\MachineName\c$\Windows
Showing me the provider path \\MachineName\c$\Windows as a prompt instead of S: hasn't fixed the problem. Like the registry I can cd past the root of drive S: to a different share or even a different server but CD \ fails. (any fix for cd \ needs to cope with UNC paths).
And if I do get-item temp:\ | cd it puts me in the Microsoft.PowerShell.Core\FileSystem::C:\Users\ME\AppData\Local\Temp>
Showing me a prompt of C:\Users\ME\AppData\Local\Temp is both correct and unexpected - I expect to be on the temp: drive But if there is come kind of lookup which translates that to TEMP: (and the UNC to S:) then if I do get-item $env:temp | cdthat will be wrong getting temp: instead of c:\users...
In all these examples it is the way set-location prefers PSPath to the fullname property which is the problem
Given that the current binding of provider items via the pipeline happens by the .PSPath property value only, the drive information is already lost by the time Set-Location sees the parameter value - and guessing a drive indeed sounds like a bad idea.
Thus, the solution is to bind such items as objects, where a drive-letter-based path can be reconstructed via the .PSDrive property. I think such a change would bring sanity to Set-Location's pipeline behavior without breaking anything.
Here's a proof of concept, Set-LocationProperly, which wraps Set-Location with the desired behavior.
From what I can tell, it should work with all providers and PowerShell-only drives, so that all of the following commands should work as intended; if no drive information is present, the behavior is as before, but with file-system items that would then only happen with raw UNC paths:
Get-Item / | Set-LocationPropertly
$PWD | Set-LocationProperly
Get-Item HKCU:\Console | Set-LocationProperly
functionSet-LocationProperly {
[CmdletBinding(DefaultParameterSetName='Path',PositionalBinding=$false)]
param(
# Note: I think it would make more sense to interpret *strings* from the pipline as *literal* paths, in which# case ValueFromPipeline could be removed, but that would at least technically be a breaking change.
[Parameter(ParameterSetName='Path',Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)]
[string] $Path,
[Parameter(ParameterSetName='LiteralPath',Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=0)]
[Alias('lp')]
[object] $LiteralPath,
[switch] $PassThru,
[Parameter(ParameterSetName='Stack')]
[string] $StackName
)
Set-StrictMode-Version 1if ($pscmdlet.ParameterSetName-eq'Stack') {
Set-Location-StackName $StackName-PassThru:$PassThru
}
elseif ($pscmdlet.ParameterSetName-eq'Path') {
Set-Location-Path $Path-PassThru:$PassThru
}
else {
$resolvedPath=if ($LiteralPath.PSDrive-and ($IsWindows-or$LiteralPath.PSDrive.Name-ne'/')) {
$providerPath=$LiteralPath.PSPath-replace'^.+?::'$driveRoot= (Get-PSDrive$LiteralPath.PSDrive.Name).Root
Join-Path ($LiteralPath.PSDrive.Name+':') $providerPath.Remove(0,$driveRoot.Length)
}
elseif ($LiteralPath-is [System.IO.DirectoryInfo]) {
$LiteralPath.FullName
}
elseif ($LiteralPath.PSPath) {
$LiteralPath.PSPath
}
else {
# Note: Despite ValueFromPipelineByPropertyName, the objects with such properties bind *as a whole*,# due to also being ValueFromPipeline as [object]s, so the properties must be tested for explicitly.if ($LiteralPath.LiteralPath) {
$LiteralPath.LiteralPath
}
elseif ($LiteralPath.lp) {
$LiteralPath.lp
}
else { # Otherwise: simply stringify the input object.# Note: This also covers [System.Management.Automation.PathInfo], such as reported by $PWD / Get-Location,# which stringifiy as their .Path property, expressed in terms of PowerShell drives."$LiteralPath"
}
}
Set-Location-PassThru:$PassThru-LiteralPath $resolvedPath
}
}
Note:
The above quietly ignores multiple input objects and only acts on the last one. It wouldn't be hard to implement a warning or emulate the current Set-Location behavior:
By contrast, Set-Location somewhat pointlessly changes the directory for each input object, which means that the last (existing) input path "wins", in effect, with preceding nonexisting ones causing statement-terminating errors.
This behavior has some justification: conceivably, you could call Set-Location -PassThru in a pipeline in order to perform subsequent operations in the same pipeline in a distinct directory each.
Michael Klement (@mklement0) - good points too.
I see 2 issues with set-Location first what is intended when a provider path is provided, and where there are behaviour differences are they bugs or intentional and second the pipe behaviour does seem intended which can be fixed by making FullName an alias for Path, (and dodging the other issues).
Quick terminology clarification: provider path (perhaps better: provider-native path) usually refers to a path that is native to a given provider, and which PowerShell can't be expected to understand without a provider prefix; e.g., HKEY_CURRENT_USER\Console vs. registry::HKEY_CURRENT_USER\Console - I'l call the latter a provider-qualified path.
In the absence of a provider prefix and a drive spec at the start of a path, PowerShell interprets a path as relative to the current location of whatever provider underlies the current location, so that while a file-system location (directory) is the current location (as is typical), Get-ChildItem HKEY_CURRENT_USER\Console (presumably in vain) looks for an file or directory named Console in a HKEY_CURRENT_USER subdirectory, for instance.
Ambiguity is avoided in one of two ways:
Prefix a provider-native path with the name of the provider to make it a provider-qualified path, e.g. registry::HKEY_CURRENT_USER\Console
Use a drive-based path, e.g, HKCU:\Console
Note that UNC file paths (e.g, \\localhost\c$) are an edge case: they aren't drive-based, so if a provider other than the file-system provider underlies the current location, they are not recognized as file-system paths (try Set-Location function:; Get-Item \\localhost\c$). As an aside: Curiously, on Unix only, / and \are recognized as file-system paths even in a location such as function: - even though there is no drive spec involved and / and \ should refer to the root location of the current drive (technically, /is a drive on Unix, but in the absence of a : following it, it can't be distinguished from referring to the current location's root); but perhaps this inconsistency is for the better in practice.
With all this in mind:
making FullName an alias for Path
Note that this would limit the solution to (a) file-system paths and (b) wouldn't respect PowerShell-only drives such as Get-Item SomeCustomDrive:foo.txt | Set-Location
What the function above does is the following, which, from what I can tell, provides consistent behavior in line with user expectations:
If an object with provider ETS properties (.PSPath, ...) is passed:
If, in addition to .PSPath, it has a .PSDrive property: translate the provider-qualified path (provider prefix + provider-native path) back into a drive-based path, as the presence of .PSDrive unambiguously implies that a drive-based path was used on input.
Otherwise, if there's no drive information: Use the .PSPath property, as currently, resulting in a full, provider-qualified path.
In the context of file-system paths, this will then only happen with UNC paths.
While the resulting $PWD.Path value (and therefore the prompt string) will still be somewhat scary-looking (e.g. Microsoft.PowerShell.Core\FileSystem::\\localhost\c$), there is justification for this behavior, given that a UNC path is ambiguous, as explained above.
That said - and this is a separate issue - in practice it would make more sense to unambiguously treat native UNC paths (those without a provider prefix) as file-system paths, just like a /-prefixed path is already unambiguously considered a file-system path on Unix.
In the context of other providers - those that optionally allow addressing an item without a drive spec - you'd only get the provider-prefixed path if you explicitly avoided a drive spec, such as Get-Item registry::HKEY_CURRENT_USER\Console | Set-Location (whereas Get-Item HKCU:\Console | Set-Location would preserve the drive).
All other cases would result in the same behavior as currently.
Steve Lee (@SteveL-MSFT), the larger issue here is that Set-Location should accept any[System.IO.DirectoryInfo] instance piped to it and honor its PS drive information, if present, not just if emitted by New-Item.
Thus, the better solution is to fix Set-Location, as previously described, which requires modifying it to accept object input.
The irony here is that providing a [System.IO.DirectoryInfo]without provider instance properties currently actually works as expected, albeit by definition only ever with file-system-native paths, and only with file paths that don't contain [ (that string pipeline input binds to -Path instead of -LiteralPath is unfortunate, but that's a separate problem):
# OK, due to effectively stripping the PS* provider properties # and the *stringified* [System.IO.DirectoryInfo] instance - which is its .FullName property - # binding to Set-Location's -Path propertyGet-Item$HOME|% { [System.IO.DirectoryInfo] $_.FullName } |Set-Location
By contrast, Get-Item $HOME | Set-Location, as reported in #9293, causes the same problem described in the initial post.
The @PowerShell/wg-powershell-cmdlets discussed this and since this is not a change in behavior and has existed for a long time, we recommend Won't Fix
Activity
iSazonov commentedon Sep 13, 2019
The same for Get-Location:
They return [PathInfo] and it is PathInfo.ToString() behavior.
Changing this would be a breaking change.
Also it is not clear why path without prefix is expected behavior.
mklement0 commentedon Sep 13, 2019
To quote from the OP, emphasis added:
I don't think anyone expects - nor should they - that the way they specify the location determines how that location is reported.
E.g, if I do
Set-Location ./tmpin order to change to, say,C:\foo\tmp, I expect both the prompt string andGet-Locationto reflectC:\foo\tmp, not./tmp.The same applies to passing a provider-prefixed path: it is just a way to identify the target item on input, which is unrelated to the presentation on output, which should be standardized.
This is a breaking change in the same way that any bug fix is a breaking change: it corrects unexpected behavior.
iSazonov commentedon Sep 13, 2019
If I want to work with native filesystem paths I use native filesystem paths. If I want provider prefixes I expect that they will be preserved, including completions.
mklement0 commentedon Sep 13, 2019
Ilya (@iSazonov) :
In this case you're not working with one path form of the other.
Instead, you're using acceptable variations in the syntactic form of an argument to target a known item.
To put it in concrete terms:
These are 3 different ways to target the same location - the variations in how you identified that location to
Set-Locationshould have no impact whatsoever on the cmdlet's output / behavior (or on related cmdlets, such asGet-Location).dkaszews commentedon Aug 24, 2022
Posh-Git seems to work, I checked that updating the prompt to the following is sufficient:
As mentioned in #17949 , updating the prompt is the best way to go as most people just care about the visual "bug" and it is not a breaking change.
dkaszews commentedon Aug 24, 2022
Best to extend
Resolve-Pathwith-SimplifyProviderand-SimplifyHomeand use them in default prompt. That way there is no breaking change and you opt into the replacement in a script if you want.jhoneill commentedon Aug 24, 2022
This has come up again in 17949
There is plainly a gap between what people EXPECT when working with a file system, and what has been implemented
#17949 was basically
New-Item(mkdir) andGet-Item/Get-ChildItemadd aPSPathproperty toSystem.IO.DirectoryInfoobjects (it isn't added via type data so the.GetDirectories()method yields objects without it)PSPathproperty is piped toset-location, that is used in preference to converting the object to string (ToString()gives thefullnameproperty)$dis a directory obtained by a cmdletcd $dconverts$dto a string and uses the full name as a path, but$d | cduses thePSPathas a literal path.Dominik Kowalski (@dkaszews) Changing the prompt to hide that his happened is NOT a good idea
Try this (on Windows)
On linux / or \ is considered to be a drive so it doesn't have the same problem but on windows \ or anything specified relative to \ fails.
BUT you could use the prompt to fix it.
There are cases where
Set-Locationcannot reliably and uniquely choose a drive (e.g. should changing into the temp directory, go to Temp: or the path within the native file file system. Or shouldHKEY_CLASSES_ROOTgo toHKEY_LOCAL_MACHINE\SOFTWARE\Classes)Note that for the registry
get-item hklm: | cdallows cd '..\HKEY_Classes_root' which isn't possible withcd HKLM:(but again breakscd \)So I think
Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOTthere is no default drive to use,Fullnamean alias for path would solve this problem. Where changing an explicit PSPath is making a dangerous assumption, in the case ofSet-Locationassuming the user wants to use the PSPath and not the fullName for the filesystem is making a wrong one.iSazonov commentedon Aug 24, 2022
It is not "hide". It is fundamentally follow PowerShell provider conceptions. We should use these fundamental conceptions right.
Set-location \is not a prove. It demonstrate a bug we should fix.jhoneill commentedon Aug 24, 2022
we might need to accept an amicable disagreement :-)
Set-location \does demonstrate that current location is set to different places, one impacted by a bug, one notAnd (on windows at least) a path starting \ means "from the root of the current drive" but PowerShell lets us set the current location to somewhere with no drive like
Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOTorMicrosoft.PowerShell.Core\FileSystem::\MachineName\c$\Windows` what does "" or "root of the drive" mean then ?Your comment above
Is what I think, although you might have changed your mind since then :-) Having the location using the provider and the prompt showing path as the provider sees it seems like masking a problem to me and there are places where it doesn't give the right answer - if I connect a PS Drive to a network share...
I end up connected to
Microsoft.PowerShell.Core\FileSystem::\\MachineName\c$\WindowsShowing me the provider path
\\MachineName\c$\Windowsas a prompt instead of S: hasn't fixed the problem. Like the registry I cancdpast the root of drive S: to a different share or even a different server but CD \ fails. (any fix forcd \needs to cope with UNC paths).And if I do
get-item temp:\ | cdit puts me in theMicrosoft.PowerShell.Core\FileSystem::C:\Users\ME\AppData\Local\Temp>Showing me a prompt of
C:\Users\ME\AppData\Local\Tempis both correct and unexpected - I expect to be on the temp: drive But if there is come kind of lookup which translates that to TEMP: (and the UNC to S:) then if I doget-item $env:temp | cdthat will be wrong getting temp: instead of c:\users...In all these examples it is the way
set-locationprefers PSPath to the fullname property which is the problemiSazonov commentedon Aug 24, 2022
James O'Neill (@jhoneill) You can find a lot of issues like you have mentioned. There are fundamental reasons for this:
I tried to put it in an RFC, but that would have led to a huge redesign of PowerShell providers and public APIs - it was rejected.
jhoneill commentedon Aug 29, 2022
Also worth noting was an experimental feature to convert PSPaths to filesystem ones was in 7.2 and previews of 7.3 but has been dropped #17670
mklement0 commentedon Aug 30, 2022
Good point, James O'Neill (@jhoneill):
Given that the current binding of provider items via the pipeline happens by the
.PSPathproperty value only, the drive information is already lost by the timeSet-Locationsees the parameter value - and guessing a drive indeed sounds like a bad idea.Thus, the solution is to bind such items as objects, where a drive-letter-based path can be reconstructed via the
.PSDriveproperty. I think such a change would bring sanity toSet-Location's pipeline behavior without breaking anything.-LiteralPathin provider cmdlets - see the discussion in Property-based pipeline-parameter binding should be applied to argument-based parameter binding as well #6057Here's a proof of concept,
Set-LocationProperly, which wrapsSet-Locationwith the desired behavior.From what I can tell, it should work with all providers and PowerShell-only drives, so that all of the following commands should work as intended; if no drive information is present, the behavior is as before, but with file-system items that would then only happen with raw UNC paths:
Get-Item / | Set-LocationPropertly$PWD | Set-LocationProperlyGet-Item HKCU:\Console | Set-LocationProperlyNote:
Set-Locationbehavior:Set-Locationsomewhat pointlessly changes the directory for each input object, which means that the last (existing) input path "wins", in effect, with preceding nonexisting ones causing statement-terminating errors.Set-Location -PassThruin a pipeline in order to perform subsequent operations in the same pipeline in a distinct directory each.iSazonov commentedon Aug 31, 2022
Impossible without #5785
jhoneill commentedon Aug 31, 2022
Michael Klement (@mklement0) - good points too.
I see 2 issues with
set-Locationfirst what is intended when a provider path is provided, and where there are behaviour differences are they bugs or intentional and second the pipe behaviour does seem intended which can be fixed by makingFullNamean alias forPath, (and dodging the other issues).mklement0 commentedon Aug 31, 2022
Ilya (@iSazonov), a rewrite of the file-system provider will be most welcome, if and when it happens (the issue was created in 2018).
In the meantime, it looks to me that the above solution works, despite being a bit kludgy.
James O'Neill (@jhoneill):
Quick terminology clarification: provider path (perhaps better: provider-native path) usually refers to a path that is native to a given provider, and which PowerShell can't be expected to understand without a provider prefix; e.g.,
HKEY_CURRENT_USER\Consolevs.registry::HKEY_CURRENT_USER\Console- I'l call the latter a provider-qualified path.In the absence of a provider prefix and a drive spec at the start of a path, PowerShell interprets a path as relative to the current location of whatever provider underlies the current location, so that while a file-system location (directory) is the current location (as is typical),
Get-ChildItem HKEY_CURRENT_USER\Console(presumably in vain) looks for an file or directory namedConsolein aHKEY_CURRENT_USERsubdirectory, for instance.Ambiguity is avoided in one of two ways:
registry::HKEY_CURRENT_USER\ConsoleHKCU:\ConsoleNote that UNC file paths (e.g,
\\localhost\c$) are an edge case: they aren't drive-based, so if a provider other than the file-system provider underlies the current location, they are not recognized as file-system paths (trySet-Location function:; Get-Item \\localhost\c$). As an aside: Curiously, on Unix only,/and\are recognized as file-system paths even in a location such asfunction:- even though there is no drive spec involved and/and\should refer to the root location of the current drive (technically,/is a drive on Unix, but in the absence of a:following it, it can't be distinguished from referring to the current location's root); but perhaps this inconsistency is for the better in practice.With all this in mind:
Note that this would limit the solution to (a) file-system paths and (b) wouldn't respect PowerShell-only drives such as
Get-Item SomeCustomDrive:foo.txt | Set-LocationWhat the function above does is the following, which, from what I can tell, provides consistent behavior in line with user expectations:
If an object with provider ETS properties (
.PSPath, ...) is passed:If, in addition to
.PSPath, it has a.PSDriveproperty: translate the provider-qualified path (provider prefix + provider-native path) back into a drive-based path, as the presence of.PSDriveunambiguously implies that a drive-based path was used on input.Otherwise, if there's no drive information: Use the
.PSPathproperty, as currently, resulting in a full, provider-qualified path.In the context of file-system paths, this will then only happen with UNC paths.
$PWD.Pathvalue (and therefore the prompt string) will still be somewhat scary-looking (e.g.Microsoft.PowerShell.Core\FileSystem::\\localhost\c$), there is justification for this behavior, given that a UNC path is ambiguous, as explained above./-prefixed path is already unambiguously considered a file-system path on Unix.In the context of other providers - those that optionally allow addressing an item without a drive spec - you'd only get the provider-prefixed path if you explicitly avoided a drive spec, such as
Get-Item registry::HKEY_CURRENT_USER\Console | Set-Location(whereasGet-Item HKCU:\Console | Set-Locationwould preserve the drive).All other cases would result in the same behavior as currently.
SteveL-MSFT commentedon Sep 19, 2022
For the initial scenario, couldn't we more simply fix this by adding a noteproperty called
Pathto the output ofNew-Item?mklement0 commentedon Sep 19, 2022
Steve Lee (@SteveL-MSFT), the larger issue here is that
Set-Locationshould accept any[System.IO.DirectoryInfo]instance piped to it and honor its PS drive information, if present, not just if emitted byNew-Item.Thus, the better solution is to fix
Set-Location, as previously described, which requires modifying it to accept object input.The irony here is that providing a
[System.IO.DirectoryInfo]without provider instance properties currently actually works as expected, albeit by definition only ever with file-system-native paths, and only with file paths that don't contain[(that string pipeline input binds to-Pathinstead of-LiteralPathis unfortunate, but that's a separate problem):By contrast,
Get-Item $HOME | Set-Location, as reported in #9293, causes the same problem described in the initial post.SteveL-MSFT commentedon Dec 7, 2022
The @PowerShell/wg-powershell-cmdlets discussed this and since this is not a change in behavior and has existed for a long time, we recommend
Won't Fix