Skip to main content
Version: 3.0 (next)

PI Agent Installation Guide

The MaestroHub PI Agent is a standalone Windows service that bridges MaestroHub to an AVEVA PI Data Archive. It runs inside the plant network, speaks to PI on your behalf, and exposes a WebSocket endpoint that the AVEVA PI System connector connects to.

MaestroHub  ──── WebSocket (TCP 45283) ───►  PI Agent  ──── PI protocol ───►  PI Data Archive
(Windows) (TCP 5450/5457)

MaestroHub dials out to the agent. The agent never needs access to MaestroHub — MaestroHub needs access to the agent.

1. Requirements​

OSWindows 10/11 or Windows Server 2016+, x64. There is no 32-bit build and no Linux build.
.NETNone. The agent ships self-contained; the runtime is inside the executable.
Native prerequisiteMicrosoft Visual C++ Redistributable (x64). Most Windows Server builds already have it. Without it the agent still starts, and states clearly that no PI operation will succeed.
PI client softwareNot required. The agent does not need PI SMT or any PI client, and does not read the machine's known-servers list.
Disk~200 MB, plus a small state file
MemoryAllow ~300 MB
Network — outboundMust reach the PI Data Archive on TCP 5450, and PI AF on TCP 5457
Network — inboundMust accept TCP 45283 from wherever MaestroHub runs

What to collect before you start​

You needNotes
PI Data Archive server nameA name, not an IP — the agent resolves it by DNS
PI AF server and databaseOnly needed to browse the asset tree
PI username and passwordOnly if the agent host is not domain-joined to the PI server
PI domain or machine nameAsk explicitly which it is — see the warning in step 4

Choose a topology​

A — one machineB — agent on a separate host
WhereAgent and MaestroHub on the same Windows machineAgent on a plant or server box, MaestroHub elsewhere
TLSCan be off (loopback only)Required
CertificateNone neededA certificate on the agent, and a CA (or skip-verify) in MaestroHub
FirewallNothing to openTCP 45283 from the MaestroHub host
Use forA first run, or a local trialAnything real

Both are covered below.

2. Download and extract​

Download the agent package from the MaestroHub portal:

https://portal.maestrohub.com/downloads/plugins

You get a zip and a checksum file beside it:

MaestroHubPiAgent-<version>-win-x64.zip
MaestroHubPiAgent-<version>-win-x64.zip.sha256

Verify the download, then extract it to a permanent folder:

Get-FileHash .\MaestroHubPiAgent-1.0.0-win-x64.zip -Algorithm SHA256
Get-Content .\MaestroHubPiAgent-1.0.0-win-x64.zip.sha256

Expand-Archive .\MaestroHubPiAgent-1.0.0-win-x64.zip -DestinationPath C:\MaestroHub\PiAgent

The two checksums must match. If they do not, stop and download it again.

Use a permanent location — not Desktop or Temp. This becomes the installation directory: the agent reads its configuration from here and writes its recovery state here. Do not put it in a folder that syncs to another machine, because the configuration file will hold secrets.

After extracting you should have:

C:\MaestroHub\PiAgent\
MaestroHubPiAgent.exe the agent — everything is inside it
appsettings.sample.json the annotated configuration template
install-service.ps1 registers it as a Windows service
uninstall-service.ps1 removes the service
README.md the full operator manual
LICENSE.txt
ThirdPartyNotices.txt

The executable is around 150 MB. That is expected — it carries the .NET runtime and the PI libraries.

appsettings.json must sit beside the executable

The agent reads its configuration from the folder the executable is in — never from your current directory. This matters because a Windows service starts in C:\Windows\System32, so anything resolved against the working directory would land somewhere surprising.

The same rule applies to every relative path inside the file, including the TLS certificate.

3. Generate an API token​

This is the shared secret MaestroHub presents when it connects. Generate a strong one:

[Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))

Keep the result — you need the same string in the agent's configuration and in the MaestroHub connection. The agent refuses to start on a token shorter than 16 characters.

4. Configure the agent​

Copy the shipped template and edit it:

cd C:\MaestroHub\PiAgent
Copy-Item .\appsettings.sample.json .\appsettings.json
notepad .\appsettings.json

appsettings.sample.json is heavily commented — every setting, its default, and what changing it does. Keys beginning // are comments and are ignored. Anything you do not need to change can be deleted.

Only two settings have no usable default: ApiToken and PiDataArchive.

Topology A — one machine, TLS off​

{
"AgentSettings": {
"Port": 45283,
"ListenAddress": "0.0.0.0",

"ApiToken": "<the token from step 3>",

"EnableTLS": false,

"PiDataArchive": "<PI-ARCHIVE>",
"AfServer": "<PI-ARCHIVE>",
"AfDatabase": "<AF-DATABASE>",

"PiUser": "<PI-USER>",
"PiDomain": "<PI-DOMAIN>",
"PiAuthMode": "windows"
},
"Logging": {
"LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" }
}
}

Topology B — separate hosts, TLS on​

The same file, with these three lines in place of "EnableTLS": false:

    "EnableTLS": true,
"TlsCertPath": "certs\\agent.pfx",
"TlsCertPassword": "<certificate password>",

Step 5 covers the certificate itself.

What the values mean​

FieldWhat to put, and why
ApiTokenThe string from step 3. Minimum 16 characters, and it must match the MaestroHub connection field character for character.
PiDataArchiveThe Data Archive's server name, not an IP address. Resolved by DNS; needs no PI client software.
AfServer / AfDatabaseOnly needed to browse the asset tree. The two go together — set one without the other and the agent refuses to start. Leave both empty if you only use plain PI point tags.
PiUserSet only if the agent host is not domain-joined to the PI server. Leave empty to connect as the Windows account the agent runs under, which is the cleaner option for a real deployment.
PiDomainFor a local Windows account on the PI host, this is that host's machine name — not a Windows domain and not a DNS suffix.
PiAuthModeOne of windows, piuser, openid, none. windows is correct for both a domain service account and a local account on the PI host.
ListenAddress0.0.0.0 means every interface. 127.0.0.1 makes the agent unreachable from any other machine — the agent warns you at startup if you set it.
PortDefault 45283. Must match Agent Port in the MaestroHub connection.
PiDomain is the most common cause of a failed connection

Ask explicitly whether the PI account is a domain account or a local account on the PI host. If it is local, PiDomain is the PI host's machine name.

Getting this wrong produces an error that reads exactly like a wrong password — and a burst of failed logons can lock out the account for everyone using it. If authentication fails twice, stop and confirm the username, password and domain rather than guessing again.

Keeping secrets out of the file​

Any setting can come from an environment variable instead. The name is PIAGENT_ followed by the JSON path with two underscores per level:

SettingEnvironment variable
AgentSettings:PiPasswordPIAGENT_AgentSettings__PiPassword
AgentSettings:TlsCertPasswordPIAGENT_AgentSettings__TlsCertPassword
AgentSettings:ApiTokenPIAGENT_AgentSettings__ApiToken

For a foreground test run, set it in the same PowerShell window you will start the agent from — it lasts for that session only:

$env:PIAGENT_AgentSettings__PiPassword = '<PI-PASSWORD>'

For a Windows service, it must outlive your session, so set it machine-wide from an elevated prompt and restart the service afterwards:

[Environment]::SetEnvironmentVariable('PIAGENT_AgentSettings__PiPassword', '<PI-PASSWORD>', 'Machine')

The agent will start with the password in appsettings.json, but it logs a warning: a plant credential in a settings file gets copied into backups, support tickets and screenshots.

5. Set up TLS​

TLS is on by default and should stay on. This WebSocket carries both your process data and the API token; over plaintext the token is readable and replayable by anyone on the network path.

Option 1 — a certificate from your own CA (any real deployment)​

You need a PKCS#12 (.pfx) file whose subject or SAN matches the hostname MaestroHub will use to reach the agent. An internally issued certificate is fine; it does not need a public authority.

    "EnableTLS": true,
"TlsCertPath": "certs\\agent.pfx",
"TlsCertPassword": "<certificate password>",
Relative paths resolve against the executable's folder

certs\agent.pfx means C:\MaestroHub\PiAgent\certs\agent.pfx, not a path relative to your shell. This is deliberate, because a Windows service starts in C:\Windows\System32. Absolute paths work too.

Create the folder and restrict the file, because its private key is inside:

New-Item -ItemType Directory -Path C:\MaestroHub\PiAgent\certs -Force
icacls "C:\MaestroHub\PiAgent\certs\agent.pfx" /grant "<service-account>:(R)"

Grant read access to the account the service will run as. If you are running in the foreground as yourself, you already have access.

Option 2 — a self-signed certificate (lab rig)​

From an elevated PowerShell:

$cert = New-SelfSignedCertificate -DnsName "pi-agent.plant.local" `
-CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(2)
$pw = ConvertTo-SecureString -String "<choose a password>" -Force -AsPlainText
New-Item -ItemType Directory -Path C:\MaestroHub\PiAgent\certs -Force
Export-PfxCertificate -Cert $cert -FilePath "C:\MaestroHub\PiAgent\certs\agent.pfx" -Password $pw

-DnsName must match the hostname MaestroHub will dial, or the handshake fails.

Then in MaestroHub, either paste the certificate into CA Certificate (PEM) or enable Skip Certificate Verification — one or the other, never both.

Option 3 — TLS off (loopback only)​

    "EnableTLS": false,

Legitimate only when MaestroHub and the agent are on the same machine, or on an isolated lab network. The agent logs a loud warning at startup whenever TLS is off, and that warning is correct. Turn Use TLS off on the MaestroHub side to match.

6. Start the agent​

Run it in the foreground first. It takes ten seconds and the output is far easier to read than the Event Log:

cd C:\MaestroHub\PiAgent
.\MaestroHubPiAgent.exe --console

--console runs it in the foreground with the log on screen. Stop it with Ctrl+C — that is a clean stop, and the agent flushes its recovery positions on the way out.

If any setting is wrong, the agent names every problem at once and exits without starting, so you fix them in one pass rather than one restart at a time.

Read the startup banner​

The first thing the agent prints is a block of facts. Most misconfigurations are visible right here, before anything has connected.

MaestroHub PI Agent 1.0.0
protocol version : 2
runtime : win-x64 (64-bit)
content root : C:\MaestroHub\PiAgent
listening on : ws://0.0.0.0:45283/ws
health : http://0.0.0.0:45283/health
PI Data Archive : <PI-ARCHIVE>
PI AF : <PI-ARCHIVE> / <AF-DATABASE>
PI identity : <PI-DOMAIN>\<PI-USER> (windows authentication)
LineWhat to check
protocol versionThe connector requires version 2. A 1 means the agent package is too old.
content rootThe folder appsettings.json was read from. If your settings appear to be ignored, the file is not in this folder.
listening onws:// when TLS is off, wss:// when on. This must agree with Use TLS in MaestroHub.
PI identityShows DOMAIN\user. If it says the service's own Windows account, PiUser was not picked up.
TLS ... DISABLED warningExpected on a loopback rig. Alarming anywhere else.

A second or two later, a line reports the PI connection is established. If PI is unreachable the agent keeps running and retries with backoff rather than exiting — deliberate, because an agent that will not start cannot tell anybody why.

Confirm it is ready​

In a second PowerShell window:

curl.exe http://127.0.0.1:45283/health

Use curl.exe with the extension — in Windows PowerShell, plain curl is an alias for a different command. With TLS on, use curl.exe -k https://<agent-host>:45283/health; -k skips the certificate check for this one diagnostic call.

What you want back:

{"ready":true,"piState":"Connected","sessionConnected":false,"agentVersion":"1.0.0","protocolVersion":2,"uptimeSeconds":42}
FieldMeaning
readytrue only once PI is connected. This endpoint reports readiness, not liveness — HTTP 503 with ready:false is the correct answer while PI is down.
piStateConnected is what you want. Connecting or Disconnected means read the agent log.
sessionConnectedWhether MaestroHub is currently attached. false is correct before you create the connection.
protocolVersionMust be 2.
Do not go further until ready is true

Every symptom past this point would just be this one wearing a different hat.

7. Install as a Windows service (optional)​

For a functional test you can leave the agent running in its console window. Install the service when you want it to survive a reboot.

Do this after the foreground run has proved the configuration is good — the script refuses to run without an appsettings.json beside the executable, precisely so a service cannot be registered on a configuration that will not start.

From an elevated PowerShell, in the installation folder:

cd C:\MaestroHub\PiAgent
.\install-service.ps1

That registers MaestroHubPiAgent for automatic start, configures it to restart after a crash, starts it, and waits for it to report healthy.

Useful options:

# Run under a dedicated service account, and open the firewall to the MaestroHub host only.
.\install-service.ps1 -ServiceAccount (Get-Credential DOMAIN\svc-maestrohub) `
-MaestroHubAddress <maestrohub-host-ip>

# Replace an existing installation. Your appsettings.json and state folder are kept.
.\install-service.ps1 -Force
OptionWhat it does
-ServiceAccountThe Windows account the service runs as, prompted for securely. The agent connects to PI as this identity when PiUser is empty, so a dedicated account is what makes PI's audit trail name the agent. The script grants it "Log on as a service" if missing. Omit it and the service runs as LocalSystem.
-MaestroHubAddressCreates an inbound firewall rule for the agent's port, scoped to that one address. Omit it to make no firewall change.
-ForceStops and deletes the existing service before reinstalling. Configuration and state are left alone.

There is deliberately no -ApiToken parameter: a secret passed on a command line is written into the PowerShell history of whoever ran it.

Afterwards:

Get-Service MaestroHubPiAgent          # is it running?
Restart-Service MaestroHubPiAgent # pick up a configuration change
.\uninstall-service.ps1 # remove the service
Configuration is read once, at startup

After editing appsettings.json, restart the service — or, in console mode, Ctrl+C and start it again. "I changed the setting and nothing happened" is almost always a missing restart.

A service does not see $env: variables set in your PowerShell window. If you supplied the PI password that way, set it machine-wide before installing the service, or the service will start and fail to authenticate to PI while the console run worked fine.

8. Connect MaestroHub to the agent​

In MaestroHub, go to Connect → New Connection → AVEVA PI System:

TabFieldValue
ConnectionAgent Host127.0.0.1 for topology A; the agent's hostname for topology B — the same name as the certificate's DNS name
ConnectionAgent Port45283, or whatever you set as Port
SecurityAPI TokenThe exact ApiToken string from appsettings.json
SecurityUse TLSMust match the agent's EnableTLS
SecurityCA Certificate (PEM)The CA that signed the agent's certificate, if it is not already trusted

Press Test Connection, then save. Watch the agent's console — you should see a session open, and the health endpoint's sessionConnected should become true.

The full field reference is in the AVEVA PI System connection guide.

9. Troubleshooting​

What you seeWhat it is
Exits immediately naming a field, exit code 78Configuration is invalid. The message names the field and the fix. Code 78 means specifically a human must edit a file — restarting will not help.
ApiToken ... is only N charactersThe minimum is 16.
TlsCertPath points at a file that does not existWrong path, or a relative path resolved against the wrong folder — relative means beside the executable.
Starts on defaults, complains ApiToken / PiDataArchive are emptyappsettings.json is not beside MaestroHubPiAgent.exe. Check the content root line in the banner.
Starts, but /health stays ready:false with piState: DisconnectedPI is unreachable (VPN? port 5450?) or the credential is wrong. The agent log names the PI error.
Windows authentication trial failed because the authentication method was not triedReads like a permissions problem; is not. Either PiUser / PiPassword / PiDomain are not all set, or PiDomain is wrong.
The credentials supplied to the package were not recognizedSame family. Usually PiDomain again.
the AVEVA AF SDK could not be loadedInstall the Visual C++ Redistributable (x64). The agent deliberately starts anyway so that /health can tell you this, instead of the service simply vanishing.
Port 45283 already in useAnother copy of the agent is running. Only one can hold the port.
MaestroHub connects, then drops when a second instance connectsThe agent serves one session and prefers the newest. Point only one MaestroHub connection at each agent.

The agent also writes to the Windows Event Log, which is where to look if the service starts and then stops before creating a log file.

Do not brute-force a PI credential

A burst of failed logons can lock the PI account for everyone using it. If authentication fails twice, stop and confirm the username, the password and — most likely — the PiDomain with whoever issued the credential.