Skip to content
Rod Christiansen edited this page Sep 5, 2026 · 2 revisions

FAQ

Questions that come up repeatedly, answered against what the Windows code actually does. Where an answer contradicts something you read in the README or an example file, this page is the one derived from the source.

How is this different from BootstrapMate for macOS?

They share the concept, the manifest vocabulary and the page names in these wikis; they share no code. The Windows build has two phases, setupassistant and userland, and calls that field a phase where macOS calls it a stage and adds a preflight stage. On Windows both phases run back to back in one SYSTEM process, so userland items do not run in a user's session — on macOS userland genuinely waits for one. Verification differs too: Windows uses Authenticode via WinVerifyTrust on MSI and EXE items only. Start at https://github.com/bootstrapmate/bootstrapmate-macintosh/wiki for the macOS behaviour.

Does BootstrapMate replace Cimian?

No. It is a provisioning tool with a beginning and an end. It downloads a manifest, installs what the manifest lists, writes its status and exits. It has no desired-state model, no version comparison, no uninstall, no catalogs and no scheduling beyond re-running the same manifest daily. The normal reason to run it is to get Cimian onto a device early enough to matter, then let Cimian do the ongoing work. See Handoff to Cimian.

What happens if a package fails?

The failure is logged as Failed to install package {name}: {msg}, the downloaded file is kept in C:\ProgramData\ManagedBootstrap\cache for you to inspect, and the run continues to the next item. Nothing aborts, nothing rolls back, and no later item is skipped as a consequence. MSI items get retried first — up to 5 attempts for a normal MSI, on exit codes 1603, 1619, 1620 and 1612 only. PowerShell, EXE, sbin-installer and Chocolatey items are not retried at all: the first non-zero exit fails the item.

Why did the run exit 0 when nothing installed?

Because per-item failures are caught deliberately so the run can continue, and the exit code reflects only whether the run completed. That has not changed: a run in which every single item failed still exits 0. The exit code is not a package-health signal.

Everything else about the run is, though. Failed packages mark their phase Failed with the names in LastError, the log ends BootstrapMate completed with N failed package(s), LastRunVersion is not written, and the reporting POST carries success: false. To judge a run, count Failed to install package lines in the newest bootstrap.log, check for LastRunVersion, and check whether C:\ProgramData\ManagedBootstrap\cache is empty — any file left there is a failed install.

Is there hash or signature verification of downloads?

Signature verification, yes. Hash verification, no. MSI and EXE items are checked with WinVerifyTrust before they run, and that is on by default (VerifyPackageSignatures). You can require a specific signer with ExpectedPublisher, permit untrusted binaries with AllowUnsigned, and override both per item. A publisher mismatch is refused even when AllowUnsigned is set. Revocation checking is deliberately disabled, because OCSP and CRL are unreliable during OOBE. ps1, nupkg and pkg items are not signature-gated at all. There is no SHA256 or other content-hash check — a hash field appears in the shipped example manifest but nothing reads it. Serve manifests and packages over HTTPS and treat that as your integrity boundary. See Security and Package Verification.

Does BootstrapMate reboot the device?

No. There is no reboot handling of any kind: no pending-reboot detection, no resume after a restart, no state carried across one. Every MSI is invoked with /norestart. A Reboot setting exists in the configuration model and in the policy template, but nothing in the CLI reads it — turning it on does nothing. If an installer you ship reboots the machine on its own, the rest of the run is lost and the daily task picks it up the next night.

Can it run again later, and is it safe to re-run?

Yes, and re-running is the design. The MSI registers a scheduled task named BootstrapMate Self-Heal that runs daily at 03:00 as SYSTEM with --force --silent --no-dialog, re-processing the whole manifest. There is no "already done" short-circuit, so every item is downloaded and installed again on every run — your installers need to tolerate that. You can also invoke it by hand at any time from an elevated prompt. Only one run happens at a time: a second invocation waits on a global mutex for up to 30 minutes.

How do I tell what version is installed, and what version last ran?

They are two different values under two different registry roots, and the distinction matters.

For the CLI's own build version, run it as the first argument — -V and --version are only honoured in position 0:

managedbootstrapinstall.exe --version

The MSI records what it installed under HKLM\SOFTWARE\BootstrapMate as Version, alongside InstallPath, InstallDate and Architecture. That value is in the MSI's own version format, which is not identical to the release tag. The version that last completed a run is separate:

Get-ItemProperty 'HKLM:\SOFTWARE\Cimian\BootstrapMate' -Name LastRunVersion

Which registry key should my Intune detection script actually check?

Decide what you are detecting. To detect that the MSI is installed, read Version under HKLM\SOFTWARE\BootstrapMate — that is what the MSI writes. To detect that a bootstrap run completed, read LastRunVersion under HKLM\SOFTWARE\Cimian\BootstrapMate. It is written only when every package in the run installed, so a device that keeps failing keeps failing detection and keeps being retried.

Do not copy the detection scripts in the repository's examples/detection-scripts directory as they stand. They read LastRunVersion from HKLM\SOFTWARE\BootstrapMate — the MSI's root, not the run's — and compare it against a version string hard-coded in the script, so out of the box they report a mismatch and retrigger the install. They also report diagnostics from status keys that nothing writes.

Why do I need to check the registry at all — isn't that what --status is for?

--status reads HKLM\SOFTWARE\BootstrapMate, which is the MSI's root, not the root StatusManager writes to. Its completion line therefore reflects the MSI install rather than a completed run, and the registry and status-file paths it prints are wrong. --clear-status is worse: it deletes a status key nothing writes and a status file nothing creates, leaving the real ones untouched — it is effectively a no-op. Query HKLM\SOFTWARE\Cimian\BootstrapMate\Status\SetupAssistant and ...\Userland directly instead.

Why are my package downloads failing with Download failed: Forbidden?

Almost always the Authorization header. BootstrapMate attaches a configured header to a package download only when the package URL's host matches the manifest URL's host, and logs Authorization header withheld for cross-host download at Debug when it does not. That restriction exists because some public object stores return 403 for a public object carrying an Authorization header they cannot validate. If your packages live on a different host from your manifest and genuinely need authentication, that combination is not supported — put the credential in the URL's own scheme, or host them together. See Serving Manifests and Packages.

Why won't the ADMX template import into Intune or Group Policy?

Both resources/BootstrapMate.admx and resources/en-US/BootstrapMate.adml are malformed XML — each has an unclosed element — so ADMX ingestion and a copy into C:\Windows\PolicyDefinitions will both fail. The underlying policy values still work if you write them directly to HKLM\SOFTWARE\Policies\BootstrapMate, by OMA-URI or by a plain registry write. See Preferences.

I set DryRun. Why did it install things anyway?

Because DryRun is not implemented. It exists in the configuration model, in the policy template and in the GUI, and the CLI ignores it. The same is true of FollowRedirects, Reboot, NetworkTimeout and DialogIcon — all configurable, none read by the CLI's execution path. This is a known gap, listed on Troubleshooting and Gotchas. Do not use a dry run to make a change safely; test on a device you can rebuild.

Where are the logs, and how long do they last?

One directory per run, C:\ProgramData\ManagedBootstrap\logs\yyyy-MM-dd\HHmmss\ in local time, holding bootstrap.log (the human log), events.jsonl (the same lines as JSON records) and session.json (the run's metadata). At the start of each run, day directories older than 30 days are deleted, all but the newest 100 session directories are deleted, and any flat *.log left at the logs root by the older layout whose last-write time is more than 30 days old is deleted too. bootstrap.log always contains everything including Debug lines, regardless of --silent or --verbose — those flags only affect console output. See Logging and Reporting.

See also

Clone this wiki locally