Public/Add-MSIXPSFMFRFixup.ps1

function Add-MSIXPSFMFRFixup {
<#
.SYNOPSIS
    Adds MFRFixup, a fix from Tim Mangan, to an MSIX package.

.DESCRIPTION
    Writes an MFRFixup entry into config.json.xml. MFRFixup (Modern File
    Redirection) is a Tim Mangan PSF component that intercepts 30+ Windows
    file-system APIs and handles Copy-on-Write redirection more efficiently
    than the standard FileRedirectionFixup.
    Do not combine MFRFixup with FileRedirectionFixup on the same process entry.

.PARAMETER MSIXFolder
    Path to the expanded MSIX package folder (must contain config.json.xml).

.PARAMETER Executable
    Regex pattern for the process entry. Default: ".*" (all processes).

.PARAMETER IlvAware
    Controls InstalledLocationVirtualization (ILV) awareness.
    $true - assumes the ILV extension is present in AppxManifest; ILV
             handles Copy-on-Write, MFRFixup provides path interception only.
    $false - MFRFixup handles all Copy-on-Write internally (no ILV required).
    Default: $true.

.PARAMETER OverrideCOW
    Controls Copy-on-Write override behaviour. Default: "default".

.EXAMPLE
    Add-MSIXPSFMFRFixup -MSIXFolder "C:\MSIXTemp\MyApp"

.EXAMPLE
    Add-MSIXPSFMFRFixup -MSIXFolder "C:\MSIXTemp\MyApp" -IlvAware $false

.NOTES
    Tim Mangan MFRFixup: https://github.com/TimMangan/MSIX-PackageSupportFramework/wiki/Fixup:-MfrFixup
    https://www.nick-it.de
    Andreas Nick, 2026
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)]
        [System.IO.DirectoryInfo] $MSIXFolder,

        [String] $Executable = '.*',

        [bool] $IlvAware = $true,

        [String] $OverrideCOW = 'default'
    )

    process {
        if (-not (Test-Path $MSIXFolder.FullName -PathType Container)) {
            Write-Error "MSIXFolder not found: $($MSIXFolder.FullName)"
            return
        }

        try { $null = [System.Text.RegularExpressions.Regex]::new($Executable) }
        catch {
            Write-Error "-Executable '$Executable' is not a valid regular expression: $_"
            return
        }

        if ($Script:PsfBasePath -notlike '*TimMangan*') {
            Write-Error "MFRFixup requires Tim Mangan PSF. Run Set-MSIXActivePSFFramework -Framework TimManganPSF first."
            return
        }

        $configXmlPath = Join-Path $MSIXFolder 'config.json.xml'
        if (-not (Test-Path $configXmlPath)) {
            Write-Warning "config.json.xml not found in: $($MSIXFolder.FullName)"
            return
        }

        $conxml = New-Object xml
        $conxml.Load($configXmlPath)

        Initialize-MSIXPSFProcessSection -ConXml $conxml

        # Locate or create the target process node
        $execNode = $conxml.SelectSingleNode("//processes/process/executable[text()='$Executable']")
        if (-not $execNode) {
            $proc = $conxml.CreateElement('process')
            $exec = $conxml.CreateElement('executable')
            $exec.InnerText = $Executable
            $proc.AppendChild($exec) | Out-Null
            $conxml.SelectSingleNode('//processes').AppendChild($proc) | Out-Null
            $execNode = $conxml.SelectSingleNode("//processes/process/executable[text()='$Executable']")
        }
        $processNode = $execNode.ParentNode

        # Skip if MFRFixup already present
        $existing = $processNode.SelectSingleNode("fixups/fixup/dll[text()='MFRFixup.dll']")
        if ($null -ne $existing) {
            Write-Verbose "MFRFixup already configured for '$Executable' — skipped."
            return
        }

        if ($null -eq $processNode.SelectSingleNode('fixups')) {
            $processNode.AppendChild($conxml.CreateElement('fixups')) | Out-Null
        }

        $fixup   = $conxml.CreateElement('fixup')
        $dllEl   = $conxml.CreateElement('dll')
        $dllEl.InnerText = 'MFRFixup.dll'
        $fixup.AppendChild($dllEl) | Out-Null

        $cfgEl  = $conxml.CreateElement('config')
        $ilvEl  = $conxml.CreateElement('ilvAware')
        # Lowercase 'true'/'false' so the XSL can emit a JSON boolean literal
        $ilvEl.InnerText = if ($IlvAware) { 'true' } else { 'false' }
        $cowEl  = $conxml.CreateElement('overrideCOW')
        $cowEl.InnerText = $OverrideCOW
        $cfgEl.AppendChild($ilvEl) | Out-Null
        $cfgEl.AppendChild($cowEl) | Out-Null
        $fixup.AppendChild($cfgEl) | Out-Null

        $processNode.SelectSingleNode('fixups').AppendChild($fixup) | Out-Null

        $conxml.PreserveWhiteSpace = $false
        $conxml.Save($configXmlPath)
        Write-Verbose "MFRFixup.dll added for executable: $Executable (ilvAware=$IlvAware, overrideCOW=$OverrideCOW)"
    }
}