Skip to content

windows_ad_user

Experimental. A user in Active Directory, run on a domain controller. Settings left unset are left as they are. Groups are set with windows_ad_group.

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

Use windows_ad_user to keep a user in Active Directory. Run it on a domain controller. Groups aren’t set here: list the user in a windows_ad_group step’s members.

step "alice" {
windows_ad_user {
name = "alice"
path = "OU=Lab,DC=lab,DC=example,DC=com"
upn = "alice@lab.example.com"
given_name = "Alice"
surname = "Smith"
display_name = "Alice Smith"
password_wo = "use an ephemeral variable here"
}
}

A service account whose password shouldn’t expire:

step "svc_backup" {
windows_ad_user {
name = "svc-backup"
description = "Runs the nightly backup"
password_never_expires = true
password_wo = "use an ephemeral variable here"
}
}
Name Type Required Description
description string No Description.
display_name string No Display name, such as Alice Smith.
enabled bool No true enables the account, false disables it. Unset, a new user is enabled when it has password_wo, and disabled when it doesn’t.
given_name string No First name.
name string Yes Logon name, used as both its sAMAccountName and its name in the directory, up to 20 characters, such as alice.
on_remove string No What happens in the domain when this resource is removed: “forget” (default) leaves the user, “delete” deletes it.
password_never_expires bool No true sets the password never to expire.
password_wo string No Password, kept out of plan and state: state records only password_hmac. It’s set when the user is made and whenever this value changes. A password changed in the domain isn’t detected.
path string No Distinguished name of the OU or container it’s in, such as OU=Lab,DC=lab,DC=example,DC=com. Unset leaves it where it is, and a new one goes to Windows’ default, CN=Users. A user found elsewhere is moved.
surname string No Last name.
upn string No User principal name, such as alice@lab.example.com.

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

Name Type Description
in_sync bool Whether the user matched at the last refresh.
password_hmac string HMAC-SHA256 of password_wo, keyed by CONN3X_HMAC_KEY or ~/.config/conn3x/hmac.key. Null without password_wo.
revision string Changes each time Conn3x changes this on the host. Handlers watch it.

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

Names. name is the logon name, the sAMAccountName, up to 20 characters. The user is found by it anywhere in the domain, and it’s also the user’s name in the directory. If the user is in another OU and path is set, apply moves it.

Waiting for AD. Straight after a DC reboots, Active Directory can answer for the domain a minute before its global catalog does, and a write made in that minute can hang. So apply first waits until a query through the global catalog works too, for up to 10 minutes, then fails with the reason AD last gave. A write that gets no answer at all runs once more when AD answers again. It reads first, so it only writes what’s still missing. A host that isn’t a DC isn’t waited on.

The password. password_wo goes to the domain controller on stdin and becomes a SecureString through .NET before any cmdlet sees it, so a logging policy that records cmdlet parameters records only the type name. It’s never in plan or state, and it’s blanked from errors. State keeps an HMAC of it, so a new password plans a change and the same one doesn’t. A password someone resets in the domain isn’t detected, because it can’t be read back.

Enabled. A new user with password_wo is enabled, and one without stays disabled, as Windows would have it. It’s made disabled first and enabled only once the password is set. enabled = true with no password ever set is refused. Conn3x won’t disable or delete the user it logs in as.

Drift. A refresh reads the location, UPN, names, description, whether the account is enabled and whether its password expires. Change any of those by hand and the next plan shows the step out of sync, and conn3x drift exits 2. Settings you leave unset aren’t compared.

Reads change nothing. A refresh runs Get-ADObject and Get-ADUser only. Nothing about the password comes back but whether one was ever set.

By default, deleting a windows_ad_user step leaves the user. With on_remove = "delete" it deletes the user, unless it’s the one Conn3x logs in as.