Files
windows-builder/includes/utils/ResignMSIX.ps1
2026-06-02 03:37:09 -07:00

106 lines
4.3 KiB
PowerShell

# =============================
# General MSIX / APPX / Bundle Auto Re-Sign Script
# =============================
param(
[Parameter(Mandatory=$true)]
[string]$PackagePath, # Input MSIX/APPX/BUNDLE
[string]$CertificateThumbprint = "", # Optional: Store cert thumbprint
[string]$PfxPath = "", # Optional: PFX file path
[string]$PfxPassword = "", # Optional: PFX password
[string]$OutputFolder = "" # Optional: output folder
)
# -----------------------------
# 1. Validate paths
# -----------------------------
if(-not (Test-Path $PackagePath)){ throw "Package file not found." }
$PackageExt = [IO.Path]::GetExtension($PackagePath).ToLower()
if($OutputFolder -eq ""){ $OutputFolder = Join-Path (Split-Path $PackagePath) "Resigned" }
if(-not (Test-Path $OutputFolder)){ New-Item -ItemType Directory -Path $OutputFolder | Out-Null }
# Detect SignTool.exe
$SignToolPaths = @(
"$env:ProgramFiles(x86)\Windows Kits\10\bin",
"$env:ProgramFiles\Windows Kits\10\bin",
"$env:ProgramFiles(x86)\Windows Kits\11\bin",
"$env:ProgramFiles\Windows Kits\11\bin"
)
$SignTool = $null
foreach($p in $SignToolPaths){
$st = Get-ChildItem -Path $p -Recurse -Filter "signtool.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
if($st){ $SignTool = $st.FullName; break }
}
if(-not $SignTool){ throw "SignTool.exe not found. Install Windows 10/11 SDK." }
Write-Host "Using SignTool: $SignTool"
# -----------------------------
# 2. Prepare temp folder
# -----------------------------
$TempDir = Join-Path $env:TEMP "Package_ReSign"
if(Test-Path $TempDir){ Remove-Item $TempDir -Recurse -Force }
New-Item -ItemType Directory -Path $TempDir | Out-Null
# -----------------------------
# 3. Handle single package vs bundle
# -----------------------------
$PackagesToSign = @()
switch($PackageExt){
".appx" { Copy-Item $PackagePath $OutputFolder; $PackagesToSign += Join-Path $OutputFolder (Split-Path $PackagePath -Leaf) }
".msix" { Copy-Item $PackagePath $OutputFolder; $PackagesToSign += Join-Path $OutputFolder (Split-Path $PackagePath -Leaf) }
".appxbundle" { makeappx unbundle /p $PackagePath /d $TempDir; $PackagesToSign += Get-ChildItem $TempDir -Recurse -Include *.appx | Select-Object -ExpandProperty FullName }
".msixbundle" { makeappx unbundle /p $PackagePath /d $TempDir; $PackagesToSign += Get-ChildItem $TempDir -Recurse -Include *.msix | Select-Object -ExpandProperty FullName }
default { throw "Unsupported package type: $PackageExt" }
}
# -----------------------------
# 4. Re-sign each package
# -----------------------------
# Get publisher string
if($CertificateThumbprint){
$Cert = Get-ChildItem Cert:\LocalMachine\My\$CertificateThumbprint
if(-not $Cert){ throw "Certificate not found in store." }
$NewPublisher = "CN=$($Cert.Subject -replace '^.*?=','')"
} elseif($PfxPath){
if(-not (Test-Path $PfxPath)){ throw "PFX file not found." }
$Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($PfxPath, $PfxPassword)
$NewPublisher = "CN=$($Cert.Subject -replace '^.*?=','')"
} else {
throw "Provide CertificateThumbprint or PfxPath"
}
Write-Host "Publisher to use: $NewPublisher"
foreach($pkg in $PackagesToSign){
Write-Host "Processing $pkg ..."
# Unpack individual package
$PkgTemp = Join-Path $TempDir ([IO.Path]::GetFileNameWithoutExtension($pkg))
if(-not (Test-Path $PkgTemp)){ New-Item -ItemType Directory -Path $PkgTemp | Out-Null }
makeappx unbundle /p $pkg /d $PkgTemp
# Update AppxManifest.xml
$Manifest = Join-Path $PkgTemp "AppxManifest.xml"
if(Test-Path $Manifest){
[xml]$Xml = Get-Content $Manifest
$Xml.Package.Identity.Publisher = $NewPublisher
$Xml.Save($Manifest)
}
# Repack package
$Ext = [IO.Path]::GetExtension($pkg)
$OutPkg = Join-Path $OutputFolder ((Split-Path $pkg -LeafBase) + "_Resigned" + $Ext)
makeappx bundle /d $PkgTemp /p $OutPkg
# Sign package
if($CertificateThumbprint){
& $SignTool sign /fd SHA256 /a /f "$($Cert.Thumbprint)" $OutPkg
} else {
& $SignTool sign /fd SHA256 /f $PfxPath /p $PfxPassword $OutPkg
}
Write-Host "Resigned package saved: $OutPkg"
}
Write-Host "All packages processed. Output folder: $OutputFolder"