If I am in the console/terminal at the C:\temp
location, and I invoke the script C:\scripts\test.ps1
, how can I get the path of the current folder (C:\temp
) from inside the script I just invoked?
None of the following has the required information:
Note:
The next section discusses PowerShell's notion of what the current (working) directory is, which is specific to PowerShell.
$pwd
and Get-Location
typically work - but not always: see below.By contrast, if you want to know what the current process sees as its current directory, which notably applies to calls to .NET APIs, use [Environment]::CurrentDirectory
- this is typically not what PowerShell sees as its current location.
The reason for this discrepancy, which is rooted in PowerShell's ability to host multiple runspaces (threads) in a single process, is explained in GitHub issue #3428
Therefore, robustly calling .NET APIs (in-process) currently requires passing full, native file-system paths - see this answer
However, calls to external programs are not affected, because PowerShell does set its notion of the current file-system directory as the working directory of the child process that is invariably created for external programs.
Follow-up GitHub issue #17149 ponders synchronizing PowerShell's current (file-system) location with that of the process for the foreground runspace, specifically in the future, starting with an experimental feature; the latter has not yet been implemented as of PowerShell (Core) 7.3.6
tl;dr
$PWD
(equivalent to calling Get-Location
without arguments) will typically - but not necessarily - reflect PowerShell's current file-system location (working directory).
The fully robust solution for returning a string that expresses the working directory as file-system-native path is:
(Get-Location -PSProvider FileSystem).ProviderPath
With use of $PWD
/ argument-less Get-Location
, additional considerations apply with respect to (a) whether the resulting object even represents a file-system location, and (b) even if so, whether its form is understood by external programs.
Read on for background information.
Get-Location
reports PowerShell's current location, which, however, isn't guaranteed to be a file-system location, given that a PowerShell provider other than the FileSystem
provider could be the one underlying the current location - even though that is rare in practice.
Therefore, to robustly determine the full path of the current file-system location, use the following:
(Get-Location -PSProvider FileSystem).Path
Note that the above expresses the file-system location potentially in terms of PowerShell-only drives, namely if the path passed to Set-Location
was expressed in terms of a drive created with New-PSDrive
.
Therefore, to robustly determine the full path of the current file-system location as a native file-system path, use .ProviderPath
instead of .Path
:
# .ProviderPath only differs from .Path if the current
# file-system location is on a PowerShell-only drive
# (a non-persistent drive established with New-PSDrive)
(Get-Location -PSProvider FileSystem).ProviderPath
In the simplest case - if you're willing to assume that the current location is a file-system location - you can use the automatic $PWD
variable, which is in effect a more efficient alternative to calling Get-Location
without arguments.
# Same as: (Get-Location).Path
$PWD.Path # same as: "$PWD" (stringified)
Note:
Stringifying a System.Management.Automation.PathInfo
instance - as reported by $PWD
/ Get-Location
- results in the value of its .Path
property, so situationally you may not need to access the .Path
property explicitly; e.g., "The current location is: $PWD"
As noted, the .ProviderPath
(e.g. $PWD.ProviderPath
) returns the native file-system path (for instances representing the paths to items of the FileSystem
provider; more generally, it returns the form of the path that is native to the underlying provider).