Built-In Module Reference

on this page

This page is the authoritative reference for the built-in modules: what each one does, which runtimes support it, its fields, and its known limitations. The per-module Supported runtimes lines below are asserted against the module catalog in code by a drift test, so this page cannot silently disagree with the binary.

Modules on this page: registry · service · file · directory · package · system_package · winget_package · remove_appx_packages · shortcut · scheduled_task · user · power_plan · windows_feature · environment · firewall_rule · powershell · shell · reboot · wait

Execution Contract

The built-in modules exposed through the local registry implement the same two-method contract:

  • Check(ctx, params) -> (needsChange, error)
  • Apply(ctx, params) -> error

The runner always calls Check() first. If it returns false, the task is reported as already in the desired state. If it returns true, Apply() runs unless the command is in dry-run mode.

Remote transports adapt that contract into the shared runtime dispatcher:

  • Check(ctx, params) -> (needsChange, message, error)
  • Apply(ctx, params) -> (output, error)

That allows remote runtimes to return a no-op message from Check() and captured command output from Apply() while preserving the same dry-run and idempotency flow.

Task Forms

Built-ins can be used either as inline modules:

yaml
- name: Ensure a directory exists
  directory:
    path: "C:\\Exhibits\\Content"

or as explicit modules:

yaml
- name: Ensure a directory exists
  module: directory
  params:
    path: "C:\\Exhibits\\Content"

Platform And Transport Support

ModuleLocal targetWinRM targetSSH target
fileYesYesYes
directoryYesYesYes
shellYesYesYes
powershellYesYesYes on Windows-over-SSH; on POSIX-over-SSH when pwsh or powershell is installed
environmentYesYesWindows-over-SSH only
waitYesYesYes on Windows-over-SSH; on POSIX-over-SSH (file_exists, port_open, service_running)
rebootYesYesWindows-over-SSH; POSIX-over-SSH (systemd)
registryWindows onlyYesWindows-over-SSH only
serviceWindows onlyYesYes on Windows-over-SSH; on POSIX-over-SSH over systemd (requires root)
packageWindows onlyYesWindows-over-SSH only
winget_packageWindows onlyYesWindows-over-SSH only
remove_appx_packagesWindows onlyYes*Windows-over-SSH only
shortcutWindows onlyYesWindows-over-SSH only
scheduled_taskWindows onlyYesWindows-over-SSH only
userWindows onlyYesYes (Windows-over-SSH; POSIX-over-SSH, requires root)
power_planWindows onlyYesWindows-over-SSH only
windows_featureWindows onlyYes*Windows-over-SSH only
firewall_ruleWindows onlyYesWindows-over-SSH only
system_packagePOSIX onlyNoPOSIX-over-SSH only (apt or dnf)

Notes:

  • *windows_feature and remove_appx_packages are registered over WinRM but cannot complete their changes over a basic WinRM session. See WinRM session limitations.
  • On non-Windows local runs, Windows-only built-ins are still registered but fail fast with a Windows-only error.
  • SSH auto-detects windows-powershell or posix-shell at connection time.
  • Windows-over-SSH shares the built-in Windows module surface with WinRM.
  • POSIX-over-SSH currently supports file, directory, shell, wait (file_exists, port_open, service_running), reboot, powershell when a remote PowerShell binary is available, user (requires root), system_package on targets with apt or dnf, and service over systemd (requires root).
  • Plugin modules run over every transport — local, SSH (POSIX and Windows), and WinRM — because the plugin process runs controller-side and its target effects flow through the transport’s handle ops. See the plugin reference.

Unsupported module usage is caught before the task runs and returns a clear, typed error; there is no silent fallback. See the error reference for when each layer catches a violation and the reason codes involved.

WinRM Session Limitations

The WinRM transport authenticates with NTLM/Negotiate and runs each operation under a non-interactive network logon. Some Windows operations require privileges or a user profile that this kind of session does not provide, so they cannot be performed over WinRM regardless of the module used:

  • windows_feature (DISM online servicing) — enabling or disabling an optional feature fails with “The symbolic link cannot be followed because its type is disabled.” DISM follows symlinks in the component store (WinSxS), and a network-logon token is not permitted to follow them. Reading feature state works; changing it does not.
  • remove_appx_packages with all-users scopeRemove-AppxPackage -AllUsers fails with HRESULT 0x80073D19 (“An error occurred because a user was logged off.”). All-users AppX removal needs an interactive session context.
  • Incremental output streaming — over WinRM, the WS-Man channel buffers a command’s stdout and delivers it in a single batch when the command completes. Output from the powershell module is still delivered correctly and in order; it just does not arrive line-by-line as it is produced.

These are properties of the WinRM session, not defects in the modules, so Preflight cannot work around them in PowerShell. There is no CredSSP option in the WinRM transport (see why CredSSP would not lift most of these). When you need these operations:

  • run them with the local target or a staged bundle executed on the box, or
  • use an interactive/elevated context (for example a scheduled task), or
  • for live streaming specifically, use Windows-over-SSH, where output is delivered incrementally.

POSIX Capability Baseline And Tiers

POSIX-over-SSH support is capability-based, not a distro allowlist. A host is supported when it provides the capabilities the modules rely on, not when its distro name appears on a list.

Capability baseline (Linux, the official tier):

  • Shell — strict POSIX sh. Modules and stdlib actions never assume Bash.
  • Core utilities — the standard POSIX toolset plus base64 (already assumed for file transfer). sha256sum/shasum are probed with a read-and-hash-locally fallback, so neither is required.
  • Init system — systemd, for service, wait’s service_running, and reboot’s if_needed probe. Hosts without systemd fail those tasks with a typed missing_prerequisite error naming what was probed; everything else still works.
  • Package managersapt and dnf officially, for system_package. Other managers are a stated limitation with the shell module as the escape hatch.
  • sudo — required only when become is used (see How become works).

Tiers:

  • Official — any Linux meeting the baseline. Static binaries mean musl/Alpine works; Alpine’s OpenRC and apk fall under the stated limitations below.
  • Best-effort — macOS and other POSIX systems (BSDs, illumos). They may work via the same capability baseline, but there are no version claims, no CI, and no required builds. family=darwin with empty distro facts is the expected shape, not a bug.

Consolidated POSIX Limitations

These are documented, not coded around; the per-module notes below colocate each one with the module it limits.

  • environment is unsupported on POSIX-over-SSH — ambient env is login-shell plumbing with no faithful analog; per-service env belongs in unit files (file + service).
  • user sets a password on creation only; an existing user’s password is never reset, even when password is supplied and Apply runs for another reason. Managed POSIX hosts authenticate by SSH key.
  • Non-apt/dnf package managers and non-systemd init are unsupported; the shell module is the escape hatch.
  • The real reboot + reconnect path is unit-tested against fakes only and is not exercised end-to-end in CI.
  • macOS/BSD is best-effort, as above.

Module Fields

registry

Supported runtimes: windows-powershell

Manage Windows registry keys and values.

FieldTypeMeaning
pathstringRegistry key path
userstringOptional Windows user for HKCU/HKEY_CURRENT_USER paths
valueslistTyped value spec list
ensurepresent or absentDesired state

Typed value specs inside values support these fields:

FieldTypeMeaning
namestringRegistry value name
typestring, expand_string, dword, qword, binary, or multi_stringRegistry value type
dataanyRegistry value data
patchlistByte patches for an existing binary value
ensurepresent or absentDesired value state

Use patch when a Windows setting is stored inside an existing binary registry value and the rest of the value should be preserved:

yaml
- name: Enable taskbar auto-hide
  registry:
    path: 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3'
    values:
      - name: Settings
        type: binary
        patch:
          - offset: 8
            data: 3

service

Supported runtimes: windows-powershell, posix-shell · requires root

Manage services. Same schema on Windows and POSIX; the runtime implementation is per-platform (Windows SCM on Windows, systemctl on POSIX-over-SSH).

FieldTypeMeaning
namestringService name
staterunning, stopped, or disabledDesired service state
startup_typeautomatic, manual, or disabledStartup behavior

POSIX-over-SSH (systemd). The target must run systemd (probed via /run/systemd/system); a host without systemd fails the task with a typed missing_prerequisite error naming what was probed. The module is requires root: run the session as root or set become: {enabled: true} to escalate (see Become).

state maps to systemctl active state:

  • running → the unit is active (systemctl start)
  • stopped → the unit is inactive (systemctl stop)
  • disabled → stop and mask in one step (systemctl stop + systemctl mask), short-circuiting startup_type just like the Windows apply. Windows’ disabled service state corresponds to systemd masked (a unit that cannot be started).

startup_type maps to systemctl enable state:

  • automaticenabled (systemctl enable)
  • manualdisabled (systemctl disable)
  • disabledmasked (systemctl mask)

Enabling or disabling first unmasks the unit (a no-op when it is not masked) so a previously masked unit can transition back to enabled or disabled.

The local POSIX target does not implement the service module; manage POSIX services over SSH. The shell module is the escape hatch for non-systemd init systems.

file

Supported runtimes: windows-powershell, posix-shell

Manage files.

FieldTypeMeaning
srcstringLocal source path to copy from
contentstringInline file content to write; may be a secret:<name> reference
content_templatestringInline file content template to render before writing; supports secret("name") placeholders
deststringDestination path
ensurepresent or absentDesired state

Use src, content, or content_template; do not combine them. content is useful for writing secret-backed files without creating a temporary plaintext source file:

yaml
- name: Write license file
  file:
    dest: "C:\\Exhibits\\license.txt"
    content: secret:license-file

Use content_template when only part of the file is secret:

yaml
- name: Write app config
  file:
    dest: "C:\\Exhibits\\app.ini"
    content_template: |
      username={{ vars.app_user }}
      password={{ secret("app-password") }}

secret:<name> is still the syntax for whole-field secret references. Inside content_template, use secret("name") so the secret can be interpolated into the rendered file body.

directory

Supported runtimes: windows-powershell, posix-shell

Manage directories.

FieldTypeMeaning
pathstringDirectory path
ensurepresent or absentDesired state

package

Supported runtimes: windows-powershell

Manage local MSI or EXE installations on Windows.

yaml
- name: Install packages
  package:
    packages:
      - product_id: "{D5E71B88-9A6C-4B6B-89C0-123456789ABC}"
        source: "C:\\Installers\\app.msi"
      - product_id: "{AAAA-...}"
        source: "C:\\Installers\\tool.exe"
        args: ["/silent", "/norestart"]
      - product_id: "{OLD-GUID}"
        ensure: absent
FieldTypeMeaning
product_idstring (required)MSI product GUID used for idempotency
sourcestringMSI or EXE installer path (required when ensure=present)
argsstring[]Extra installer arguments
ensurepresent or absentDesired state (default: present)

Use package when you already have a staged or local installer path. Use winget_package for package-manager-driven installs.

system_package

Supported runtimes: posix-shell · requires root

Manage repo packages through apt or dnf on POSIX targets.

yaml
- name: Install packages
  system_package:
    packages:
      - name: tree
      - name: jq
        version: "1.6-2.1"
      - name: legacy-tool
        ensure: absent

The packages list is the primary interface. Each entry supports:

FieldTypeMeaning
namestring (required)Package name as known to the detected package manager
versionstringPin to an exact version, in the native manager format
ensurepresent or absentDesired state (default: present)

system_package autodetects apt or dnf from the target’s cached detection facts (facts.os.package_manager) and is POSIX-only. It mirrors the winget_package list shape but uses name instead of id. A task whose target has neither manager fails with a per-task environment-prerequisite error before Check() runs.

version is compared as an exact string against the native version string: dpkg-query ${Version} for apt, and rpm %{VERSION}-%{RELEASE} for dnf. Supply the full native version string the manager reports, including epoch or release where relevant. Targets with a package manager other than apt or dnf are not supported; use the shell module as an escape hatch.

system_package requires root. Run as root or set become: {enabled: true} to escalate to root; a non-root run fails with a requires-root-violation before Check().

winget_package

Supported runtimes: windows-powershell

Manage packages through winget.

yaml
- name: Install packages
  winget_package:
    packages:
      - id: Microsoft.VisualStudioCode
        version: "1.85.0"
      - id: Git.Git
        scope: machine
      - id: Microsoft.VisualStudio.2022.Community
        args:
          - --override
          - "--quiet --wait --norestart"
      - id: OldApp
        ensure: absent

The packages list is the primary interface. Each entry supports:

FieldTypeMeaning
idstring (required)winget package identifier
versionstringPin to an exact version
sourcestringwinget source name
argsstring[]Extra winget command arguments
scopemachine or userInstall scope (default: machine)
ensurepresent or absentDesired state (default: present)

Put package-specific winget flags under args on that package entry. Do not add flags as additional packages list items.

remove_appx_packages

Supported runtimes: windows-powershell

Remove built-in Windows Store-style packages.

yaml
- name: Remove bloatware
  remove_appx_packages:
    packages:
      - name: Microsoft.Xbox*
        scope: both
      - name: Microsoft.BingNews
      - name: Microsoft.549981C3F5F10
        scope: provisioned
FieldTypeMeaning
namestring (required)Package name or wildcard pattern
scopecurrent_user, all_users, provisioned, or bothRemoval scope (default: both)
ensureabsentDesired state

Installed Appx packages that Windows marks NonRemovable are ignored so checks do not report changes that Windows will not allow Preflight to apply.

shortcut

Supported runtimes: windows-powershell

Manage Windows .lnk shortcuts.

FieldTypeMeaning
targetstringShortcut target path
destinationstring.lnk path to manage
argsstringOptional arguments
iconstringOptional icon path

scheduled_task

Supported runtimes: windows-powershell

Manage Windows scheduled tasks.

FieldTypeMeaning
pathstringScheduled task folder path, such as \Preflight\
namestringScheduled task name
executestringExecutable path
argumentsstringOptional command arguments
working_dirstringOptional working directory
triggerstartup, onlogon, daily, or onceTrigger type
start_atstringStart time for daily and once triggers
delaystringDelay for startup and onlogon triggers
run_asstringRun-as user
run_levelleast or highestPrivilege level
enabledboolEnabled state
ensurepresent or absentDesired state

delay accepts ISO-8601 duration strings such as PT30S.

user

Supported runtimes: windows-powershell, posix-shell · requires root

Manage local users.

FieldTypeMeaning
namestringUser name
passwordstringPlaintext password or a secret reference
groupsstring[]Group memberships
ensurepresent or absentDesired state

Windows. When ensure: present is used without a password, Preflight creates the user without a password if the account does not already exist. If the user already exists, omitting password leaves the current password unchanged. Requested groups are additive and ensure membership in those groups without removing other existing memberships.

POSIX (requires root). Over SSH-POSIX the same schema drives useradd/userdel. ensure: present creates a missing user with useradd and, when a password is supplied, sets it via chpasswd on creation only. Group membership is additive (usermod -aG) and never strips existing memberships. ensure: absent runs userdel.

Known limitation — POSIX password drift. The password of an existing user is never reset, even when password is supplied and Apply runs for another reason (for example, to add a group). Managed POSIX hosts authenticate by SSH key, so password drift on existing accounts is documented rather than corrected. To force a password change, manage the password out of band (for example, via a shell task running chpasswd).

power_plan

Supported runtimes: windows-powershell

Manage named Windows power plans.

FieldTypeMeaning
namestringFriendly scheme name
basestringBase alias or GUID to clone when creating the scheme
activateboolWhether to activate the scheme after applying it
settingslistAC and DC setting overrides
ensurepresent or absentDesired state

Each entry in settings supports:

FieldTypeMeaning
subgroupstringPower setting subgroup alias or GUID
settingstringPower setting alias or GUID
ac_valueintegerAC value override
dc_valueintegerDC value override

windows_feature

Supported runtimes: windows-powershell

Manage Windows optional features.

FieldTypeMeaning
namestringFeature name
ensurepresent or absentDesired state

environment

Supported runtimes: windows-powershell

Manage environment variables.

Known limitation — POSIX. environment is unsupported over POSIX-over-SSH: ambient environment is login-shell plumbing with no faithful analog, and per-service environment belongs in unit files (managed with file + service). The local POSIX target registers an os.Setenv-backed implementation that only affects the preflight process, which is rarely what you want; for managed endpoints use file + service instead.

FieldTypeMeaning
namestringVariable name
valuestringVariable value
scopemachine or userTarget scope
ensurepresent or absentDesired state

firewall_rule

Supported runtimes: windows-powershell

Manage Windows firewall rules.

FieldTypeMeaning
namestringRule name
directioninbound or outboundTraffic direction
actionallow or blockRule behavior
protocoltcp, udp, or anyProtocol
portsint, string, or arrayPort or port list
ensurepresent or absentDesired state

powershell

Supported runtimes: windows-powershell, posix-shell

Run PowerShell.

FieldTypeMeaning
scriptstringInline PowerShell script
filestringPath to a PowerShell script file
argsstring[]Arguments passed to the script file path
check_scriptstringInline non-mutating PowerShell check script
createsstringSkip when this path already exists
working_dirstringWorking directory
envobjectEnvironment variables visible to the PowerShell process

Exactly one of script or file should be provided for meaningful behavior.

When working_dir is set, relative creates paths are checked from that directory.

check_script takes precedence over creates. It must return either:

  • a boolean, where true means change is needed
  • an object with needs_change and optional message

shell

Supported runtimes: windows-powershell, posix-shell

Run a shell command.

FieldTypeMeaning
cmdstringCommand to execute
argsstring[]Command arguments
createsstringSkip when this path already exists
working_dirstringWorking directory
envobjectEnvironment variables visible to the command process

When working_dir is set, relative creates paths are checked from that directory.

reboot

Supported runtimes: windows-powershell, posix-shell · requires root

Request a reboot.

FieldTypeMeaning
conditionalways or if_neededReboot policy (default: if_needed)
timeoutintegerReconnect-wait timeout in seconds (default: 300)

On POSIX-over-SSH (systemd hosts), condition: always issues systemctl reboot and waits for the SSH connection to re-establish within timeout. condition: if_needed probes the distro reboot-required signal: /var/run/reboot-required (the apt convention, also honored as a plantable marker on any distro) and needs-restarting -r (dnf). When neither signal is available, no reboot is needed and the task output says so. reboot requires root on POSIX — run as root or with become. The real reboot+reconnect path is unit-tested against fakes only and is a stated limitation: it is not exercised end-to-end in CI.

wait

Supported runtimes: windows-powershell, posix-shell

Wait for a condition to be met before continuing.

FieldTypeMeaning
conditionport_open, file_exists, or service_runningWait condition
targetstringWhat to wait on — interpretation depends on condition (see below)
timeoutduration stringMaximum time to wait, e.g. "5m", "30s" (default: "5m")

The target field is required and interpreted per condition:

conditiontarget formatExample
port_openaddress:port TCP endpoint"localhost:8080"
file_existsFile system path"C:\\Exhibits\\ready.txt"
service_runningWindows service name or systemd unit name"W32Time", "nginx.service"

On POSIX-over-SSH, service_running probes systemctl is-active --quiet. It requires systemd; a host with no init system detected fails the task with the typed environment-prerequisite error (missing_prerequisite).