Add PSContentPath Infrastructure#26509
Conversation
…ether or not migration took place
…ault PSContentPath location
There was a problem hiding this comment.
Pull request overview
This PR introduces an experimental feature called PSContentPath that changes the default location for PowerShell user content (modules, scripts, help, and profiles) from Documents\PowerShell to LocalAppData\PowerShell on Windows, and provides a configurable path via Get-PSContentPath and Set-PSContentPath cmdlets. The feature includes lazy migration logic to move config files from the old location to the new location when the experimental feature is enabled.
Key changes:
- Adds experimental feature
PSContentPathwith new cmdlets to get/set the content path - Implements lazy migration from old config directory to new default location (LocalAppData)
- Updates all content path references to use the centralized
Utils.GetPSContentPath()API
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| ExperimentalFeature.cs | Adds PSContentPath experimental feature definition |
| GetSetPSContentPathCommand.cs | New cmdlets for getting and setting PSContentPath with validation |
| PSConfiguration.cs | Adds GetPSContentPath/SetPSContentPath methods and lazy migration logic |
| Utils.cs | Adds GetPSContentPath() helper method with fallback logic |
| CorePsPlatform.cs | Adds DefaultPSContentDirectory constant for the new default location |
| ModuleIntrinsics.cs | Updates GetPersonalModulePath and SetModulePath to use new API |
| HostUtilities.cs | Updates profile path logic to use GetPSContentPath |
| HelpUtils.cs | Updates help search path to use GetPSContentPath |
| InitialSessionState.cs | Registers new Get/Set-PSContentPath cmdlets |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
If user intention is to migrate content to new location I believe the new cmdlets should help them. |
|
@jshigetomi - Please mark this PR as a Draft & go through the PR checklist & mark things appropriately add some PR Context as is requested in the PR template. Until all thats done we shouldn't look to accept this pr. You can do better than this & should do so in future too. |
|
@kilasuit - Thanks for calling me out on that. Definitely intended this as a draft. |
…Shell into PSModulePathFix
|
@jshigetomi I'm coming back to this & am reviewing right now & wanna address some bits prior to a proper code review. I noticed earlier you had mentioned
I see this was removed since then and that copilot was concerned about data loss which we can't 100% manage as well all sorts of things can happen that can cause data loss. However, this concern "could" be worked around by having an export/import mechanism (as opposed to a move) by making use of archiving methods maybe by using the Microsoft.PowerShell.Archive module or native with an Export-PSContent cmdlet and an Import-PSContent cmdlet duo which I think would enable 2 important scenarios in my mind
Tne Preseeding scenario also allows for smaller OS images too which is a good thing. Which I can envison being part of some orgs DSC configurations as I know it would be part of any future ones that I would use whether it be to build an OS/Container Image. This also supports being able to do hashing checks for integrity purposes. That's something that I'd like to see we have however I'm 50/50 on whether these Cmdlets should be in PSResourceGet or included as part of PowerShell. There's benefits having them in both places & infact I think that it may actually be sensible to have them in both, at least for a short period of time. Also we need to be mindful of not overengineering this just because we can, however as part of the Import process, on completion it optionally could remove any existing data from the old location as we have to be mindful of some of the 7 & 5.1 differences and just leave this up to the user/admins to manage.
I don't see this being needed with your Set-PSContentPath cmdlet so kinda glad this has gone from how this is right now for review.
Whilst I don't like it, PowerShellGet 1.0.0.1 & other versions of that module could potentially be updated to check for an environment variable or reg key entry that points to the new PSContentPath which I think would mitigate @iSazonov concerns here.
What do you mean by this? |
When pwsh 6 came out it moved the modules directory from Documents\WindowsPowerShell to Documents\PowerShell. For that transition we added the Documents\PowerShell module folder to $env:PSModulePath first while keeping Documents\WindowsPowerShell. And for removing Move-PSContentPath, I think it would be best in another PR so we don't bloat this one up more than it already is. But yes I do like your ideas. Once this is in I will work on creating a nice migration tool of some sort. |
|
Only other small comment atm is would it be best to just have all -PSContent cmdlets in |
|
The @PowerShell/wg-powershell-cmdlets discussed the cmdlets. For |
198cfc3 to
95ec9f8
Compare
|
@jshigetomi can we please update PR Summary with the changes since Steve's comments from the Working Group above which FYI I wasn't able to attend the meeting where these comments came from. Also just for people like @iSazonov reading this PR that wanted the Size to be returned as part of An example returning the User's PSModulePath directories recursive size using the PSTree Module would be |
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
- Added tests for automatic variable. - Added tests for -default parameter - added tests for legacty documents path -Added test for deduplication of PSModulePath
…elpful error Fix tests
PR Summary
This pull request introduces new user-facing cmdlets for managing the PowerShell content path, refactors how personal module and configuration paths are determined, and improves cross-platform consistency for configuration storage. The most significant changes are the addition of
Get-PSContentPathandSet-PSContentPathcmdlets, updates to the logic for resolving user content/config paths (especially on Windows), and the adoption of the content path as the basis for the personal module path.Platform-specific content/config path handling:
DefaultPSContentDirectoryandLocalAppDataPSContentDirectoryproperties inCorePsPlatform.csto standardize the location of PowerShell content data across platforms. On Windows, this now prefersLocalAppData\PowerShell, with a fallback for legacy locations.PowerShellConfigto select the user config directory/file based on the presence of existing config files, ensuring backward compatibility while defaulting to the new location for new installs.Personal module path changes:
GetPSContentPath()), rather than hardcoded locations likeMy Documentsor XDG directories.Constants and documentation improvements:
ModuleIntrinsics.cs.New cmdlets for PSContentPath management:
Get-PSContentPathandSet-PSContentPathcmdlets, allowing users to query and configure the PowerShell content path with validation logic.Get-PSContentPathGets the current PowerShell user content path (where modules, scripts, help, and profiles are stored). Returns a
System.IO.DirectoryInfoobject with aConfigFileNoteProperty attached, which the default list formatter displays.Set-PSContentPathSets a custom content path, persisted in
powershell.config.json. The confirm impact isHigh, so users are prompted for confirmation by default.-Path <string>-Default-WhatIf/-Confirm$PSUserContentPathVariableA readonly automatic variable exposing the current content path. Users cannot modify it directly—they get a helpful error directing them to use
Set-PSContentPath.PR Context
This change represents a major milestone for the PowerShell ecosystem—one that has been long requested by the community, and discussed extensively. The feature originated from community feedback in #15552, aligns with related work in PowerShell/PSResourceGet#1912, and was shaped through detailed specifications in PowerShell/PowerShell-RFC#388.
This feature lays the foundation for flexible, user-configurable PowerShell content storage, addressing scenarios such as roaming profiles and containerized environments.
By enabling customization of content paths, we empower users to adapt PowerShell to modern deployment and security requirements.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header