Repository navigation
Add PSContentPath Infrastructure - #26509
Justin Chung (jshigetomi) wants to merge 52 commits into
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. |
|
Justin Chung (@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. |
|
Ryan Yates (@kilasuit) - Thanks for calling me out on that. Definitely intended this as a draft. |
…Shell into PSModulePathFix
198cfc3 to
95ec9f8
Compare
|
Justin Chung (@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 Ilya (@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
|
Hello! I am looking forward to this implementation and I am just curious if it has been slated for any particular release milestones. Do you think it'll make it into 7.7.0? |
|
Please also provide Push/Pop-PSContentPath. especially because you're planning on using a fallback stack anyways. This would be incredibly useful when working in certain contexts, like git worktreees. |
|
dn-jmp The goal is to make it into 7.7 |
|
One other curveball to potentially support would be having no content path. Why? Lockdown scenarios and isolation testing. If I wanted to isolate a particular load error, I would want to ensure that no content is loaded from other directories. Similarly, if I wanted to lock down a particular session so that it cannot load other things, I would want to load whatever is required, change the content paths, and change the language mode. If there was no acceptable location to load content from, this would help harden the surface area in these scenarios. |
|
James Brundage (@StartAutomating) the no content path scenario is interesting. Right now, the content is made available via the PSModulePath variable, and this PR just provides infrastructure to add the defined content path to PSModulePath. The scope of this work would be beyond just the user level. |
Fine to know. If we're just manipulating PSModulePath, then definitely Push/Pop-PSContentPath. Also, if we're manipulating PSModulePath, for discoverability I'd highly suggest |
|
James Brundage (@StartAutomating) We can get that in the next PR, do not want to delay this anymore. |
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,Documents\PowerShellis still preferred for PSContentPath , with a fallback for legacy locations. This was to avoid a breaking change and just make this PR an introduction for the infrastructure.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.
Partially Addresses: #26121 #27370 #24274
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header