PowerShell profiles on PowerShell Core

Created on 27 Aug 2017  路  8Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

#Add the following to the $profile file
$PSDefaultParameterValues.Add('Get-Service:Name', 'spooler')
#Open PowerShell Core and inspect the contents of $PSDefaultParameterValues
$PSDefaultParameterValues

Expected behavior

$PSDefaultParameterValues should contain the contents specified in the PowerShell profile file specified in $profile.

Actual behavior

$PSDefaultParameterValues is blank.

The same example works as expected on PowerShell Desktop 5.1.

Is profile support removed from PowerShell Core?

Environment data

> $PSVersionTable
ame                           Value
----                           -----
PSVersion                      6.0.0-beta
PSEdition                      Core
GitCommitId                    v6.0.0-beta.4
OS                             Microsoft Windows 10.0.15063
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Resolution-Answered

Most helpful comment

I was sure I upgraded to beta 6 yesterday, but that turned out to be on a different machine.
Anyway, I think I found the root cause.
$profile points to C:UsersDocumentsPowerShellMicrosoft.PowerShell_profile.ps1. I didn`t know that PowerShell Core does not leverage the same profile path as PowerShell Desktop (C:UsersDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1.)

After creating a symbolic link to the WindowsPowerShell folder it works as expected:

New-Item -ItemType SymbolicLink -Path (Join-Path -Path $Env:USERPROFILE -ChildPath Documents) -Name PowerShell -Target (Join-Path -Path $Env:USERPROFILE -ChildPath Documents\WindowsPowerShell)

All 8 comments

It may not always make a difference, but generally please try to use the most recent release before reporting an issue - current is beta 6.

In the current beta I cannot reproduce the issue.
Silly questions, but did you make sure to either open a new session after changing $PROFILE or run . $PROFILE before testing? Is there code in the profile that runs later and perhaps clears the variable?

I'm not repro'ing this either in beta.6

I was sure I upgraded to beta 6 yesterday, but that turned out to be on a different machine.
Anyway, I think I found the root cause.
$profile points to C:UsersDocumentsPowerShellMicrosoft.PowerShell_profile.ps1. I didn`t know that PowerShell Core does not leverage the same profile path as PowerShell Desktop (C:UsersDocumentsWindowsPowerShellMicrosoft.PowerShell_profile.ps1.)

After creating a symbolic link to the WindowsPowerShell folder it works as expected:

New-Item -ItemType SymbolicLink -Path (Join-Path -Path $Env:USERPROFILE -ChildPath Documents) -Name PowerShell -Target (Join-Path -Path $Env:USERPROFILE -ChildPath Documents\WindowsPowerShell)

Yes, the $PROFILE paths are edition-specific, which generally makes sense (and, obviously, there's no _Windows_ PowerShell profile on Unix platforms).

And if you already have the Documents\PowerShell directory:

New-Item -ItemType SymbolicLink -Path (Join-Path -Path $Env:USERPROFILE -ChildPath Documents\PowerShell) -Name Microsoft.PowerShell_profile.ps1 -Target (Join-Path -Path $Env:USERPROFILE -ChildPath Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

The snippets above will not work correctly for users who have their Documents directory renamed or redirected out of the default location. Typical cases include redirection to OneDrive.

The robust way is to ask the OS for the location of the Documents directory:

# if pwsh profile directory does not exist yet
New-Item -ItemType SymbolicLink -Path ([Environment]::GetFolderPath('Personal')) -Name PowerShell -Target (Join-Path -Path ([Environment]::GetFolderPath('Personal')) -ChildPath WindowsPowerShell)

# if pwsh profile directory already exists
New-Item -ItemType SymbolicLink -Path (Join-Path -Path ([Environment]::GetFolderPath('Personal')) -ChildPath PowerShell) -Name Microsoft.PowerShell_profile.ps1 -Target (Join-Path -Path ([Environment]::GetFolderPath('Personal')) -ChildPath WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Good point, @jberezanski.

Two asides:

  • I wish calling a .NET method weren't needed for this - see #6966

  • PowerShell's automatic $HOME variable is defined as the value of %USERPROFILE% (using cmd notation; for the profile and configuration information), though it should have been %HOMEDRIVE%%HOMEPATH% (for the user's _files_), because these two can be configured to point to different locations.

Actually, several years ago I had created a PS module for inspecting and manipulating known folders using the COM API (which provides much more functionality than the legacy API used internally by the .NET Environment class). I wanted to ease my pain of mass redirecting the folders (including the Public ones) out of the system drive when setting up multiple computers for several members of my family - by default possible only by clicking in the GUI (and requiring temporarily disabling UAC to move the Public folders). The goal was to be able to write

# as any user
Get-KnownFolder | Move-KnownFolder -Destination F:\Profiles\$Env:UserName
# as admin
Get-KnownFolder -Public | Move-KnownFolder -Destination F:\Profiles\Public

The module is fully functional (I tend to use it any time I set up a new computer); I just ran out of free time and motivation to make the finishing touches - writing some docs/examples and publishing to PSGallery. I could probably make that effort if there is interest.

Here we would use:

PS C:\> (Get-KnownFolder -Name Personal).Path
F:\Profiles\jberezanski\Documents

Edit: I skimmed your post and jumped straight to writing my answer without noticing the linked issue; I'll repost it there, maybe it will help someone.

Was this page helpful?
0 / 5 - 0 ratings