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:
- Get-Location
- $myinvocation
- $pwd
- $PSScriptRoot
Note:
The next section discusses PowerShell's notion of what the current (working) directory is, which is specific to PowerShell.
$pwdandGet-Locationtypically 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
PowerShell's current location vs. its current directory, PowerShell-specific vs. native file-system paths:
tl;dr
$PWD(equivalent to callingGet-Locationwithout 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:
With use of
$PWD/ argument-lessGet-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-Locationreports PowerShell's current location, which, however, isn't guaranteed to be a file-system location, given that a PowerShell provider other than theFileSystemprovider 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:
Note that the above expresses the file-system location potentially in terms of PowerShell-only drives, namely if the path passed to
Set-Locationwas expressed in terms of a drive created withNew-PSDrive.Therefore, to robustly determine the full path of the current file-system location as a native file-system path, use
.ProviderPathinstead of.Path:In the simplest case - if you're willing to assume that the current location is a file-system location - you can use the automatic
$PWDvariable, which is in effect a more efficient alternative to callingGet-Locationwithout arguments.Note:
Stringifying a
System.Management.Automation.PathInfoinstance - as reported by$PWD/Get-Location- results in the value of its.Pathproperty, so situationally you may not need to access the.Pathproperty 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 theFileSystemprovider; more generally, it returns the form of the path that is native to the underlying provider).