Skip to content

[Design] MachineFolder: a per-machine writable data store for MSIX-packaged PowerShell #27697

Description

@jshigetomi

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:ApplicationDataappdata:MachineFolder extension. 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 using GetCurrentPackageFamilyName (kernel32) plus the PackageRepositoryRoot registry value. Returns null when 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, alongside AllUsers (= $PSHOME, read-only product defaults) and CurrentUser.
  • Merge precedence:
    • Policy settings: MachineFolder → $PSHOME → CurrentUser (system wins)
    • Preference settings: CurrentUser → MachineFolder → $PSHOME (user wins)
  • Writes targeting AllUsers are redirected to the MachineFolder store when packaged; only changed values are written (the shipped $PSHOME product 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

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Enhancementthe issue is more of a feature request than a bugPackage-MSIXIssue occurs with MSIX packageWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions