Powershell: Push-Location does not set [Environment]::CurrentDirectory

Created on 5 Jun 2019  路  9Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

PS C:\Users\lit> Push-Location 'W:\home'
PS W:\home> (Get-Location).Path
W:\home
PS W:\home> Write-Host ([System.Environment]::CurrentDirectory)
C:\WINDOWS\System32
PS W:\home> $PSVersionTable.PSVersion.ToString()
6.2.1

Expected behavior

[Environment]::CurrentDirectory would have the value 'W:\home'.

Actual behavior

 [Environment]::CurrentDirectory contains 'C:\WINDOWS\System32'.

Environment data

PSVersion 6.2.1 PSEdition Core GitCommitId 6.2.1 OS Microsoft Windows 10.0.17763 Platform Win32NT PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1 WSManStackVersion 3.0

Issue-Question Resolution-Answered

Most helpful comment

There's also the issue where you could do Push-Location -Path HKLM:\SOFTWARE but that does not translate into an actual file system path.

All 9 comments

@Liturgist This is actually by design. PowerShell supports multiple runspaces per process, each of which has its own notion of the "current directory". Even if set/push-location did set the process-wide current directory, you couldn't depend on it because another runspace might change it at any time. As a result, you have to use the provider APIs to perform path-based operations using the current working directory specific to the current runspace.

Ok, then. It appears that [Environment]::CurrentDirectory is not necessarily the CurrentDirectory in a given runspace. I guess that means using Resolve-Path for any references.

Given that, what are some use cases for using [Environment]::CurrentDirectory?

Also, why does [Environment]::CurrentDirectory get set in ISE after doing a Push-Location?

Push-Location is clearly not equivalent to PUSHD in cmd.exe.

There's also the issue where you could do Push-Location -Path HKLM:\SOFTWARE but that does not translate into an actual file system path.

@Liturgist This is actually by design. PowerShell supports multiple runspaces per process, each of which has its own notion of the "current directory". Even if set/push-location did set the process-wide current directory, you couldn't depend on it because another runspace might change it at any time. As a result, you have to use the provider APIs to perform path-based operations using the current working directory specific to the current runspace.

What would be applicable uses for the process-wide current directory?

Have you tried Get-Location instead?

I am find with runspaces all having their own "current" working directory.

What I would like to know is appropriate uses for the process-wide current directory? [Environment]::CurrentDirectory

Spawning new processes, or checking the dir for .NET function calls would be my guess.

@Liturgist

What I would like to know is appropriate uses for the process-wide current directory?

In PowerShell? Basically none. Processes are spawned using the Runspace CWD so the process CWD doesn't matter. You _could_ set the CWD if you're using the .NET filesystem APIs as long as you can guarantee that there are no other Runspaces being used which is only possible for personal scripts. But even then, the .NET APIs don't understand PowerShell paths so you're better off using the Provider APIs to resolve the path before passing it to File.ReadAllText(). Ultimately, [Environment]::CurrentDirectory is exposed because PowerShell exposes .NET and that API is part of .NET.

Ok, I will take it that [System.Environment]::CurrentDirectory is not of much use in PowerShell.

Would it be expected to reflect the current directory at the time PowerShell was started (assuming that no PowerShell code has use a .NET call to change it)?

Was this page helpful?
0 / 5 - 0 ratings