Skip to content

windows_powershell

Experimental. A PowerShell script on a Windows host, for what no module covers yet. Guards say when it has already done its job.

Experimental. Windows support is new, and this module may change between releases.

Use windows_powershell for what no Windows module covers yet. Values go in args, and the script reads them as $A.name: they arrive as data, so a quote or a $(...) in one is just text.

Create a directory once:

step "app_dir" {
windows_powershell {
script = "param($A) [void][IO.Directory]::CreateDirectory($A.dir)"
args = { dir = "C:\\app" }
creates = "C:\\app"
}
}

Run only while a check says the work isn’t done:

step "long_paths" {
windows_powershell {
script = "Set-ItemProperty -LiteralPath 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\FileSystem' -Name LongPathsEnabled -Value 1"
unless = "(Get-ItemProperty -LiteralPath 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\FileSystem').LongPathsEnabled -eq 1"
}
}
Name Type Required Description
args map of string No Values the script reads as $A.name. They reach it as data, never as code.
args_wo map of string No Like args, but kept out of state: state records only args_hmac, and the values are blanked from output and errors. Use it for secrets.
creates string No Skip the script while this path exists.
removes string No Skip the script while this path is missing.
script string Yes PowerShell script. Start it with param($A), and read arguments as $A.name rather than interpolating them into the text.
timeout string No How long the script may run before it is stopped. Defaults to “30m”.
triggers dynamic No Any value; the script runs again whenever it changes.
unless string No Skip the script while this PowerShell check holds: it holds unless it throws, its last output is $false, or a native program it ran last exited non-zero. It runs at every plan, so it must change nothing. It gets args but never args_wo, which a plan doesn’t have.

Conn3x sets these; reference them as conn3x_windows_powershell.<circuit>__<step>["<host>"].<name>.

Name Type Description
args_hmac string HMAC-SHA256 of args_wo, keyed by CONN3X_HMAC_KEY or ~/.config/conn3x/hmac.key. Null without args_wo.
revision string Changes each time Conn3x changes this on the host. Handlers watch it.
satisfied bool Whether the guards hold on the host.
stderr string Error output of the last run, truncated to 4 KiB.
stdout string Output of the last run, truncated to 4 KiB.

A step lowers to the conn3x_windows_powershell resource, one instance per host, and connects with its circuit’s ssh block.

Failing. A script fails by throwing. Errors stop it by default, because $ErrorActionPreference is Stop. It also fails when the last native program it ran exits non-zero; for a tool with other success codes, such as robocopy, finish with $global:LASTEXITCODE = 0. Calling exit is reported as a failure: use return to finish early, and throw to fail.

Guards. Like command, the script runs when the step is created, when anything that defines it changes, and when a refresh finds its guards no longer hold. unless runs at every plan, so it must change nothing.

Secrets. args_wo stays out of the plan and state. State records only args_hmac, and the values are blanked from output and errors. A refresh doesn’t have them, so an unless check that needs them sees them only during an apply.

Secrets and logging. Where a policy turns on PowerShell’s module logging, Windows records what’s passed to any cmdlet. Conn3x keeps args_wo away from cmdlets on its way to your script, so don’t pass a secret to one yourself: use a .NET method, as in [IO.File]::WriteAllText($A.path, $A.secret).

Timeouts. A script is stopped after timeout. Conn3x stops the whole process tree when it cancels a run, but if the connection itself drops, as when the machine running Conn3x crashes, the script carries on running on the host.

Connecting. The ssh block works as it does on Linux, with its host key pinned or in known_hosts. Windows Server 2025 ships OpenSSH. Server 2022 doesn’t, so bootstrapping adds it first, as the Azure example’s script does. Either way, Conn3x installs its own host key as part of bootstrapping the host. become only checks that the login is elevated, since Windows has no sudo. agent and become_password_file are errors. Keep user as the bare name, such as azadmin, which still works after the host is promoted to a domain controller.

Deleting a windows_powershell step does nothing on the host.