Skip to content

Item Types

Rod Christiansen edited this page Sep 5, 2026 · 1 revision

Item Types

An item's type decides how the downloaded file is executed, which optional keys apply, and what counts as success. Five values are handled: msi, exe, ps1 (with powershell as a synonym), nupkg and pkg. Anything else fails the item with Unsupported package type: {type}. Supported types are: msi, exe, ps1, nupkg, pkg.

type is matched case-insensitively at install time. It is also the main ordering key inside a phase — see Stages.

At a glance

type Executed by Signature gate arguments target Success is
msi msiexec.exe, or sbin-installer for a Cimian-built MSI Yes Appended to the msiexec command Only on the sbin-installer path Exit code 0, with retries
exe The file itself Yes The entire command line No Exit code 0
ps1, powershell powershell.exe No Appended after -File No Exit code 0
nupkg sbin-installer, else Chocolatey No Appended to either command On the sbin-installer path Exit code 0
pkg sbin-installer only No Appended to the command Yes Exit code 0

The Authenticode gate applies only to msi and exe, because those are the file formats WinVerifyTrust can validate. Scripts and the two package formats are not verified at all, so expectedPublisher and allowUnsigned do nothing on them. See Security and Package Verification.

msi

The default path builds:

msiexec.exe /i "<cached file>" /qn /norestart <arguments>

/qn /norestart are always present, so an MSI never shows UI and never restarts the machine on its own. There is no reboot handling anywhere in the tool; a package that needs a reboot gets one when something else reboots the device.

Before each launch, BootstrapMate waits for the global Windows Installer mutex to go idle, and it retries on a defined set of exit codes. This is the most involved behaviour in the tool and it has its own page: Retries and Timeouts.

There is one fork. If the MSI contains the literal CIMIAN_PKG_BUILD_INFO — the marker a Cimian-built package carries — and sbin-installer is present on the machine, the item is handed to sbin-installer instead, and logs Using sbin-installer for Cimian MSI: {file}. Files whose name begins sbin-installer are excluded from that test, so the installer helper itself always goes through msiexec. The detection reads the whole MSI into memory as text, which is worth knowing if you ship very large MSIs.

On the sbin-installer path the retry policy above does not apply and target does.

MSI exit codes

Exit code Treated as Effect
0 Success Item complete
1618 ERROR_INSTALL_ALREADY_RUNNING Scheduling collision, not a failure Waits for the other transaction, retries, and does not consume a retry attempt
1603 ERROR_INSTALL_FAILURE Retryable Retried up to the attempt limit
1619 ERROR_INSTALL_PACKAGE_OPEN_FAILED Retryable Retried up to the attempt limit
1620 ERROR_INSTALL_PACKAGE_INVALID Retryable Retried up to the attempt limit
1612 ERROR_INSTALL_SOURCE_ABSENT Retryable Retried up to the attempt limit
Anything else non-zero Failure Item fails with MSI installer failed with exit code: {n}

The exception is an item recognised as the installer helper — its name contains System Binary Installer or sbin-installer, or its filename contains sbin-installer. Those retry on any non-zero code, not just the four above.

Note that 3010 (reboot required) is not in the retryable set and is not treated as success, so an MSI that returns it fails the item even though it installed.

exe

The cached file is started directly, with arguments joined by spaces as its entire command line. Nothing is added, so you must supply the vendor's own silent switches yourself — there is no equivalent of the automatic /qn. Standard output is logged at Info and standard error at Warning, both prefixed [OUTPUT] {name}: .

A non-zero exit code fails the item with Executable failed with exit code: {n}. There are no retries. Installers that report success with a non-zero code, or that return before their work is done, will be misreported; wrap those in a ps1 item instead.

ps1 and powershell

Both spellings run the same thing:

powershell.exe -ExecutionPolicy Bypass -NoProfile -File "<cached file>" <arguments>

Windows PowerShell, not PowerShell 7, and always elevated with the run's own token. Output is captured the same way as for exe. A non-zero exit code fails the item with PowerShell script failed with exit code: {n}, and the script's own exit code is therefore the only success signal — a script that swallows its errors reports success.

Two gotchas. Scripts are never signature-checked, so a script item is the widest hole in the verification story; host them where you host the manifest. And a script whose name contains cleanup, clean, wipe, remove, delete, purge, nuclear or maintenance is pushed to the end of its phase, regardless of where you put it in the manifest.

nupkg

If sbin-installer is present it handles the package. If not, the log records sbin-installer not found / Using Chocolatey fallback and the item goes to Chocolatey.

The Chocolatey path is a lot of machinery. It resolves the package id and version from the .nuspec inside the .nupkg, falling back to parsing the filename; it checks whether the package is already present to choose between install and upgrade; and it runs the result through powershell.exe against the cache directory as a local source:

choco {install|upgrade} "<id>" --source="<cache dir>" --version="<version>" -y --ignore-checksums --acceptlicense --confirm --force --no-progress --quiet --limit-output <arguments>

If Chocolatey is not installed, or choco --version fails, BootstrapMate installs it from https://community.chocolatey.org/install.ps1 first, which means the fallback path needs internet access to a host you may not have allowed. If it finds a Chocolatey directory whose choco.exe does not work, it runs a destructive cleanup that deletes C:\ProgramData\chocolatey and rewrites the machine PATH to strip every entry containing chocolatey. Watch for Broken Chocolatey detected in the log.

Failure message: Chocolatey {install|upgrade} failed with exit code {n}, with the captured stdout and stderr appended.

pkg

sbin-installer only. If it is not found, the item fails immediately with sbin-installer is required for .pkg packages but was not found. Please install sbin-installer first. The source marks this case for removal, so treat pkg as legacy and prefer msi or nupkg for new work.

The sbin-installer path

Three types can end up here: pkg always, nupkg when it is available, and a Cimian-built msi when it is available. The command is:

installer --pkg "<cached file>" --target <target> <arguments>

target defaults to /. The helper is located by trying, in order, C:\Program Files\sbin\installer.exe, C:\Program Files (x86)\sbin\installer.exe, C:\sbin\installer.exe, C:\Tools\sbin\installer.exe, and finally where.exe installer.exe — accepting a where hit only if its path contains sbin or System Binary, so a Chocolatey shim called installer.exe is not mistaken for it.

A non-zero exit fails the item with sbin-installer install failed with exit code: {n} plus the captured output. Note that on success, sbin-installer's own stdout and stderr are logged at Debug only, so an opaque failure needs a rerun with --verbose.

When the installer never starts

For exe, ps1, nupkg and pkg, the exit-code check sits inside a null guard on the process handle. If the process cannot be started at all, no exception is thrown and the item is reported as installed. Confirm an install landed rather than trusting the item's success line.

Divergence from macOS

The macOS build has a different type set entirely — package, rootscript and userscript — and gates packages on a SHA-256 hash and a Team ID rather than Authenticode. Nothing in the type vocabulary transfers between the two. See https://github.com/bootstrapmate/bootstrapmate-macintosh/wiki/Item-Types.

See also

Clone this wiki locally