Powershell: `Set-Location` breaks `$PWD`

Created on 4 Apr 2019  路  4Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

Steps documented below. $PWD.Path populates, but other members break (returning $null). This behavior does not happen by using Set-Location without piping.

Expected behavior

$ > Set-Location -Path C:\
$ > $PWD.Drive

Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
C                  50.00        100.00 FileSystem    C:\

$ > Get-Item -Path C:\Windows | Set-Location
$ > $PWD.Drive

Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
C                  50.00        100.00 FileSystem    C:\

$ >

Actual behavior

$ > Set-Location -Path C:\
$ > $PWD.Drive

Name           Used (GB)     Free (GB) Provider      Root
----           ---------     --------- --------      ----
C                  50.00        100.00 FileSystem    C:\

$ > Get-Item -Path C:\Windows | Set-Location
$ > $PWD.Drive
$ >

Environment data

Name                           Value
----                           -----
PSVersion                      6.2.0
PSEdition                      Core
GitCommitId                    6.2.0
OS                             Microsoft Windows 6.1.7601 S
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets-Management Issue-Question

Most helpful comment

The issue isn't the pipe here, it's the type of item you're providing. You're piping in a DirectoryInfo _object_ and not a string, which seems to cause Set-Location to actually use the PSPath property, seen here:

PS Microsoft.PowerShell.Core\FileSystem::C:\windows> get-item c:\windows | Set-location
PS Microsoft.PowerShell.Core\FileSystem::C:\windows> $pwd|fl *

Drive        : 
Provider     : Microsoft.PowerShell.Core\FileSystem
ProviderPath : C:\windows
Path         : Microsoft.PowerShell.Core\FileSystem::C:\windows

Either the Set-Location command needs to be updated to normalize the path it's using properly, or whatever it's calling that causes $pwd to be updated needs to be fixed. Ideally, I'd want both fixed to double-check each other, tbh, just in case someone tries to be funny and update it themselves somehow in a weird way.

All 4 comments

The issue isn't the pipe here, it's the type of item you're providing. You're piping in a DirectoryInfo _object_ and not a string, which seems to cause Set-Location to actually use the PSPath property, seen here:

PS Microsoft.PowerShell.Core\FileSystem::C:\windows> get-item c:\windows | Set-location
PS Microsoft.PowerShell.Core\FileSystem::C:\windows> $pwd|fl *

Drive        : 
Provider     : Microsoft.PowerShell.Core\FileSystem
ProviderPath : C:\windows
Path         : Microsoft.PowerShell.Core\FileSystem::C:\windows

Either the Set-Location command needs to be updated to normalize the path it's using properly, or whatever it's calling that causes $pwd to be updated needs to be fixed. Ideally, I'd want both fixed to double-check each other, tbh, just in case someone tries to be funny and update it themselves somehow in a weird way.

@vexx32 Thanks for the additional digging. I found this behavior also exists on Windows PowerShell. I noticed it because it kept breaking $Function:prompt

Aaaand I figured out a way to fix it.

PS Z:\Scripts\PowerShell-Core> gi c:\windows|set-location
PS C:\windows> $pwd

Path
----
C:\windows

PS C:\windows> $pwd|fl *

Drive        : C
Provider     : Microsoft.PowerShell.Core\FileSystem
ProviderPath : C:\windows
Path         : C:\windows

_Update_: This may be a separate problem - see #10522


As of 7.0.0-preview.3, the problem is now more conspicuous:

PS> Get-Item / | Set-Location
PS Microsoft.PowerShell.Core\FileSystem::>

Note the broken current location reported via the prompt function, based on the stringification of $executionContext.SessionState.Path.CurrentLocation (effectively, its .Path property).

(As an aside: on Windows you'd get PS Microsoft.PowerShell.Core\FileSystem::C:\>, but on Unix the / gets eaten.)

Was this page helpful?
0 / 5 - 0 ratings