> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/powershell-universal/config/agent.md).

# Agent

Configure Devolutions Agent or the PowerShell Universal Event Hub agent to run jobs and commands on remote computers.

PowerShell Universal supports two remote-agent implementations. Use **Devolutions Agent** for new deployments. It connects to PowerShell Universal over gRPC and supports remote jobs, computer groups, PowerShell remoting commands, and multi-pwsh virtual environments. The **PowerShell Universal Agent** remains available for Event Hub-based automation.

## Devolutions Agent

Devolutions Agent is the recommended agent for new installations. It establishes an outbound, authenticated gRPC connection to PowerShell Universal; PowerShell remoting does not need to be configured between the server and the managed computer.

Download the Windows installer from the [Devolutions Download Center](https://devolutions.net/download-center/). For container deployments, use the [`devolutions/powershell-universal-agent`](https://hub.docker.com/r/devolutions/powershell-universal-agent) image from Docker Hub.

### Prerequisites and connectivity

Install Devolutions Agent on the computer that will run the jobs. The agent must be able to reach the PowerShell Universal gRPC endpoint over HTTP/2. In the default development configuration, this is port `5006`; use the HTTPS endpoint in production.

Each agent needs a unique, stable agent ID. When the agent connects, PowerShell Universal creates or updates a Computer record with type **Agent**, marks it online, and adds tags for its machine name, operating system, architecture, hubs, and capabilities. Use these tags to target the agent with computer groups.

### Create an app token

Create a dedicated app token for every Devolutions Agent. The token must have the built-in **Agent** role. This role is intentionally limited to agent registration and does not grant management API permissions, so do not reuse an administrator or automation token.

{% code collapsedlinecount="10" %}

```powershell
Grant-PSUAppToken `
  -IdentityName 'devolutions-agent-01' `
  -Role 'Agent' `
  -Description 'Devolutions Agent on production-01' `
  -Expiry (Get-Date).AddYears(1)
```

{% endcode %}

Store the returned token as a secret. Rotate it before it expires and replace it in the agent configuration. The agent cannot connect with a missing, invalid, or non-Agent-role token.

### Configure the agent

The Windows installer can enable the **PowerShell Universal Agent** feature and collect the PowerShell Universal server URL, app token, agent ID, and display name. The agent can also be configured in `agent.json`.

{% code collapsedlinecount="10" %}

```json
{
  "PsuAgent": {
    "Enabled": true,
    "ServerUrl": "https://psu.contoso.com:5006",
    "AgentId": "devolutions-agent-01",
    "DisplayName": "Production agent 01",
    "AppToken": "$secret:psu-agent-token",
    "Hubs": ["production"],
    "PowerShell": {
      "VersionSelector": "7.6"
    }
  }
}
```

{% endcode %}

`AppToken` accepts either the token value or a `$secret:<name>` reference resolved by PowerShell SecretManagement. `AgentId` is the identifier used to target the agent. `DisplayName` is a friendly name shown in PowerShell Universal. `Hubs` become **Hub** computer tags. `PowerShell` can select a `multi-pwsh` version, use a specific executable path, or use Windows PowerShell.

For the Linux container image, supply `PSU_SERVER_URL` and `PSU_APP_TOKEN`; both are required to enable the PSU integration.

{% code collapsedlinecount="10" %}

```powershell
docker run --rm `
  --add-host host.docker.internal:host-gateway `
  --env PSU_SERVER_URL='http://host.docker.internal:5006' `
  --env PSU_APP_TOKEN='<application-token>' `
  --env PSU_AGENT_ID='devolutions-agent-linux' `
  --env PSU_HUBS='production' `
  devolutions/powershell-universal-agent:latest
```

{% endcode %}

### Run jobs on an agent

After the agent appears in **Manage > Computers & Groups > Computers**, create a computer group whose tags select it. For example, an agent configured with `"Hubs": ["production"]` has a `Hub` tag with the value `production`; a computer group with the `production` tag selects that agent.

Assign the computer group to a script or schedule and choose whether to run on **any** matching computer or **all** matching computers. You can also invoke a script against one agent by using its agent ID as the queue.

{% code collapsedlinecount="10" %}

```powershell
# Run on one named Devolutions Agent.
Invoke-PSUScript -Name '.\Inventory.ps1' -Queue 'devolutions-agent-01'

# Run on any online computer selected by the production-agents group.
Invoke-PSUScript -Name '.\Inventory.ps1' -ComputerGroup 'production-agents'
```

{% endcode %}

Only online agents that are not in maintenance mode are selected. A group invocation configured for **All** creates a job for every matching agent; **Any** selects one matching agent.

### Run commands with Invoke-PSUCommand

`Invoke-PSUCommand` is an alias for `Send-PSUEvent`. Use `-Computer` to run on a particular agent ID, or `-ComputerGroup` to run against each matching computer in a group. The command returns pipeline output and writes the remote warning, information, verbose, and error streams locally.

{% code collapsedlinecount="10" %}

```powershell
# Run a script block on one Devolutions Agent.
Invoke-PSUCommand `
  -Computer 'devolutions-agent-01' `
  -ScriptBlock { Get-CimInstance Win32_OperatingSystem }

# Run a command on all agents selected by a computer group.
Invoke-PSUCommand `
  -ComputerGroup 'production-agents' `
  -Command Get-Service `
  -Parameters @{ Name = 'Spooler' }
```

{% endcode %}

Use `-Timeout` to allow longer-running commands. The agent must remain connected for the entire invocation.

### Use multi-pwsh virtual environments

For an isolated or container execution environment with a virtual environment enabled, PowerShell Universal automatically packages the selected `multi-pwsh` virtual environment and instructs the remote agent to import it before the job starts. The agent then hosts the job with the matching PowerShell version and virtual-environment name.

Use this to ship the modules required by a job:

1. Create or update the virtual environment in PowerShell Universal and install the required modules into it.
2. Select that isolated or container environment for the script.
3. Target the Devolutions Agent directly or through a computer group.

The import runs through `multi-pwsh venv import`. You do not need to manually copy the modules to the agent; keep the virtual environment definition and its modules under PowerShell Universal management so the agent receives the expected package.

### What PowerShell Universal transfers

PowerShell Universal creates a remote repository under the agent's temporary directory at `PowerShellUniversal/Repository`, with `Scripts` and `Modules` folders. The repository's Modules folder is added to the remote PowerShell module path.

For a script job, PowerShell Universal transfers the job's startup script to the remote Scripts folder and runs the job over the gRPC PowerShell-remoting stream. This transfer is per execution: the copied startup script is removed after the job finishes. The admin console does not provide an **Install on Agent** action or a **Keep run scripts on agents** setting.

When the selected environment uses a multi-pwsh virtual environment, its package is imported before the job runs. Do not assume that arbitrary server files, secrets, or modules installed outside the selected virtual environment are transferred to the agent; provision those explicitly in the environment or on the managed computer.

## PowerShell Universal Agent

The PowerShell Universal Agent is the original Event Hub-based agent. It runs a local script or direct PowerShell command after receiving an Event Hub invocation over WebSockets. Use it when you need an existing Event Hub workflow; use Devolutions Agent for new remote-job deployments.

### Configure agent.json

Create `agent.json` after installation. Store it under `$env:ProgramData\PowerShellUniversal` for a system-wide agent or `$env:AppData\PowerShellUniversal` for a per-user agent.

{% code collapsedlinecount="10" %}

```json
{
  "Connections": [
    {
      "Url": "https://psu.contoso.com",
      "Hub": "eventHub",
      "AppToken": "<application-token>",
      "ScriptPath": "script.ps1",
      "Description": "My agent"
    }
  ]
}
```

{% endcode %}

`Url` and `Hub` are required. Authenticate with `AppToken` or `UseDefaultCredentials`. `ScriptPath` is optional because Event Hubs can invoke PowerShell commands directly. A relative script path is resolved from the PowerShell Universal data directory; use an absolute path when the script is stored elsewhere.

### Send Event Hub commands

Use `Invoke-PSUCommand` or `Send-PSUEvent` to invoke the configured Event Hub. For Event Hub-specific examples and invocation options, see [Event Hubs](/powershell-universal/api/event-hubs.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.devolutions.net/powershell-universal/config/agent.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
