A standalone Windows package builder. Define your package in a build-info.yaml, add payload files and PowerShell scripts, and cimipkg produces signed, versioned .msi or .nupkg packages — no WiX Toolset required.
Prebundled in Cimian for enterprise software deployment.
Building an MSI shouldn't require learning WiX XML schemas and a compiler toolchain. Enterprise environments need signed packages with install scripts, but the existing tooling makes that painful — especially when you're managing dozens or hundreds of packages across an organization.
cimipkg takes the same approach as munkipkg on macOS: a simple directory layout, a build-info manifest, and a single command to build. If you've used munkipkg, this will feel familiar.
The project structure is the source of truth. Keep your package directories in version control and you have a complete, auditable library of every management package your team has built — not just the binaries, but the scripts, metadata, and signing configuration that produced them.
See also the companion pkg-inspector for inspecting the contents of built .msi and .nupkg packages.
Download from Releases (x64 and arm64). Also ships with the CimianTools build.
dotnet publish -c Release -r win-x64
dotnet publish -c Release -r win-arm64# Create a new project scaffold
cimipkg --create my-package
# Build an MSI (default)
cimipkg my-package
# Build with verbose output
cimipkg --verbose my-packagemy-package/
├── build-info.yaml # Package metadata (required)
├── payload/ # Files to install (optional)
├── .env # Environment variables for signing + scripts (optional, gitignored)
└── scripts/ # PowerShell install/uninstall scripts (optional)
├── preinstall.ps1 # Runs before payload is copied
├── postinstall.ps1 # Runs after payload is copied
└── uninstall.ps1 # Runs when the package is removed
Scripts are numbered for ordering (preinstall01.ps1, preinstall02.ps1, etc.) and combined into a single action per phase at build time.
product:
name: MyApp
version: 2025.12.09
developer: MyCompany
identifier: com.mycompany.myapp
description: My application package
install_location: C:\Program Files\MyApp
postinstall_action: none
signing_certificate: ${SIGNING_CERT_SUBJECT}
signing_thumbprint: ${SIGNING_CERT_THUMBPRINT}# Optional: explicit UpgradeCode (otherwise derived deterministically from identifier)
upgrade_code: "{GUID}"
# Optional: additional MSI properties
msi_properties:
CUSTOM_PROP: "value"Any scalar field can contain ${NAME} placeholders, resolved in order:
- Built-in tokens:
${TIMESTAMP}(YYYY.MM.DD.HHMM),${DATE},${DATETIME},${version} .envfile in the project directory (or pass--env <path>)- Process environment variables
- Unresolved placeholders are left literal (fail-soft)
# build-info.yaml (committed)
signing_thumbprint: ${SIGNING_CERT_THUMBPRINT}
signing_certificate: ${SIGNING_CERT_SUBJECT}# .env (gitignored)
SIGNING_CERT_THUMBPRINT=1423F241DFF85AD2C8F31DBD70FB597DAC85BA4B
SIGNING_CERT_SUBJECT=YourOrganization Enterprise CertificateCLI flags (--sign-thumbprint, --sign-cert) override anything resolved from YAML or env. The same .env file also injects variables into install/uninstall scripts at build time.
cimipkg <project-directory>
cimipkg --sign-cert "My Certificate" <project-directory>The default output format. Builds native Windows Installer packages via the DTF (WixToolset.Dtf.WindowsInstaller) API — no WiX compiler or msiexec needed at build time.
- Creates MSI tables (Property, Directory, Component, File, Media, Feature, etc.)
- Embeds payload files in a compressed CAB archive
- Converts PowerShell scripts to VBScript custom actions (base64-encoded, chunked — supports scripts of any practical size)
- Authenticode-signs embedded scripts if a signing certificate is configured — the temp
.ps1written at install time already carries a valid signature, preventing EDR/AV false positives - Stores the full
build-info.yamlin theCIMIAN_PKG_BUILD_INFOMSI property for metadata round-trip - Generates a deterministic
UpgradeCodefrom the product identifier (stable across versions) - Signs the MSI with the configured certificate
- Custom actions auto-detect PowerShell 7 (
pwsh.exe) at install time, falling back to PowerShell 5.1 - Scripts should stay 5.1-compatible, but
#Requires -Version 7works when pwsh is installed - The resulting MSI can be installed by
msiexec, MDM systems, or sbin-installer
| Project script | MSI custom action |
|---|---|
preinstall*.ps1 |
Runs before payload copy |
postinstall*.ps1 |
Runs after payload copy |
uninstall.ps1 |
Runs on REMOVE="ALL" |
MSI requires major.minor.build format (0-255, 0-255, 0-65535). Date-based versions are automatically converted: 2026.04.05.1423 becomes 26.4.51423. The original version is preserved in the CIMIAN_FULL_VERSION MSI property.
cimipkg --nupkg <project-directory>Builds Chocolatey-compatible NuGet packages from the same project structure.
| Project script | nupkg file |
|---|---|
preinstall*.ps1 |
chocolateyBeforeModify.ps1 |
postinstall*.ps1 |
chocolateyInstall.ps1 |
uninstall.ps1 |
chocolateyUninstall.ps1 |
Chocolatey limitation: chocolateyBeforeModify.ps1 only runs on upgrade or uninstall — not on fresh install. This is a Chocolatey engine limitation. sbin-installer does not have this limitation and runs it unconditionally.
# Wrap an MSI for Intune
cimipkg --intunewin <project-directory>
# Wrap a nupkg for Intune
cimipkg --nupkg --intunewin <project-directory>Generates .intunewin packages for Microsoft Intune deployment. Works with both .msi and .nupkg output formats. Requires IntuneWinAppUtil.exe on PATH.
For MSI, the .msi is used directly as the setup file. For nupkg, a Chocolatey wrapper Install.ps1 is generated.
The post-build cimiimport prompt is automatically skipped when stdin is non-interactive (CI runners, piped input, IDE run-configs). Use --skip-import to suppress it explicitly in other contexts.
Apache License 2.0 — see LICENSE.