# Windows Server installation

## Package and requirements

Extract the complete UICConnectTMS-win-x64 ZIP to a local staging directory. Run `Configure.cmd`, or run `setup/TMS.ServerSetup.exe` as Administrator. This is an interactive console EXE with masked password entry; it does not require the Windows Desktop runtime.

Requires Windows x64, .NET 8 runtime and ASP.NET Core 8 runtime. No SDK or IIS is required. The reported target server with both runtimes at 8.0.10 meets the major-version requirement. Keep server runtimes patched through your normal maintenance process.

The SQL database must already exist. Setup tests the connection and applies embedded, versioned SQL migrations without dropping the database. The SQL login needs migration DDL permissions for setup and normal application DML permissions at runtime. Existing administrator accounts are preserved.

APK metadata and signature inspection runs inside .NET using bundled libraries. No Android SDK, aapt, external apksigner, Java installation or tool-path configuration is required on the server. Keep all payload files together; see Third-party-notices.md for the bundled components.

## Install or update step by step

1. Copy the new ZIP and its `.sha256` file to the server. Compare `Get-FileHash .\UICConnectTMS-win-x64-<timestamp>.zip -Algorithm SHA256` with the checksum file, then extract into a new staging folder. Keep all package folders together.
2. For an update, back up SQL, application artifacts, configuration and the TLS certificate. Schedule a maintenance window: setup applies database migrations before restarting services. Stop the three TMS services before running setup for an update.
3. Run `Configure.cmd` as Administrator. On an existing installation, select the same configuration directory (default `C:\ProgramData\UICConnectTMS`). Enter retains stored settings and passwords; do not switch directories unless creating a separate installation.
4. Enter SQL connection settings, portal and MQTT ports, public hostname, certificate and storage paths. SQL database creation is a separate prerequisite. Use the existing PFX on updates to retain terminal trust.
5. No APK inspection tool paths are required. The package includes the inspection libraries and does not compile, configure or install any Android application.
6. Setup checks the database before asking about the initial administrator. The default is **no** when users already exist and **yes** only when the database has no users. For a new database, create the initial administrator with a password of at least 12 characters.
7. Answer **yes** to install/update and start Windows services. Keep the existing installation directory on updates. Permit the configured HTTPS and MQTT TLS ports through the server firewall according to your network policy.
8. Open `https://<server>:5102` (or your configured HTTPS port), sign in, and complete the checks below. No source repository, .NET SDK, Gradle, Android Studio or Windows Desktop runtime is needed on the server.

## Verify the installation

In PowerShell, run:

```powershell
dotnet --list-runtimes
Get-Service UICConnectTMS.DataService,UICConnectTMS.Mqtt,UICConnectTMS.Portal
```

Confirm all three services are Running, the portal opens, existing customers/devices and parameters are present, and a terminal can reconnect and report telemetry. Test remote assistance with operator consent. Service startup alone does not confirm terminal connectivity.

For APK upload verification, upload the separately supplied `UIC-Device-Lab-NEWPOS-1.0.2.apk`, select NEWPOS NEW9810, and save the build. Under **View versions > Integrity**, compare **Signature** against the previous build. Version 1.0.2 (build 3) uses the same development signing certificate as 1.0.0:

```text
70DCD59AE328312F2154EF64210D95C437351E847975FB215243217CD6739D50
```

Its APK file SHA-256 is:

```text
62E814E6EDC57F5964666C1C2F12ED0C80B93B04C735BE37CA3147449EA89AA3
```

The file hash changes between builds; the signing-certificate fingerprint should match for this update. Uploading validates a build; release and device deployment are separate actions. The demo APK is intentionally separate from this server package.

## Configuration

Enter accepts the shown default or stored non-secret setting. Password prompts show asterisks and never display a stored value; Enter keeps an existing password. On first setup there is no default SQL or administrator password. PFX passwords and internal service keys are generated when creating a certificate.

| Setting | Default |
|---|---|
| SQL server / database | localhost / UICConnectTMS |
| SQL login | app_uic_tms, password required |
| SQL SSL / trust server certificate | true / false |
| Portal HTTP | 15100, loopback only |
| Portal HTTPS | 5102, all IPv4 interfaces |
| Internal gRPC | 15101, loopback HTTP/2 only |
| MQTT | TLS only, 5883, all IPv4 interfaces |
| Remote desktop | Portal HTTPS endpoint, same certificate |
| Remote session / admission / concurrency | 10 minutes / 120 seconds / 100 |
| Configuration | C:\ProgramData\UICConnectTMS |
| Installed programs | C:\Program Files\UICConnectTMS |

Provide a public DNS name/IP matching the TLS certificate. Supply an existing PFX, or allow setup to create a self-signed server certificate at a new path. The generated public `.crt` is available for device enrollment trust. Self-signed certificates are not automatically browser-trusted. No trust-store or firewall rules are changed automatically. Allow inbound configured HTTPS and MQTT TLS ports as needed. HTTP and gRPC remain loopback-only.

MQTT requires an individual provisioned client certificate from the separate IoT CA, plus each enrolled device's unique credentials; there is no shared/default broker password or anonymous listener. Topic authorization remains device scoped. Remote desktop uses the active authenticated MVC relay implementation; the disabled legacy standalone proxy is deliberately not installed. Session limits are configurable, but remote consent and authorization checks remain enforced.

## Certificate selection

Choose `pfx`, `machine`, or `user` in setup. Both HTTPS (including remote desktop) and MQTT use the chosen certificate.

- **pfx**: enter the PFX path and its masked password. Enter keeps a stored password; `-` selects an unprotected PFX. A new, nonexistent path retains the self-signed generation option.
- **machine**: search the Local Machine Personal (My) store by exact CN or friendly name.
- **user**: search the Personal (My) store of the account running the elevated setup by exact CN or friendly name. If elevation uses a different administrator, that administrator's store is searched.

Matches display subject, friendly name, expiry and thumbprint; choose the numbered certificate. Setup checks validity dates, private-key access and server-authentication usage. Check that the certificate SAN covers the public server hostname and that clients trust its issuer.

Store selection creates an encrypted PFX service copy in the protected configuration folder, with a generated password stored in DPAPI. This allows LocalService to use a certificate selected from a user's store without depending on that user's profile or changing the original private-key permissions. **Store private keys must be exportable**; non-exportable keys are rejected with instructions to supply a suitable PFX. Original store certificates remain unchanged. Store renewal is not automatic: rerun setup, select the renewed certificate and restart services.

New installations default to SQL user `app_uic_tms`, HTTPS **5102**, and MQTT TLS **5883**. Existing installations retain stored values as prompt defaults; explicitly enter the new values when migrating and update firewall rules and terminal endpoints accordingly. Setup does not create the SQL login.

## Account recovery and MFA protection

Setup asks for the public HTTPS portal URL used in password-recovery links. Email recovery is optional. Choose standard `smtp` delivery or the native `aws-ses` API. SMTP requires the host, port, TLS, sender address and optional username/password. AWS SES requires a verified sender identity, region and either the AWS default credential chain (recommended for an EC2 instance role) or a dedicated access key with `ses:SendEmail` permission. Accounts still in the SES sandbox can send only to verified recipients. Verify outbound delivery and sender authorization after installation. The public recovery form deliberately returns the same response for known and unknown addresses.

Setup creates an installation-specific account security key. DataService uses it to encrypt authenticator MFA secrets with AES-GCM. The account key, SMTP password and any explicitly configured AWS SES access credentials are stored only in `runtime.secrets.dpapi`. Preserve that protected file on in-place upgrades and include it in the coordinated server backup. If the account key is lost, enrolled MFA secrets cannot be decrypted and affected accounts require administrative recovery.

## MQTT IoT certificates

The installer creates a separate IoT certificate authority on first installation and preserves it on upgrades. Enter the 64-hex common bootstrap key using the masked prompt and securely provision that key into terminal enrollment. The CA password and bootstrap key are DPAPI-protected; the private CA PFX is access-restricted. Keep the CA and database together in protected backups.

MQTT now requires client certificates. Older agents using only passwords cannot connect. Install UIC Home 3.9.0-dev/build 13 or later with its secure enrollment settings. Device > Operations > Credential management > IoT certificates provides status, rotation and revocation. See the included `IoT-certificates.md` for the protocol and rollout limitations. The installer still does not build or configure the Android app.

## Password protection

`runtime.json` stores only non-secret settings. `runtime.secrets.dpapi` contains the complete database connection string, PFX password, optional SMTP password or AWS SES credentials, MFA encryption key and internal service keys encrypted with Windows DPAPI LocalMachine. Secrets are decrypted only in service memory. Neither development runtime configuration nor development certificates are included in the package.

The configuration directory ACL grants Administrators and SYSTEM full access and LocalService read access. Artifact storage grants LocalService modify access. Installed programs grant LocalService read/execute only. DPAPI protects secrets at rest, not against a compromised administrator or a process already running with an authorized identity. The encrypted file is machine-bound: rerun setup and enter secrets when moving to another server. Back up the database and configuration together using your protected server backup process; do not expect copying the DPAPI file alone to a new machine to work.

Windows authentication is optional, but setup runs as your administrator while services run as LocalService. A successful integrated-auth setup connection does not prove the service identity has SQL access. SQL authentication is the default deployment choice; for Windows authentication arrange the correct SQL grants/service account before starting.

## Services and updates

Setup optionally installs/updates and starts UICConnectTMS.DataService, UICConnectTMS.Mqtt and UICConnectTMS.Portal. They run as LocalService, start automatically and restart after failures. Portal and MQTT depend on DataService. Keep the extracted package to rerun configuration. Settings take effect after restarting services (the install/update choice does this).

The installer stops existing TMS services before copying program files. It never deletes the database, artifacts, or configuration. It does not provide automated binary rollback: retain the previous package and back up SQL/configuration before upgrading. Setup requires administrator elevation and service installation must be validated on the target server. Use Windows Event Viewer for service startup failures. The installer does not write SQL passwords or administrator passwords to log files.

The portal uses Kestrel directly. Access `https://<server>:5102`; the setup summary shows configured ports. Enroll terminals with the new server address, MQTTS port and certificate; local-development enrollment settings do not automatically transfer.

## Build and checks

Run `scripts/Build-ServerPackage.ps1` on the development machine. It produces framework-dependent win-x64 executables, a ZIP, and SHA-256 checksum. `setup/TMS.ServerSetup.exe --self-test` checks DPAPI round-trip without changing server settings or installing services. Live Windows-service registration requires an elevated target-server run and is not performed by the build.

## Installation diagnostics

Setup keeps its window open on both success and failure. Service installation writes a timestamped `service-install-*.log` in the configuration directory and prints each service status. A success report means all three services were still Running after the startup check; it is not a substitute for testing portal login and device connectivity.

If setup fails, preserve the log, correct the reported error, and rerun Configure.cmd from the latest extracted package. Existing configuration and secrets are retained. Windows services run without desktop windows; inspect them in Services or with `Get-Service UICConnectTMS.*` in PowerShell.

For manual diagnostics, stop the corresponding service first to avoid port conflicts. Installed programs use their adjacent `TmsConfig.path` file to find the saved configuration. An explicit path also works:

```powershell
& 'C:\Program Files\UICConnectTMS\TMS.DataService\TMS.DataService.exe' --TmsConfig 'C:\ProgramData\UICConnectTMS\runtime.json' --contentRoot 'C:\Program Files\UICConnectTMS\TMS.DataService'
```

Run diagnostics as Administrator because the configuration is access-restricted. Do not copy development `.local` files to the server. The default production configuration is under ProgramData, not Program Files.

## Rotating diagnostic logs

Setup and all three services use Serilog file logging. Files are stored in the `logs` subdirectory next to `runtime.json` (normally `C:\ProgramData\UICConnectTMS\logs`). Each component has its own files: `Setup-YYYYMMDD.log`, `TMS.DataService-YYYYMMDD.log`, `TMS.Connectivity.Mqtt-YYYYMMDD.log`, and `TMS.Portal-YYYYMMDD.log`. Portal logs also cover its remote desktop hosting.

Service logs roll daily and at 10 MB. Keep 30 files per component by default, including size-roll segments: this means 30 files, not necessarily 30 days. The oldest files are removed when rolling. Installer prompts `LogFileSizeMB` (1–100) and `LogRetainedFiles` (2–365) configure services; restart them after changes. Setup itself uses fixed 10 MB / 30-file defaults.

Startup/shutdown, host errors and application diagnostics are recorded; startup failures include exception type, error code and stack. Request bodies, credentials, configuration dumps and verbose HTTP request logging are not enabled. Treat diagnostic files as private operational data. The installer gives Administrators/SYSTEM full access and LocalService modify access only to the logs folder, without granting write access to protected configuration.

The separate `service-install-*.log` transcript remains in the configuration directory and records Windows service registration and startup results. These per-run transcripts are not automatically rotated; archive or remove them under your server retention policy. Failures before setup can open the protected log directory remain visible in the console. Windows Event Viewer remains useful for Windows Service Control Manager and early process failures.

## Remote desktop over HTTPS

Remote desktop shares portal TCP 5102 using secure WebSockets; MQTT remains TCP 5883. Browser HTTPS sessions may negotiate HTTP/2 WebSockets (CONNECT), while Android uses HTTP/1.1 upgrade (GET). Both remote socket endpoints support both methods. Form antiforgery applies to Start/End operations; socket admission uses the operator session and exact Origin for the viewer, and HTTPS plus the short-lived admission ticket for the terminal.

Portal logs include remote role, request method/protocol, WebSocket detection, handshake response status and connection termination. They do not record admission tickets or frame/input contents. HTTP/1.1 success is 101; HTTP/2 success is 200. A 400/405 response before connection can indicate an old portal build with GET-only routes or form-token filtering on CONNECT. Update the portal and create a new session. A reverse proxy, if present, must forward WebSockets correctly.

## Included in the September 24 workspace update

- Groups and subgroups: expandable tree, direct-membership device grid, group editing and device moves that preserve tags. See docs/32-groups-workspace.md.
- Remote keyboard: masked text entry and numeric keypad in the remote viewer. Select the device field, enter text in the portal, and choose Send to field. This replaces the selected field; it does not submit the Android form.
- Remote HTTPS compatibility: HTTP/2 browser WebSockets and HTTP/1.1 terminal WebSockets share the configured portal HTTPS port.

Upgrade the complete service payload together: Portal, DataService, MQTT and their bundled dependencies. The group changes include updated gRPC contracts; do not apply only the Portal DLL. This feature update adds no database migration and does not require recreating the database. Retain existing configuration, secrets, TLS and IoT CA files. The installer retains them when using the same configuration directory.

The remote keyboard requires UIC Home 3.9.5 or later and enabled UIC remote input Accessibility. The connected test terminal has already received this agent version. The server package does not contain or install Android APKs. After upgrading, refresh the browser and create a new remote session.

Validation for these changes: 190 integration checks passed on the development environment, including direct group filtering, tenant authorization, tag-preserving moves, and bounded remote text forwarding. Final Windows service startup and device keyboard operation must also be checked on the target server.
