# CD to user home directory then call GetFullPath with a relative path
cd; [System.IO.Path]::GetFullPath("path")
Per the documentation for GetFullPath and the behavior in Windows PowerShell:
C:\Users\<USER>\path
A path relative to "c:\windows\system32\" is returned regardless of the current working directory.
C:\WINDOWS\system32\path
Name Value
---- -----
PSVersion 7.0.0-preview.2
PSEdition Core
GitCommitId 7.0.0-preview.2
OS Microsoft Windows 10.0.18362
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
None of the .NET internal/integral methods recognize the current $PWD to the best of my knowledge. My first experience with this was with the [XML.Document] Save() method.
I wouldn't be surprised if Windows PowerShell behaves the same, just happens to set the current .NET directory differently.
Just checked it, actually, and using PowerShell Set-Location commands does _not_ affect the current directory from .NET's end. Windows PowerShell _does_ however set the initial location differently.
So this is the same in Windows PS, just with different initial locations between winPS and Core
Please see #3428.
The short of it:
Use Convert-Path to resolve a (relative) PowerShell path to a full one.
Because PowerShell allows you to create multiple runspaces in a single process, each with its own current location, while .NET has only _one_ current directory for the whole process ([Environment]::CurrentDirectory), it cannot keep the current PowerShell (filesystem) location in sync with .NET
Ok. I see there is an open doc issue for this. Would be nice to see this captured somewhere discoverable as while always converting to absolute paths works that's not obvious or natural if you haven't been burned by this before.
@vexx32, the difference is in the setting of the Start in: setting in the start menu shortcut. Windows Powershell has it set to %HOMEDRIVE%%HOMEPATH%, while PowerShell Core doesn't specify it.
This is one of those items 'Hey, you can just access the entire .NET subsystem...', 'Yes, ...but there are so many thing you will need to learn first!'
@mklement0, just found out Convert-Path is worthless if the path does not yet exist, say when you are using the 'MoveTo()' method.
@msftrncs, yes, good point, that is a current limitation - see #2993
The short of it is:
To pass not-yet-extant paths (PowerShell _Core_ only, because only .NET Core supports the .GetFullPath() overload with a second argument that specifies the reference directory):
[IO.Path]::GetFullPath($path, $PWD.ProviderPath)
To be fully robust, you additionally need to guard against the current location not being a _filesystem_ location:
[IO.Path]::GetFullPath($path, (Get-Location -PSProvider FileSystem).ProviderPath)
The latter should work in _all_ scenarios - but it doesn't exactly roll off the tongue.