Repository navigation
[Design] MachineFolder: a per-machine writable data store for MSIX-packaged PowerShell #27697
Description
Summary
Under MSIX, $PSHOME is read-only and package registration is per-user, so PowerShell has nowhere to persist system-wide state (config, profile, session configuration, updatable help). This issue describes the shared mechanism those individual gaps build on: an admin-writable, all-users-readable per-machine data store ("MachineFolder"), and the configuration merge model layered on top of it.
This is the solution substrate for the gaps first reported in #9278 and tracked under #27565. First implementation (system-wide config) is in PR #27632.
Mechanism
- Opt in via the AppxManifest
appdata:ApplicationData→appdata:MachineFolderextension. The OS provisions the folder at…\AppRepository\Families\ApplicationData\<PackageFamilyName>\Machine. - ACL via SDDL
(A;OICI;GA;;;BA)(A;OICI;GR;;;BU)→ Administrators full control, Built-in Users read, both inherited to child files and subfolders. - Detection / entry point:
Utils.GetPackagedMachineDataStorePath()— resolves the store usingGetCurrentPackageFamilyName(kernel32) plus thePackageRepositoryRootregistry value. Returnsnullwhen the process has no package identity (unpackaged) or off-Windows, so all behavior collapses to the legacy model when the store is absent.
Configuration model (first consumer — PR #27632)
- New
ConfigScope.MachineFolder, alongsideAllUsers(=$PSHOME, read-only product defaults) andCurrentUser. - Merge precedence:
- Policy settings: MachineFolder →
$PSHOME→ CurrentUser (system wins) - Preference settings: CurrentUser → MachineFolder →
$PSHOME(user wins)
- Policy settings: MachineFolder →
- Writes targeting
AllUsersare redirected to the MachineFolder store when packaged; only changed values are written (the shipped$PSHOMEproduct config is never rewritten). Group Policy / registry continues to trump all config.
⚠️ Behavior change to fold in
Experimental features moved to an explicit per-feature enabled/disabled model (per-scope ExperimentalFeatures + DisabledExperimentalFeatures sets). A consequence: an older config that disabled a preview feature by omission (a reduced ExperimentalFeatures list) is reinterpreted as "explicit enables plus product defaults," so that feature re-enables once. Old JSON still parses and loads. This is what currently updates test/powershell/engine/ExperimentalFeature/Get-ExperimentalFeature.Tests.ps1 (the "Feature is enabled in user config only" case) and relates to the Test-CanWriteToPsHome revert called out in #9278.
Rollout / children
- System-wide config relocation — PR Place System-Wide Config in the Machine Folder for MSIX Packages #27632
- AllUsers profile relocation — PS7-packaged: $profile.AllUsersAllHosts not writable by administrators #27564
- SessionConfig
.psscwrite-location (Register/Set-PSSessionConfiguration) — Some cmdlets and config require writing to $PSHOME\SessionConfig folder #9278 (WinRM/remoting activation tracked separately in PS7-packaged: WinRM / PowerShell Remoting broken under MSIX #27563) - Updatable help at system scope — PS7-packaged: Update-Help -Scope AllUsers fails under MSIX ($PSHOME read-only) #27699
- Export effective config cmdlet — PS7-packaged: provide a cmdlet to export the fully merged / effective configuration #27698
Non-goals
- Mutable/mutable-directory packages.
- Package Support Framework (PSF): changes the entry point to a per-user, non-elevated launcher, so it cannot provision or seed an admin-owned machine store.
Tracked by #27565.
Activity