Windows Powershell $profile does not show a real path

tl;dr:

The problem may not be PowerShell-related, but may be due to a missing special-folder path definition in the registry.

Verify that registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders contains a REG_EXPAND_SZ value named Personal with data %USERPROFILE%\Documents - see diagnostic commands below.

If you find that you must (re)create it, use:

New-ItemProperty `
  'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders' `
  Personal -Value '%USERPROFILE%\Documents' -Type ExpandString -Force

and then log off and back on (or reboot) to see if that fixed the problem.


Eris's helpful answer tells us that the user-specific PS profile paths are derived from what Environment.GetFolderPath(Environment.SpecialFolder.Personal) returns.

.NET gets this value, presumably via the SHGetKnownFolderPath Shell API function, from registry key HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders, value Personal, where it is normally defined as a REG_EXPAND_SZ value containing (expandable) string %USERPROFILE%\Documents.
(There's also a legacy fallback location - see here.)

Profiles CurrentUserAllHosts and CurrentUserCurrentHost containing just relative paths, namely:

  • WindowsPowerShell\profile.ps1
  • WindowsPowerShell\Microsoft.PowerShell_profile.ps1

suggests that the Environment.GetFolderPath(Environment.SpecialFolder.Personal) call, whose result is used as the path prefix, unexpectedly returned an empty string, which in turn suggests a registry problem.


Here are some diagnostic commands and their expected outputs (jdoe represents your username):

# Verify that %USERPROFILE% is defined.
> $env:USERPROFILE
C:\Users\jdoe

# Verify that %USERPROFILE% is defined in the registry.
> Get-ItemPropertyValue 'HKCU:\Volatile Environment' USERPROFILE
C:\Users\jdoe

# Verify that the API call to retrieve the known folder
# "Personal" (Documents) returns the expected value.
> [Environment]::GetFolderPath('Personal')
C:\Users\jdoe\Documents

# See if the registry contains the expected definition.
> Get-ItemPropertyValue 'HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders' Personal
C:\Users\jdoe\Documents

According to the powershell source code on github, they look for Environment.SpecialFolder.Personal

It starts in ConsoleHost.cs and you can track this down to utils.cs where they call Environment.GetFolderPath(Environment.SpecialFolder.Personal);