Unattended rollout
Rolling the agent out to a fleet: multi-provision tokens, golden images, cloud-init, configuration management and Group Policy.
Nothing extra is needed for a fleet rollout. It is the same install command with a multi-provision token, run by whatever already provisions your servers.
The token
Generate a multi-provision token under Manage > Agents. One token, one command, up to 500 hosts. Each host that redeems it becomes its own agent, named from its own reported hostname rather than from a name you typed.
Pick an agent group in the wizard before generating the token, and every host arrives already in that group - so a certificate policy on it applies before the agent's first ordinary check-in. Write the policy first, on an empty group, and servers provisioned months later get their certificate on the way up.
Tokens expire after an hour
An enrollment token is valid for one hour from creation, whatever its use count. Mint it as part of the provisioning run - from an operator's session immediately before the run, or as a step in the pipeline - rather than baking one into an image.
A multi-provision token in an image is a secret in an image
It registers agents in your organization. Scope it to the rollout and do not reuse one indefinitely. Anything that can read the image can read the token.
The command
It is the same one-command install as on a single server, with the token in the command - exactly what the dashboard's enrollment wizard hands out:
curl -fsSL https://get.aethercert.com | sudo bash -s -- --token <token>A provisioning run has no terminal - cloud-init, ssh without -t, a CI job, a remoting
session, a scheduled task - so the script asks nothing and takes the token from
--token / -Token or the AETHERCERT_TOKEN environment variable. Without either it
stops with an error before downloading anything. A token in the command never stops for a
review, terminal or not; -y / --yes (-Yes on Windows) additionally rules out every
other question, such as the menu for a host that already runs aethercert.
| Linux | Windows | Meaning |
|---|---|---|
--token <token> | -Token '<token>' | The enrollment token. Both also read AETHERCERT_TOKEN. |
--api <url> | -Api '<url>' | Control plane to enroll against. Both also read AETHERCERT_API. |
--proxy <url> | -Proxy '<url>' | HTTPS proxy for the script's own downloads, and written into the agent's config.json. |
--version <ver> | -Version '<ver>' | Pin a published installer version. |
-y, --yes | -Yes | Never ask anything. |
-- <args> | -InstallerArgs @(...) | Passed straight to aethercert-installer - see below. |
NO_COLOR turns off the Linux script's coloured output; a log that is not a terminal is
never coloured anyway.
Naming the script explicitly
get.aethercert.com chooses the script by client - PowerShell gets install.ps1,
everything else on the command line install.sh. Automation that should not depend on
that guess can name the script directly; both addresses serve the same script to every
client:
https://get.aethercert.com/install.shhttps://get.aethercert.com/install.ps1
Both verify the download against its published checksum - and, where release signing is configured, against a detached Ed25519 signature - before executing anything. Keep that property in whatever you script yourself.
Pin a version with --version / -Version so an image build is reproducible. Without it,
the install tracks the current published build.
Existing automation keeps working
The commands handed out before get.aethercert.com existed fetch the same scripts from
the CDN and remain supported, so a playbook, image recipe or GPO that uses them needs no
change:
curl -fsSL https://cdn.aethercert.com/install.sh | sudo sh -s -- --token <token>& ([scriptblock]::Create((irm https://cdn.aethercert.com/install.ps1))) -Token '<token>' -YesThe Linux script is POSIX sh, so piping it into sh rather than bash is fine - and is
what an Alpine host, which has no bash, needs.
Per-approach notes
| Approach | How |
|---|---|
| Golden image | Bake the installer binary and the command into the image build. Pin a versioned CDN path so the image is reproducible. Mint the token at build time, since it will have expired long before the image is deployed - which means each build enrolls, not each boot. |
| cloud-init / user data | Add the one-liner (curl -fsSL https://get.aethercert.com | bash -s -- --token <token> - cloud-init already runs as root) as a runcmd step, with the token injected by whatever renders the user data. This is the shape that works best with the one-hour expiry. |
| Ansible, Puppet, Chef, DSC | Run the installer as an ordinary command resource, guarded by whether the service already exists. aethercert-installer status exits 0 either way, so it is safe as a check. |
| Group Policy / Intune | Run the script-block form with -Token and -Yes as a startup script, or deploy the installer binary and run it with the token as an argument. |
A golden image enrolls once, not once per boot
An image baked with a completed install carries that one host's credentials. Every VM
cloned from it would then be the same agent. Either run the install on first boot -
cloud-init, a first-boot script - or bake only the binary and leave the install
command to first boot.
Waiting for the install on Windows
The Windows installer is a GUI-subsystem executable, so PowerShell and cmd.exe do not
wait for it. In a provisioning script that has to block:
Start-Process -Wait -NoNewWindow -FilePath .\aethercert-installer-windows-amd64.exe `
-ArgumentList 'install','--api','https://api.aethercert.com','--token','<token>'Piping its output also makes PowerShell wait.
Useful flags for a scripted install
| Flag | Why |
|---|---|
--quiet | Print warnings and failures only. |
--manual-start | Register the service without auto-start. |
--no-start | Register it without starting it now. |
--no-tray | Skip the tray icon on a headless Windows server. |
--no-update-service | Skip the Update Service. This host then never updates itself. |
--service-account / --service-password | Run the service as a named account instead of LocalSystem. |
--config <path> | An absolute path for config.json. Must be absolute; the installer rejects a relative one. |
--lang en|de | Language for the installer's own output. |
--proxy <url> / --no-proxy <hosts> | Hosts that reach the internet through a proxy - system uses the Windows machine proxy. Written into the component's config.json; see Outbound proxy. |
The full list is in the CLI reference.
Behind a proxy
--proxy / -Proxy covers the script's own requests (the token check, the installer
download, its checksum and signature) and is written into the agent's config.json. The
very first request - the one that fetches the script itself - is not the script's yet, so
give that one the proxy too:
curl -fsSL --proxy http://proxy.corp.example:3128 https://get.aethercert.com \
| sudo bash -s -- --token <token> --proxy http://proxy.corp.example:3128$env:AETHERCERT_TOKEN='<token>'
& ([scriptblock]::Create((irm -Proxy http://proxy.corp.example:3128 https://get.aethercert.com/install.ps1))) -Proxy 'http://proxy.corp.example:3128'Without -Proxy, Windows uses the machine's proxy settings for the downloads.
Verifying a rollout
The dashboard's agent list is the reckoning: every host that redeemed the token appears there after its first check-in, with its hostname, version and last-seen time. An enrollment token's own page lists the agents that came from it, which is the quickest way to see whether 300 hosts became 300 agents.
On an individual host, aethercert-installer status prints what is installed and which
control plane it points at.
Installing the agent
Every way to install the aethercert agent - the one-command install from get.aethercert.com on Linux and Windows, the manual download for locked-down hosts, the graphical setup wizard, and what the installer does to the host.
Containers and manual setups
Running the agent without registering an operating-system service - in a container, or under your own process supervisor.