Skip to content

Example Manifests

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

Example Manifests

Three complete manifests you can copy, change the URLs in, and run. Every key used here is one the parser actually reads; see the Manifest Reference for the full list and Item Types for what each type does.

The manifest shipped in the repository at examples/bootstrapmate.json is not runnable as written — its first entry has displayname but no name, and a missing name on any entry throws before the first install. Start from one of these instead.

Minimum viable

One package, one phase. This is the manifest to use for a first run on a test device: it proves the URL is reachable, the file downloads, and the install path works, without anything else in the way.

{
  "setupassistant": [
    {
      "name": "Management Agent",
      "url": "https://example.com/bootstrap/packages/ManagementAgent.msi",
      "file": "ManagementAgent.msi",
      "type": "msi"
    }
  ]
}

userland is omitted, which records that phase as Skipped and moves on. Run it with:

& 'C:\Program Files\BootstrapMate\managedbootstrapinstall.exe' --url https://example.com/bootstrap/minimal.json --verbose --no-dialog

A provisioning manifest for Autopilot

A realistic first-boot manifest for a device coming through Autopilot and the Enrollment Status Page (ESP). The shape of it is: get the installer helper down first, then the ongoing management agent, then the runtime and the architecture-specific payload, and finish with a script that starts the handoff.

Both phases run back to back in the same process, as SYSTEM, so treat the split as ordering plus separate status reporting rather than as two environments — see Stages.

{
  "setupassistant": [
    {
      "name": "System Binary Installer",
      "url": "https://example.com/bootstrap/packages/sbin-installer-1.4.0.msi",
      "file": "sbin-installer-1.4.0.msi",
      "type": "msi",
      "expectedPublisher": "Example Organisation"
    },
    {
      "name": "Cimian",
      "url": "https://example.com/bootstrap/packages/Cimian-2026.09.01.msi",
      "file": "Cimian-2026.09.01.msi",
      "type": "msi",
      "expectedPublisher": "Example Organisation"
    },
    {
      "name": "Visual C++ Redistributable (x64)",
      "url": "https://example.com/bootstrap/packages/VCRedist-x64.exe",
      "file": "VCRedist-x64.exe",
      "type": "exe",
      "arguments": ["/install", "/quiet", "/norestart"],
      "condition": "architecture_x64"
    },
    {
      "name": "Visual C++ Redistributable (arm64)",
      "url": "https://example.com/bootstrap/packages/VCRedist-arm64.exe",
      "file": "VCRedist-arm64.exe",
      "type": "exe",
      "arguments": ["/install", "/quiet", "/norestart"],
      "condition": "architecture_arm64"
    }
  ],
  "userland": [
    {
      "name": "Corporate Root Certificates",
      "url": "https://example.com/bootstrap/packages/RootCerts.msi",
      "file": "RootCerts.msi",
      "type": "msi",
      "expectedPublisher": "Example Organisation"
    },
    {
      "name": "Start Ongoing Management",
      "url": "https://example.com/bootstrap/scripts/start-management.ps1",
      "file": "start-management.ps1",
      "type": "ps1",
      "arguments": ["-Environment", "Production"]
    }
  ]
}

Four things in that manifest are worth pointing at.

The installer helper is named System Binary Installer, which is one of the names that select the ten-attempt, retry-on-any-error MSI policy in Retries and Timeouts. That naming is load-bearing, not decorative.

The two redistributables are the same item twice, gated by condition, because condition only understands architecture_x64 and architecture_arm64. On an x64 device the arm64 entry logs a [SKIPPED] line and nothing else happens. See Conditions and Skipping.

The script is named Start Ongoing Management rather than something like "Clean up and start management". A ps1 item whose name contains cleanup, clean, wipe, remove, delete, purge, nuclear or maintenance is moved to the end of its phase automatically, which is rarely what you meant.

And the script must exit 0 when it has nothing to do. A non-zero exit is the only failure signal for a ps1 item, so a script that ends on a stray error code reports a failed item even though provisioning worked.

Every installer type side by side

A reference manifest rather than a deployment one, showing all five types and the optional keys that apply to each. Note the asymmetry: arguments reaches every type, target only reaches the sbin-installer paths, and expectedPublisher and allowUnsigned only apply to msi and exe, because those are the only types Authenticode-verified.

{
  "setupassistant": [
    {
      "name": "Vendor Suite",
      "url": "https://example.com/bootstrap/packages/VendorSuite.msi",
      "file": "VendorSuite.msi",
      "type": "msi",
      "arguments": ["ALLUSERS=1", "DESKTOPSHORTCUT=0"],
      "expectedPublisher": "Vendor Software Inc"
    },
    {
      "name": "Legacy Driver Package",
      "url": "https://example.com/bootstrap/packages/LegacyDriver.exe",
      "file": "LegacyDriver.exe",
      "type": "exe",
      "arguments": ["/S", "/norestart"],
      "allowUnsigned": true
    },
    {
      "name": "Internal Tooling",
      "url": "https://example.com/bootstrap/packages/InternalTooling-3.2.1.nupkg",
      "file": "InternalTooling-3.2.1.nupkg",
      "type": "nupkg",
      "target": "/"
    },
    {
      "name": "Legacy Payload",
      "url": "https://example.com/bootstrap/packages/LegacyPayload-1.0.0.pkg",
      "file": "LegacyPayload-1.0.0.pkg",
      "type": "pkg",
      "target": "/"
    }
  ],
  "userland": [
    {
      "name": "Configure Workstation",
      "url": "https://example.com/bootstrap/scripts/configure-workstation.ps1",
      "file": "configure-workstation.ps1",
      "type": "ps1",
      "arguments": ["-Verbose"]
    }
  ]
}

allowUnsigned on the driver package permits an installer whose Authenticode signature does not verify; it does not permit a signature from the wrong publisher, which is refused either way. The nupkg and pkg entries both need sbin-installer on the device — without it, pkg fails outright and nupkg falls through to Chocolatey, which will install Chocolatey from the internet if it is not already present.

The same manifest in YAML, if you would rather maintain it that way, is the same keys and the same values; serve it from a URL ending .yaml or .yml.

See also

Clone this wiki locally