-
Notifications
You must be signed in to change notification settings - Fork 1
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.
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.
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.
| 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.
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.
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.
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.
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.
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.
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.
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.