-
Notifications
You must be signed in to change notification settings - Fork 0
Configuration
StartSet reads a single YAML file:
C:\ProgramData\ManagedState\Config.yaml
This is the equivalent of outset's com.github.outset preference domain. There is no registry
configuration, no environment-variable configuration and no MDM-delivered preference channel —
the file is the whole surface. If it is absent or unparseable, StartSet uses defaults and logs the
fact; it does not fail.
Keys are snake_case. Unknown keys are ignored silently (IgnoreUnmatchedProperties), so a typo
does not error — it just does nothing. Check Loaded preferences from … in the session log and
confirm the behaviour you expect actually changed.
| Key | Type | Default | Effect |
|---|---|---|---|
wait_for_network |
bool | true |
Wait for network connectivity before running boot payloads |
network_timeout |
int (seconds) | 180 |
How long to wait for the network |
ignored_network_failure |
bool | false |
Continue anyway when the network wait times out |
verbose |
bool | false |
Raise the log level to Debug |
debug |
bool | false |
Raise the log level to Debug |
log_level |
string | unset | Explicit level; overrides verbose/debug
|
checksum_validation |
bool | false |
Validate payloads against share\checksums.yaml before running |
allowed_extensions |
list | .ps1 .cmd .bat .exe .msi .msix |
Which files in a payload directory count as payloads |
script_timeout |
int (seconds) | 3600 |
Per-payload timeout; the process tree is killed on expiry |
parallel_execution |
bool | false |
Not implemented. Setting it logs a warning; execution stays sequential |
login_delay |
int (seconds) | 0 |
Pause after a logon event before running login payloads |
log_script_output |
bool | true |
Fold payload stdout/stderr into the session log |
ignored_users |
list of strings | [] |
Usernames whose login payloads are skipped entirely |
overrides |
list of strings | [] |
Filenames that re-run even if the run-once ledger says they ran |
Note the key name. It is ignored_network_failure, not ignore_network_failure — the YAML alias
in the model has the -ed. The mis-spelled form is an unmatched property and is ignored, leaving
the default false in place, which means a boot run aborts when the network never arrives.
Accepted values, case-insensitive:
| Value | Serilog level |
|---|---|
debug, verbose
|
Debug |
information, info
|
Information |
warning, warn
|
Warning |
error |
Error |
fatal |
Fatal |
Anything unrecognised falls back to Information. With log_level unset, debug: true or
verbose: true both yield Debug; otherwise the level is Information.
Setting this key replaces the default list rather than adding to it. If you want to restrict
payloads to PowerShell only, list just .ps1; if you want to add an extension you must re-list
the defaults you still want. An extension with no registered processor is discovered but fails
with UnsupportedType, so this list cannot be used to add support for new file types.
Matched case-insensitively against the username passed into the engine — the TargetUserName
from the logon event, or the --user value, or Environment.UserName. This is the bare account
name, not DOMAIN\user. The check short-circuits the entire run for that user: nothing in
login-once, login-every or the privileged login directories executes.
add-ignored-user lowercases what you give it before storing. Use it rather than editing the file
by hand — it writes the file back through the same serializer.
Matched on filename only, case-insensitively — a full path in the list is reduced to its
filename before comparison. An entry causes the payload to skip the run-once check and execute on
every trigger; it does not clear the ledger. To do both, use
remove-override <name> --clear-runonce.
When on, every discovered payload is checked against share\checksums.yaml before execution. A
payload with no recorded checksum passes — absence is not a failure. A payload whose hash no
longer matches its recorded value is skipped with Checksum validation failed.
Record checksums with managedstatekeeper checksum all --record, or add … --checksum when
staging a script. See CLI Reference.
wait_for_network: true
network_timeout: 300
ignored_network_failure: true
log_level: information
log_script_output: true
script_timeout: 1800
login_delay: 15
checksum_validation: false
allowed_extensions:
- .ps1
- .cmd
- .bat
- .exe
- .msi
- .msix
ignored_users:
- kioskuser
- svc_backup
overrides:
- Set-DefaultAppAssociations.ps1
- Map-DepartmentDrives.ps1
parallel_execution: false
verbose: false
debug: falseThe CLI loads the file once at start-up. The service loads it once at start-up too — the preferences service can watch the file and raise a change event, but the service host does not enable that watcher, so edits do not take effect in the running service. Restart it:
Restart-Service StartSetCommands that write configuration (add-ignored-user, remove-ignored-user, add-override,
remove-override) rewrite the whole file through the YAML serializer. Comments and key ordering
in a hand-written file are not preserved across such a write.
share\checksums.yaml is written by the checksum commands. Entries are keyed by the full path of
the payload at the time it was recorded.
version: 1
last_modified: 2026-03-01T18:22:04.0000000+00:00
checksums:
C:\ProgramData\ManagedState\login-every\Map-DepartmentDrives.ps1:
sha256: 3b1f9a0c8e6d4f2a1b7c5d9e0f3a6b8c2d4e6f8a0b1c3d5e7f9a1b3c5d7e9f01
size: 2048
recorded_at: 2026-03-01T18:22:04.0000000+00:00
comment: Recorded via CLI at 03/01/2026 10:22:04Because the key is a full path, a recorded checksum does not follow a payload moved to a different directory — the entry simply stops matching anything and the moved payload validates by absence.
StartSet — MIT licensed — windowsadmins/startset — a Windows port of macadmins/outset.
StartSet
How it works
Migrating
Operating
Contributing