Skip to content

sanderdewit/msix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

224 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MSIX PowerShell Module — v0.73.0

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 the SignTool backend which emits a Write-Warning when this happens).


Table of contents


Why this module

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:


Quick start

The maintainer owns the MSIX name 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-MsixToolchain

Initialize-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


Architecture

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.


Investigation & auto-fix

Static analysis (no install required)

$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.ps1

With Process Monitor (runtime)

Initialize-MsixToolchain
$report = Invoke-MsixInvestigation -PackagePath app.msix -WithProcMon `
    -PackageFamilyName 'Contoso.App_8wekyb3d8bbwe' -AppId 'App' `
    -DurationSeconds 30 -ProcessName 'app.exe'

One-call auto-remediation

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

PSF injection

$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 $pw

Modern 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 $pw

Signing backends

Four 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 $spSecret

Standard scripts (PSADT)

Generate, 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 $pw

Bundled templates: CreateShortcut, CopyIconToAppData, CleanupOldUserData, RegisterFileAssociation, CustomerSettingsBootstrap.


Win32 App Isolation

Opt-in AppContainer isolation. The actual isolation switch is the AppContainer trust level on a partial-trust entry pointAdd-MsixAppIsolation sets, on each <Application>:

  • EntryPoint="Windows.PartialTrustApplication" (the full-trust entry point hard-requires runFullTrust, 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 trust

Two things that can't be isolated (the cmdlet warns/throws) — with escape hatches:

  • PSF packages (PsfLauncher*.exe entry point) — PSF injects fixup DLLs into the target process, which AppContainer blocks. Run Remove-MsixPsf first: it restores the real executable from config.json and strips the PSF payload (warning about every behaviour that disappears with it).
  • windows.comServer extensions (e.g. a COM shell context-menu like NppShell) — invalid with a partial-trust entry point. Pass -RemoveComServer to 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 AppSilo

Validate 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-2 AppContainer 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). See TEST-PLAN.md Scenario 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.


Manifest-only fixers

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.

Runtime deployment testing

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 / EventLogArtifacts

Pipeline orchestrator

Invoke-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'
    }
}

App Attach (VHDX / CIM)

# 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

Context menus

# 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'

Debug & sandbox

# 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 + DebugView

CI/CD

All 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
        }
    }

Tests

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,Builders

CI runs PSScriptAnalyzer (Error + Warning) and Pester on every push / PR via .github/workflows/ci.yml. Releases publish to PSGallery via .github/workflows/publish.yml.


What's new in v0.73

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):

  • .msixbundle supportNew-MsixBundle / Expand-MsixBundle / Get-MsixBundleInfo, and Invoke-MsixBundleOperation to run any mutator against each inner package (unbundle → mutate → rebundle → sign, atomic).
  • resources.pri regenerationUpdate-MsixResourcePri + Set-MsixBrandMetadata -RegeneratePri make brand edits on ms-resource:-localized packages actually take effect.
  • Runtime deployment testingTest-MsixDeployment deploys into a clean Hyper-V VM over PowerShell Direct, launches, probes, and returns a verdict whose artifacts feed the analyze → autofix loop.
  • In-process signingInvoke-MsixSigning -Signer SignerSignEx signs 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.

Release history

The full per-version history lives in CHANGELOG.md.


License

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.

About

Cmdlets to make msix packaging easier

Resources

License

Contributing

Stars

3 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors