Enterprise-grade MSIX packaging automation for mission-critical environments. Covers the full conversion lifecycle: static + runtime investigation, PSF injection, manifest editing, signing (local / Azure Trusted Signing / Key Vault), CI/CD pipeline orchestration, sandbox debugging, App Attach, Win32 App Isolation, deployment-script templates, and a comprehensive Pester test suite.
Security note — this module is designed for use in high-assurance environments (DoD, NATO, financial, healthcare). All downloaded toolchain binaries are Authenticode-verified against a trusted-publisher allowlist before use. Signing secrets are kept in
[SecureString]throughout; they never appear in log output, recommendation text, or on the process command line (with the exception of theSignToolbackend which emits aWrite-Warningwhen this happens).
- Why this module
- Quick start
- Architecture
- Investigation & auto-fix
- PSF injection
- Signing backends
- Standard scripts (PSADT)
- Win32 App Isolation
- Manifest-only fixers
- Pipeline orchestrator
- App Attach (VHDX / CIM)
- Context menus
- Debug & sandbox
- CI/CD
- Tests
- What's new in v0.73
- Release history
- License
Microsoft's MSIX docs describe a manual workflow for every common conversion
problem: download Procmon, set filters, run the app, eyeball the failures,
hand-edit config.json, copy DLLs, repack, sign. This module collapses that
into a small set of idempotent, pipeline-safe functions.
Key design principles
| Principle | How it's implemented |
|---|---|
| Sign once | Invoke-MsixPipeline unpacks, edits, repacks, then signs a single scratch copy. The original is never overwritten until signing succeeds. |
| No secrets on disk | PfxPassword is [SecureString] everywhere; Get-MsixDebugRecommendation emits Read-Host -AsSecureString placeholders, never the real value. |
| No unverified binaries | Every toolchain download (PSF, Procmon, msixmgr, SDK tools) is Authenticode-verified before use. |
| WhatIf everywhere | All mutating cmdlets support -WhatIf. Pack/unpack still runs so you can preview the result; signing and the final file replacement are skipped. |
| Idempotent | All manifest mutators are safe to run twice — they check before writing. |
References this module automates:
- Package Support Framework overview
- PSF — FileSystem Write Permission
- PSF — Run scripts to create shortcuts
- Accelerators
- Support legacy context menus
- Win32 app isolation
- TMurgent PSF fork
The maintainer owns the
MSIXname on PSGallery (Install-Module MSIX). When developing against a working copy, import by full path so you load the repo version rather than the installed one.
Import-Module 'C:\path\to\MSIX\MSIX.psd1' -Force
# One-time toolchain setup: MakeAppx, signtool, PSF, Procmon, msixmgr
# All from official/signed sources, on demand.
Initialize-MsixToolchainInitialize-MsixToolchain downloads and Authenticode-verifies:
| Component | Source | Used by |
|---|---|---|
MakeAppx.exe + signtool.exe |
Microsoft.Windows.SDK.BuildTools (NuGet) | pack / unpack / sign |
| TMurgent PSF | GitHub releases (Tim Mangan) | Add-MsixPsfV2, Add-MsixStandardScript |
| Sysinternals Process Monitor | Sysinternals (Microsoft) | Invoke-MsixInvestigation -WithProcMon |
| msixmgr | aka.ms/msixmgr (Microsoft) |
New-MsixAppAttachImage |
Skip individual components: Initialize-MsixToolchain -Skip Sdk,Procmon,MsixMgr
MSIX\
├── MSIX.psd1 Module manifest (v0.73.0)
├── MSIX.psm1 Root module — dot-sources all sub-modules
├── MSIX.Logging.ps1 Write-MsixLog + log-level / file controls
├── MSIX.Core.ps1 Workspace, process runner, tools resolution
├── MSIX.Validation.ps1 Manifest / config / process validators
├── MSIX.Manifest.ps1 XML helpers, namespace registry, pure transforms
├── MSIX.ManifestExtensions.ps1 Manifest-only fixers (desktop6, uap5, uap6…)
├── MSIX.PSF.ps1 Fixup builders + Add-MsixPsfV2 injection engine
├── MSIX.PsfBinaries.ps1 PSF / Procmon / SDK downloader + Authenticode verify
├── MSIX.Signing.ps1 Invoke-MsixSigning (SignTool / TrustedSigning / AzureSignTool)
├── MSIX.Pipeline.ps1 Invoke-MsixPipeline — sign-once orchestrator
├── MSIX.ContextMenu.ps1 com + desktop4/desktop5 context menus (legacy IContextMenu + modern IExplorerCommand)
├── MSIX.Scripts.ps1 PSADT-flavoured standard scripts + Set-MsixScriptSignature
├── MSIX.AppIsolation.ps1 Win32 App Isolation (rescap capabilities, opt-in)
├── MSIX.Investigation.ps1 Static + procmon analysis + recommendations
├── MSIX.Scanners.ps1 Read-only Get-Msix*Candidate/*Entry/HeuristicFinding
├── MSIX.PackageMutators.ps1 Add-MsixCapability + Remove-Msix*Artifact + payload Add-*
├── MSIX.AutoFix.ps1 Invoke-MsixAutoFix + Invoke-MsixAutoFixFromAnalysis
├── MSIX.Detection.ps1 Read-only scanners (fonts, shortcuts, capability hints)
├── MSIX.Debug.ps1 Start-MsixDebugSession + sandbox bootstrap
├── MSIX.AppData.ps1 Container / orphan / merged-fs helpers
├── MSIX.AppAttach.ps1 VHDX/CIM generator (msixmgr, Authenticode-verified)
├── MSIX.Accelerator.ps1 MS Learn accelerator YAML import + apply (safe parser)
├── MSIX.Limitations.ps1 Limitations knowledge base
├── MSIX.Trace.ps1 DebugView / TraceFixup output parser
├── MSIX.MFR.ps1 Modern File Redirection (TMurgent fork)
├── MSIX.VcRuntime.ps1 VC++ runtime detection + bundling
├── MSIX.Compare.ps1 Compare-MsixPackage (manifest + file + signing diff)
├── MSIX.OfflineRegistry.ps1 Offreg (offline hive) read/write helpers
├── MSIX.Distribution.ps1 .appinstaller, modification + framework packages
├── MSIX.Bundle.ps1 .msixbundle: bundle/unbundle + mutate-through-bundle
├── MSIX.RuntimeTest.ps1 Test-MsixDeployment (Hyper-V runtime verification)
├── templates/ .ps1.tmpl files for standard scripts
├── MSIX.Tests/ Pester v5 test suite (700+ tests)
├── docs/ Per-fixup reference, limitations, know-your-installer
├── CONTRIBUTING.md Coding standards and security guidelines
├── EXAMPLES.md 26 copy-paste recipes for all major use cases
└── TEST-PLAN.md 14 manual / integration test scenarios + release checklist
All logging uses Write-Information (stream 6) — fully capturable in CI
pipelines. Security-critical notices use Write-Warning (stream 3) so they
appear in -WarningVariable captures.
$report = Invoke-MsixInvestigation -PackagePath app.msix
$report.Findings | Format-Table Severity, Category, Symptom
$report.SuggestedFixups | ConvertTo-Json -Depth 8 # PSF path
$report.SuggestedManifestFixes | Format-Table # manifest alternatives
$report.RecommendedCommands | Out-File next-steps.ps1Initialize-MsixToolchain
$report = Invoke-MsixInvestigation -PackagePath app.msix -WithProcMon `
-PackageFamilyName 'Contoso.App_8wekyb3d8bbwe' -AppId 'App' `
-DurationSeconds 30 -ProcessName 'app.exe'Invoke-MsixAutoFixFromAnalysis connects investigation to remediation — it
runs the right fixer for every finding and signs once at the end.
$report = Invoke-MsixInvestigation -PackagePath app.msix
Invoke-MsixAutoFixFromAnalysis -Report $report `
-VcRuntimeSourceFolder 'C:\…\VC143.CRT' `
-Pfx cert.pfx -PfxPassword (Read-Host -AsSecureString)
# Preview only — no mutation:
Invoke-MsixAutoFixFromAnalysis -Report $report -DryRun$pw = Read-Host -AsSecureString
# File redirection (writes to install-dir → per-user redirect)
$frf = New-MsixPsfFileRedirectionConfig -Base 'VFS/ProgramFilesX64/App/' `
-Patterns '.*\.log', '.*\.tmp', '.*\.cache'
# Environment variable injection
$env = New-MsixPsfEnvVarConfig -Variables @{ APP_MODE = 'packaged'; APP_VER = '3' }
# Custom working directory
Add-MsixPsfV2 -PackagePath app.msix `
-Fixups @($frf, $env) `
-WorkingDirectory 'VFS/ProgramFilesX64/App/' `
-Pfx cert.pfx -PfxPassword $pwModern File Redirection (MFR — TMurgent fork, ILV-aware):
$rule = New-MsixMfrTraditionalRule -KnownFolder 'ProgramFilesX64' `
-RelativePath 'Contoso/logs' -Patterns '.*\.log' -Cow enablePe
$mfr = New-MsixPsfMfrConfig -TraditionalRules @($rule) -GlobalIlvAware $true
Add-MsixPsfV2 -PackagePath app.msix -Fixups @($mfr) -Pfx cert.pfx -PfxPassword $pwFour backends, all accepting [SecureString] for any secret:
$pw = Read-Host -AsSecureString
# Local signtool + PFX (emits Write-Warning about cmdline exposure)
Invoke-MsixSigning -PackagePath app.msix -Pfx cert.pfx -PfxPassword $pw
# Safe local PFX (SignerSignEx): the password loads the cert in-process and
# signtool signs by thumbprint — the password/PFX path never hit the cmdline.
Invoke-MsixSigning -PackagePath app.msix -Signer SignerSignEx -Pfx cert.pfx -PfxPassword $pw
# Azure Trusted Signing (recommended for production)
Invoke-MsixSigning -PackagePath app.msix -Signer TrustedSigning `
-TrustedSigningAccount 'contoso' -TrustedSigningProfile 'Code Signing' `
-TrustedSigningEndpoint 'https://weu.codesigning.azure.net'
# Azure Key Vault via AzureSignTool
Invoke-MsixSigning -PackagePath app.msix -Signer AzureSignTool `
-KeyVaultUrl 'https://my-vault.vault.azure.net' `
-KeyVaultCertificate 'my-cert' `
-KeyVaultClientId $spId -KeyVaultClientSecret $spSecretGenerate, sign, and inject deployment-toolkit-style PowerShell scripts as PSF
startScript / endScript entries. Customer-specific values are baked in at
generation time.
$pw = Read-Host -AsSecureString
# See bundled templates
Get-MsixStandardScript | Format-Table Name, Description
# Generate + sign (no package touched)
New-MsixStandardScript -Name CreateShortcut `
-Parameters @{ DisplayName = 'Contoso'; Target = 'contoso.exe' } `
-OutputPath C:\src\createshortcut.ps1 `
-Pfx cert.pfx -PfxPassword $pw
# Generate + sign + inject into MSIX in one step
Add-MsixStandardScript -PackagePath app.msix -AppId 'App' `
-Name CreateShortcut `
-Parameters @{ DisplayName = 'Contoso'; Target = 'contoso.exe' } `
-RunOnce -WaitForScriptToFinish `
-Pfx cert.pfx -PfxPassword $pw
# Sign any script with the same cert
Set-MsixScriptSignature -ScriptPath my-script.ps1 -Pfx cert.pfx -PfxPassword $pwBundled templates: CreateShortcut, CopyIconToAppData, CleanupOldUserData,
RegisterFileAssociation, CustomerSettingsBootstrap.
Opt-in AppContainer isolation. The actual isolation switch is the AppContainer
trust level on a partial-trust entry point — Add-MsixAppIsolation sets, on
each <Application>:
EntryPoint="Windows.PartialTrustApplication"(the full-trust entry point hard-requiresrunFullTrust, which keeps the process full-trust — so it could never isolate);TrustLevel="appContainer"; and- removes
runFullTrust(incompatible with AppContainer; the partial-trust entry point doesn't need it).
Two modes:
-Mode |
Manifest | Status | Behavior |
|---|---|---|---|
| AppContainer (default) | uap10:RuntimeBehavior="packagedClassicApp" |
GA (Win10 2004+) | ungranted access denied |
| AppSilo | uap18:RuntimeBehavior="appSilo" + uap18:EntryPoint="Isolated.App" + isolatedWin32-* |
preview (Win11 24H2) | access brokered (consent prompts); raises MinVersion to 26100 |
-Capabilities are standard package capabilities in AppContainer mode (default:
none — strictest) and isolatedWin32-* / device capabilities in AppSilo mode
(default: isolatedWin32-promptForAccess).
$pw = Read-Host -AsSecureString
Get-MsixIsolationCapability # rich objects: Name / ElementType / Description (AppSilo caps)
# GA AppContainer (strict): app runs in an AppContainer, ungranted access denied.
Add-MsixAppIsolation -PackagePath app.msix -Pfx cert.pfx -PfxPassword $pw
# ... grant specific access:
Add-MsixAppIsolation -PackagePath app.msix -Capabilities internetClient -Pfx cert.pfx -PfxPassword $pw
# Win32 App Isolation silo (preview) with the file-access broker:
Add-MsixAppIsolation -PackagePath app.msix -Mode AppSilo -Pfx cert.pfx -PfxPassword $pw
Remove-MsixAppIsolation -PackagePath app.msix -Pfx cert.pfx -PfxPassword $pw # restores full trustTwo things that can't be isolated (the cmdlet warns/throws) — with escape hatches:
- PSF packages (
PsfLauncher*.exeentry point) — PSF injects fixup DLLs into the target process, which AppContainer blocks. RunRemove-MsixPsffirst: it restores the real executable from config.json and strips the PSF payload (warning about every behaviour that disappears with it). windows.comServerextensions (e.g. a COM shell context-menu like NppShell) — invalid with a partial-trust entry point. Pass-RemoveComServerto strip the COM server and its Explorer context-menu verbs (that functionality is lost).
Verify and tune with the isolation toolkit:
# Would this package isolate? (static manifest verdict with reasons)
Test-MsixIsolation -PackagePath app-isolated.msix
# Is the RUNNING app actually in an AppContainer? (token check: S-1-15-2 SID)
Test-MsixIsolation -PackageFamilyName 'MyApp_abc123def' # or -ProcessId <pid>
# Which capabilities does the app need? Trace it, then map the denials:
$pml = Invoke-MsixProcMonCapture -ScriptBlock { <# drive the app #> }
Get-MsixProcMonFailure -PmlPath $pml | Get-MsixIsolationAdvice -Mode AppSiloValidate first. Many legacy apps break under isolation because they expect broad filesystem/registry access. Prompts alone are NOT proof of isolation (ASR rules also prompt) — only the
S-1-15-2AppContainer SID is (Test-MsixIsolation). The AppSilo layer is a preview feature; if its brokering doesn't engage on a given build the app still runs in the AppContainer (access denied rather than prompted). SeeTEST-PLAN.mdScenario 6.
Invoke-MsixPipeline supports AppIsolation as a first-class config key —
applied in the same unpack/repack/sign pass as publisher updates and PSF
injection.
Alternatives to PSF for symptoms the modern manifest schema handles natively (faster, no foreign DLLs, survives Windows updates cleanly):
| Cmdlet | Schema | Min OS | Replaces |
|---|---|---|---|
Set-MsixFileSystemWriteVirtualization |
desktop6 | 19041 | PSF FileRedirection (broad) |
Set-MsixRegistryWriteVirtualization |
desktop6 | 19041 | RegLegacy Hklm2Hkcu (broad) |
Set-MsixInstalledLocationVirtualization |
uap10 | 19041 | FRF + update-time policy |
Add-MsixLoaderSearchPathOverride |
uap6 | 17134 | DynamicLibraryFixup |
Add-MsixFirewallRule |
desktop2 | 15063 | post-install netsh |
Add-MsixStartupTask |
uap5 | 15063 | HKLM/HKCU \Run keys |
Add-MsixProtocolHandler |
uap | any | host-side protocol script |
Add-MsixFileTypeAssociation |
uap | any | host-side FTA script (now with -Logo/-InfoTip/EditFlags/-Verbs) |
Add-MsixService |
desktop6 | 19041 | services the capture's installer registered (agents/updaters/licensing) |
Add-MsixShellHandlerExtension |
desktop2 | 15063 | preview/property/thumbnail shell handlers from the registry |
Add-MsixToastActivator |
desktop + com | 16299 | toast click re-activation |
Add-MsixPackageDependency |
foundation | any | bundling framework DLLs (VCLibs, WindowsAppRuntime as <PackageDependency>) |
Set-MsixMutablePackageDirectory |
desktop6 | 18362 | plugin/mod folders via %ProgramFiles%\ModifiableWindowsApps |
Add-MsixPackageCertificate |
foundation | any | the capture's certutil step (windows.certificates, per-package store) |
Add-MsixAppExtensionHost / Add-MsixAppExtension |
uap3 | 14393 | ad-hoc plugin folder drops (AppExtensionCatalog contract) |
Add-MsixAutoPlayHandler |
uap | any | AutoPlay registry handlers |
Add-MsixShareTarget |
uap | any | Share-sheet integration |
Add-MsixFullTrustProcess |
desktop | 14393 | UWP-main + Win32-companion pattern |
Scanners feed these into Invoke-MsixInvestigation findings and
Invoke-MsixAutoFixFromAnalysis planning: Get-MsixServiceEntry,
Get-MsixShellHandlerEntry, Get-MsixPackageCertificateCandidate
(certificate declaration is opt-in via -DeclarePackageCertificates +
-PackageCertificateStore — installing a certificate is a trust decision).
Distribution (after post-processing): New-MsixAppInstallerFile generates
a .appinstaller with the full auto-update policy; New-MsixModificationPackage
builds a uap4:MainPackageDependency customization package that layers
settings/plugins onto a vendor MSIX without touching it.
Multi-arch bundles: New-MsixBundle / Expand-MsixBundle /
Get-MsixBundleInfo wrap MakeAppx bundle operations, and
Invoke-MsixBundleOperation applies any mutator to each inner package
(unbundle → mutate → rebundle → sign) so the whole toolkit works on
.msixbundle inputs, not just single .msix files.
Localization repair: Update-MsixResourcePri regenerates resources.pri
via makepri, and Set-MsixBrandMetadata -RegeneratePri makes brand edits on
ms-resource:-localized packages actually take effect at runtime.
Shared runtime frameworks: stop bundling a JRE into every app.
New-MsixFrameworkPackage packages a runtime once as a <Framework> package;
Add-MsixRuntimeDependency wires each consumer (<PackageDependency> +
optional JAVA_HOME/DOTNET_ROOT env wiring). Get-MsixBundledRuntime
detects private runtime copies in captures, and autofix can strip + rewire
them (opt-in, explicit framework identity).
Modification packages: New-MsixModificationPackage layers files AND
settings (-RegistryContent builds Registry.dat/User.dat) onto a vendor
MSIX without touching it; ConvertTo-MsixModificationPackage productizes the
delta between a vendor package and a customized copy automatically.
Static analysis says whether a package should work; Test-MsixDeployment
proves whether it does. It installs a signed package into a clean Hyper-V VM
over PowerShell Direct (no VM networking), launches it via shell:AppsFolder,
and probes liveness — returning a verdict object shaped like the other
Test-Msix* results, with the event-log artifacts wired to feed the
analyze → autofix loop.
$cred = Get-Credential
Test-MsixDeployment -PackagePath app.msix -VMName 'Win11-24H2' `
-Credential $cred -CertPath app.cer -Checkpoint 'clean'
# -> Passed / Reasons / ProcessAlive / CrashDetected / EventLogArtifactsInvoke-MsixPipeline applies every requested stage to a single workspace,
then signs once at the very end. Atomic: if signing fails, the original
target is never overwritten — the unsigned scratch package is preserved at
UnsignedOutputPath for manual re-sign.
$pw = Read-Host -AsSecureString
Invoke-MsixPipeline -PackagePath app.msix -OutputPath app-fixed.msix -Config @{
Publisher = 'CN=Contoso, O=Contoso, C=NL'
PSF = @{
Fixups = @( New-MsixPsfFileRedirectionConfig -Base 'logs' -Patterns '.*\.log' )
WorkingDirectory = 'VFS/ProgramFilesX64/Contoso/'
}
AppIsolation = @{
Capabilities = 'isolatedWin32-promptForAccess', 'isolatedWin32-userProfileMinimal'
}
Signing = @{
Pfx = 'cert.pfx'
PfxPassword = $pw
UnsignedOutputPath = 'C:\drop\app-unsigned-fallback.msix'
}
}# VHDX — auto-sized, NTFS, optional ACLs
New-MsixAppAttachImage -PackagePath app.msix -OutputPath app.vhdx
# CIM — no Hyper-V required
New-MsixAppAttachImage -PackagePath app.msix -OutputPath app.cim -FileType cim
# Multiple packages into one image
New-MsixAppAttachImage -PackagePath @('a.msix','b.msix') -OutputPath bundle.vhdx -SizeGB 4
Test-MsixAppAttachImage -ImagePath app.vhdx# Legacy IContextMenu COM shell extension (com + desktop4/desktop5, Win10 1809+ / build 17763+).
# Emits the com:SurrogateServer registration AND the desktop4:FileExplorerContextMenus
# verb in one call — the field-verified pattern Explorer actually activates.
Add-MsixLegacyContextMenu -PackagePath app.msix `
-ShellExtDll 'VFS\ProgramFilesX64\App\ShellExt.dll' `
-Clsid 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' `
-DisplayName 'My Context Menu' `
-FileTypes '*', '.log', 'Directory' `
-Pfx cert.pfx -PfxPassword (Read-Host -AsSecureString)
# Modern IExplorerCommand (desktop4, recommended for new extensions)
Add-MsixFileExplorerContextMenu -PackagePath app.msix `
-AppId 'App' -VerbId 'open' -VerbClsid '{XXXXXXXX-…}' `
-FileTypes '.txt', '.log'
# Alternative classic-handler schema (-Schema desktop9|Both): the MS-documented /
# commercial-tool shape (windows.fileExplorerClassicContextMenuHandler).
# Win11 21H2+ only; appears in the CLASSIC menu ("Show more options").
Add-MsixLegacyContextMenu -PackagePath app.msix -Schema Both `
-ShellExtDll 'VFS\ProgramFilesX64\App\ShellExt.dll' `
-Clsid 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' -DisplayName 'My Context Menu'# Spin up Windows Sandbox with the broken package + this module pre-loaded
$cfg = New-MsixSandboxConfig -DropFolder 'C:\drop' -PackageName 'broken.msix'
Start-MsixSandbox -ConfigPath $cfg
# Inside the sandbox the LogonCommand auto-runs Start-MsixDebugSession which:
# - Runs Invoke-MsixInvestigation (static)
# - Prints numbered copy-paste-ready fix commands (saved to recommended-commands.ps1)
# - Optionally installs the package, opens Procmon + DebugViewAll functions are non-interactive — no Read-Host, no PromptForChoice.
Import-Module .\MSIX\MSIX.psd1 -Force
Initialize-MsixToolchain | Out-Null
$report = Invoke-MsixInvestigation -PackagePath $env:BUILD_OUTPUT
if ($report.Findings | Where-Object Severity -eq 'Error') {
throw 'Compatibility errors detected — aborting.'
}
Invoke-MsixPipeline -PackagePath $env:BUILD_OUTPUT -OutputPath $env:BUILD_FIXED `
-Config @{
PSF = @{ Fixups = $report.SuggestedFixups }
Signing = @{
Signer = 'TrustedSigning'
TrustedSigningAccount = $env:TS_ACCOUNT
TrustedSigningProfile = $env:TS_PROFILE
TrustedSigningEndpoint = $env:TS_ENDPOINT
}
}Pester v5 tests under MSIX.Tests\. 500+ tests cover pure functions, manifest
transforms, XML security (XXE / billion-laughs rejection), secret non-leakage,
input validation, idempotency, and the module export contract — plus
Integration-tagged tests that pack real .msix fixtures via MakeAppx (skipped
when the SDK toolchain isn't present). A coverage-map guardrail asserts every
mutating cmdlet is exercised by a test.
Install-Module Pester -MinimumVersion 5.5 -Scope CurrentUser
# All tests
.\MSIX.Tests\Invoke-MsixTests.ps1
# By tag
.\MSIX.Tests\Invoke-MsixTests.ps1 -Tag Security
.\MSIX.Tests\Invoke-MsixTests.ps1 -Tag Manifest,BuildersCI runs PSScriptAnalyzer (Error + Warning) and Pester on every push / PR via
.github/workflows/ci.yml. Releases publish to PSGallery via
.github/workflows/publish.yml.
Shared runtime frameworks (#130) — package a JRE/.NET/Python runtime ONCE
as a <Framework> package (New-MsixFrameworkPackage) and wire any number of
apps to it (Add-MsixRuntimeDependency: dependency + optional
JAVA_HOME/DOTNET_ROOT env wiring). Get-MsixBundledRuntime finds private
runtime copies in captures; autofix can strip + rewire them (opt-in, explicit
framework identity).
Modification packages completed (#131) — New-MsixModificationPackage -RegistryContent layers HKLM/HKCU settings (built into
Registry.dat/User.dat), and ConvertTo-MsixModificationPackage
productizes the delta between a vendor package and a customized copy.
Test-MsixDeployment -ModificationPackagePaths probes main + mods together.
From 0.72 (source-only, first published here):
.msixbundlesupport —New-MsixBundle/Expand-MsixBundle/Get-MsixBundleInfo, andInvoke-MsixBundleOperationto run any mutator against each inner package (unbundle → mutate → rebundle → sign, atomic).- resources.pri regeneration —
Update-MsixResourcePri+Set-MsixBrandMetadata -RegeneratePrimake brand edits onms-resource:-localized packages actually take effect. - Runtime deployment testing —
Test-MsixDeploymentdeploys into a clean Hyper-V VM over PowerShell Direct, launches, probes, and returns a verdict whose artifacts feed the analyze → autofix loop. - In-process signing —
Invoke-MsixSigning -Signer SignerSignExsigns by thumbprint with the certificate loaded in-process: no PFX password or path on any command line.
Earlier in the 0.71 line: the App Isolation rework (partial-trust
AppContainer/AppSilo that provably isolates), the isolation toolkit
(Remove-MsixPsf, Test-MsixIsolation, Get-MsixIsolationAdvice), packaged
services, shell handlers, toast activators, package dependencies/certificates,
distribution (.appinstaller), and the module-wide Get-Help repair.
The full per-version history lives in CHANGELOG.md.
This module is free to use, modify, and build on — including commercially, inside your own organisation, and as part of your own packaging workflows. It is licensed under the PolyForm Shield 1.0.0 license.
In plain English: do whatever you like with it, with one exception — you may not use it to build a product that competes with this module (for example, folding it into a rival MSIX-packaging tool or service). If that's what you're after, get in touch and we'll talk about a separate commercial license.
PolyForm Shield is a source-available license, not an OSI open-source license — that single competitive carve-out is the only difference from a permissive license like Apache-2.0. Contributions are welcome under the same terms (see CONTRIBUTING.md).
Third-party binaries: PSF binaries fetched at runtime remain the property of their respective owners (Microsoft / Tim Mangan / TMurgent Technologies). This module does not redistribute any binaries — it downloads them on demand from the authors' official release channels and verifies Authenticode signatures before use.