Cronomicon · PowerShell Guide
📗 Usage Guide

Cronomicon

The self-hosted Script Orchestrator — schedule and run Bash, Ansible, Terraform, PowerShell, Perl and Python jobs across your fleet from one auditable web console.

Guide PowerShell guide — running PowerShell scripts with Cronomicon Version P1.0

How to run PowerShell well inside Cronomicon — chiefly against Windows fleets over OpenSSH: how a powershell run actually reaches its target, what that means for Windows hosts (and the one thing to know for Linux targets), how env, run inputs and outputs look from inside a PowerShell script, the exit-code semantics that decide whether your run reads Success or Failed, and how to use Cronomicon's features — scopes, run inputs, reference bindings, workflow outputs — idiomatically from PowerShell.

PowerShell is a shell-family run type, so most of the machinery is shared with Bash: read the Bash Guide for the two-executor model, targeting, bastions and secrets in full depth — this guide states the shared rules briefly and goes deep only where PowerShell differs. Companions: the User Manual, the Administrator Manual (§4, SSH executor), and the Runner Install Guide / Runner Config Guide / Runner Security Guide guides.

The one-sentence model. A PowerShell script is a Script (run type powershell), a Scope names the hosts it may touch, a Job binds the two to schedules and env — and the run executes over SSH: the dialing side (the Cronomicon server or a runner) connects to each target and invokes powershell -NonInteractive -Command there.


1 · How a PowerShell run reaches its target

Like Bash, a powershell run can execute on either executor — the in-app SSH executor (default via the resolution chain; the pool is off until an operator sets CRONOMICON_SSH_EXECUTOR_ENABLED=true, or shell runs queue forever) or a runner inside the target's segment. On both, the actual mechanics are identical: the dialing side opens an SSH connection to each target and runs

powershell -NonInteractive -Command <your script>

on the target (when the run injects environment, the invocation becomes powershell -NonInteractive -Command - and the program — an $env: prelude plus your body — arrives on stdin, so no value ever touches argv; see §4). Two consequences worth internalizing:

Runner capability nuance. A runner claims the powershell run type when pwsh is on its own PATH (the auto-detect probe) — even though execution happens on the targets over SSH. For a Linux runner that serves a Windows fleet but has no local pwsh, declare the capability explicitly (-capabilities bash,powershell / CRONOMICON_RUNNER_CAPABILITIES); otherwise the run queues “waiting for a powershell-capable runner.” A runner's -os flag records the runner host's own OS — it does not restrict what OS its targets run.


2 · Getting scripts in

Identical to the rest of the catalog (Bash Guide §2 in depth): any raw *.ps1 under scripts/ in the definitions repo is auto-discovered as a Script with run type powershell; or author a kind: Script YAML with exactly one of command / script / scriptPath and optional declared prompts; jobs bind by script_ref, or in-app via the Composer. Wire cronomicon validate . into CI — and Invoke-ScriptAnalyzer (PSScriptAnalyzer) sits beside it as naturally as shellcheck does for bash.


3 · Windows fleets: scopes, host records & auth

Targeting follows the shared shell-family rules — a scope fans out to its member hosts, a pinned target_host wins outright on every run path, a per-run host subset is SSH-executor-only (422 scope_membership otherwise) — with these Windows-fleet specifics:


4 · Env, inputs, outputs — and exit codes that tell the truth

Reading the environment

Injected environment (job env ← schedule env ← per-run overrides, plus bound references and the dispatcher's CRONOMICON_RUN_* context set) arrives as an $env: prelude ahead of your body, delivered on stdin — never argv, never /proc-visible. Read it the normal way:

$release = $env:TARGET_RELEASE          # a run-input answer (§ below)
$apiKey  = $env:CRONOMICON_SECRET_API_KEY  # a bound secret reference
Write-Output "run $($env:CRONOMICON_RUN_ID) on scope $($env:CRONOMICON_RUN_SCOPE)"

Run inputs, not Read-Host

The invocation is -NonInteractive: Read-Host, credential prompts and -Confirm dialogs don't hang — they throw (“Read and Prompt functionality is not available”). Declare operator questions as run inputs (spec.prompts) and read the answers from $env:; add -Confirm:$false / -Force to cmdlets that would otherwise prompt.

Exit codes: make failure loud

Cronomicon judges each host by the process exit code — and PowerShell's defaults are looser than Bash's. powershell -Command exits 1 on a terminating error, but non-terminating errors (most cmdlet failures) and failed native commands do not fail the run by themselves. Open every script with:

$ErrorActionPreference = 'Stop'     # non-terminating errors become terminating
Set-StrictMode -Version Latest

# after any native command you care about:
some.exe --do-thing
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

That is PowerShell's set -euo pipefail. Per-host results aggregate exactly as for bash: all ok → success, all failed → failure, mixed → warning (partial), with each host's output prefixed [hostname].

Workflow outputs (A12)

Hand values to downstream workflow steps with the standard marker on stdout:

Write-Output "::cronomicon-output name=HOTFIX_KB::KB5031364"

A downstream step binds an input to it and receives it as env. The output_secret_leak fail-close applies here too — never emit a bound secret as an output. See User Manual §7.5.


5 · Secrets from PowerShell

The delivery model is the shared one (Bash Guide §5): declare reference bindings on the job, receive $env:CRONOMICON_SECRET_<name> / $env:CRONOMICON_VAR_<name>; the in-app executor resolves and injects fail-closed with STDIN delivery, the runner path needs the per-runner Secret injection flag, and CRONOMICON_KEY_* material is runner-only. PowerShell-specific habits:


6 · Best-practice checklist


7 · Troubleshooting

SymptomLikely cause → fix
Runs sit queued forever (executor ssh)The SSH executor pool is disabled — CRONOMICON_SSH_EXECUTOR_ENABLED=true, or route to a runner.
Queued, “waiting for a powershell-capable runner”No online runner claims powershell — the probe needs local pwsh; declare -capabilities explicitly for a runner that only dials PowerShell targets (§1).
Per-host failure: powershell: command not foundA non-Windows target with only pwsh — add the powershell symlink/alias (§1). On Windows: the OpenSSH session's PATH is broken.
Error “Read and Prompt functionality is not available”Something asked a question under -NonInteractive — Read-Host, a confirm, a credential dialog. Replace with run inputs / -Confirm:$false (§4).
Run reads Success but the work failedA non-terminating error or a failed native command didn't move the exit code. Add the §4 preamble and the $LASTEXITCODE check.
cred_error on a Windows host despite a correct keyThe account is an Administrator and the key isn't in administrators_authorized_keys (§3).
Host-key mismatch / conn_error / unpinned_bastion_target / executor_lost / cronomicon: job timed outShared shell-family causes — see the Bash Guide §7 table; the rules are identical for PowerShell.

For the SSH executor's internals see Administrator Manual §4; for agent-side key custody and host-key approval, Runner Security Guide.