Logging User Actions in WinCC: Audit Trail and Operator Messages
Siemens WinCC HMI/SCADA systems routinely perform operator input, value changes, recipe selections, screen switches, and acknowledgments. Engineering teams that need to track who did what, when, and from which client typically require that information in the same SQL-based archive the process values use, so it can be queried, exported, and audited. WinCC provides three production-ready mechanisms for this: the licensed Audit Trail option, the user-defined operator message subsystem, and VBS / C action scripting with manual HMIRuntime.Trace / archive writes. This reference compares the three mechanisms, gives commissioning-grade configuration for each, and shows how the resulting records surface in the archive table.
1. Overview and Architectural Position
Every WinCC project is organized around three data flows: process values (tags, archives, trends), messages (bit-level, system, operator, and process messages routed through the Alarm Logging service), and user administration (SIMATIC Logon, internal user, or Windows domain accounts). A user action becomes auditable only at the boundary where one of those flows is intercepted.
Where a user action is captured determines what information is captured:
-
Audit Trail records every change to configured variables and selected operator actions, signed with a checksum chain and stored in
dbo.AUDIT_TC/dbo.AUDIT_TCV. It is the only mechanism that meets 21 CFR Part 11-style requirements and is tamper-evident. -
User-defined operator messages route through Alarm Logging and are stored in
dbo.MSGalongside process and system messages. They are queryable through standard Alarm Control filtering. -
Scripts can call
HMIRuntime.Trace, write to a user archive field, append to a text file, or insert directly into an archive tag. Maximum flexibility, no built-in integrity guarantees.
2. Prerequisites
- WinCC V7.4 SP1 or later (this article assumes V7.5 SP2 / V7.5 SP3) or TIA Portal WinCC Professional V17/V18 for the equivalent S7-1500 HMI panel. TIA Unified is not covered here because the archive schema is different (PouchDB / SQLite).
- A configured user administration: SIMATIC Logon, internal WinCC users, or a Windows domain group. Without resolvable user identity, all three mechanisms lose their value.
- SQL Server reachable from the WinCC server. The default instance is
\WinCCwith databasesCC_<ProjectName>_R(runtime) andCC_<ProjectName>_A(archive). - For Audit Trail: a valid WinCC Audit license (article 6AV6371-1DX07-4AX0 for V7.x base; expansion package 6AV6371-1DX07-4CX0 for the advanced option).
- Permissions: member of the
SIMATIC HMI/WinCC Administratorsgroup on the WinCC server,db_owneron the archive database for custom table writes.
Reference: WinCC V7.5 SP2 Manual (Siemens Support entry 109751755) and Siemens Support FAQ 24325381: Operator Messages in WinCC.
3. Method A: WinCC Audit Trail (Licensed)
WinCC Audit is a separate runtime component installed on the WinCC server. Once licensed, the configuration surface in WinCC Explorer gains an "Audit" editor tree node and an "Audit" column appears in the Tag Management and Alarm Logging properties.
3.1 Enabling the Editor
- In WinCC Explorer, right-click the project node and choose Properties → Options. Confirm that the WinCC Audit option is licensed and active.
- Open the new Audit editor. Three sub-nodes are visible: Configuration, Reports, and Viewer.
- In Configuration → Settings, set:
-
Audit size of trace→ number of records buffered in memory (default 1 000, raise to 10 000 for fast operator stations). -
Audit retention→ days to keep archive data before pruning; FDA-style projects require indefinite retention with archive backup policy. -
Checksum algorithm→ SHA-256 (V7.5 SP2 default; older builds use SHA-1, which is not acceptable for regulated environments).
-
3.2 Marking Tags and Messages for Auditing
| Object | Location in WinCC Explorer | Property to Enable | Notes |
|---|---|---|---|
| Process tag | Tag Management → <Channel> → Tag | Properties → Audit → tick Auditing active | Any tag write through WinCC is captured with old value, new value, user, computer, timestamp. |
| Tag with limits | Tag properties → Limits | Same Audit tab | Limit-violation events are also written. |
| Operator message class | Alarm Logging → Message Classes | Properties → Audit → tick Audit this message class | Captures operator-input messages generated by the system. |
| User-defined message | Alarm Logging → Individual messages | Tick Audited in message properties | Required for FDA-style tracking of single operator acknowledgments. |
| Screen actions | Graphics Designer → Object → Events | Tick Audit this event in the event configuration dialog | Captures screen open, close, button press, and value change events with the object name. |
3.3 What Gets Written
Audit records are stored in the archive database in two tables:
-
dbo.AUDIT_TC— audit trail configuration changes (who enabled/disabled auditing, license status, project changes). -
dbo.AUDIT_TCV— variable value changes; primary columns areTC_TIME,TC_USER,TC_COMPUTER,TC_VAR,TC_OLDVAL,TC_NEWVAL,TC_HASH_PREV,TC_HASH. -
dbo.AUDIT_TCM— message-related audit events (acknowledgments, status changes).
TC_HASH_PREV / TC_HASH pair forms a hash chain. WinCC Audit Viewer verifies the chain whenever an audit file is opened. Any tampering breaks the chain and is reported as "Audit trail invalid".3.4 Querying from the Archive Table
Although Audit Trail writes to its own dedicated tables rather than the process value archive, those tables are inside the same CC_<Project>_A database, so a single SQL query can join Audit data with process values:
-- All operator-driven setpoint changes in the last 24 h
SELECT a.TC_TIME,
a.TC_USER,
a.TC_COMPUTER,
a.TC_VAR,
a.TC_OLDVAL,
a.TC_NEWVAL,
a.TC_HASH
FROM dbo.AUDIT_TCV AS a
WHERE a.TC_TIME > DATEADD(HOUR, -24, GETDATE())
AND a.TC_USER <> 'SYSTEM'
ORDER BY a.TC_TIME DESC;
-- Join audit and process archive for context
SELECT v.TC_TIME AS change_time,
v.TC_USER,
v.TC_NEWVAL AS new_setpoint,
ar.PVVARIABLEW AS measured_value
FROM dbo.AUDIT_TCV AS v
INNER JOIN dbo.ARCHIVE AS ar
ON ar.PVARCHIVETIME BETWEEN v.TC_TIME AND DATEADD(SECOND, 60, v.TC_TIME)
WHERE v.TC_VAR LIKE 'S7$Program/SETPOINT%';
Reference: WinCC V7.5 SP2 Audit Option Manual (Siemens Support entry 109769926).
4. Method B: User-Defined Operator Messages
Operator messages are the lightweight way to get user actions into the Alarm Logging archive. A user-defined operator message is a string formatted with up to 10 process values; it is dispatched the same way as a bit-level alarm and lands in dbo.MSG with full origin information.
4.1 Configuring the Message Class
- In WinCC Explorer, open Alarm Logging → Message Classes. Right-click and add a new class USER_AUDIT with:
- Type: Operator message
- Archive: Long-term archive (otherwise messages are lost on archive swap)
- Priority: 1 (audit messages should not be alarm-priority, otherwise the alarm control flashes on every entry)
- Inside the new class, add an individual message with a default text containing the 10 process-value placeholders:
Operator %1 changed %2 from %3 to %4 at %5
4.2 Triggering an Operator Message
Three trigger mechanisms are available; the choice depends on whether the action is a value change, a button press, or a periodic event.
| Mechanism | Where Configured | Behavior | Typical Use |
|---|---|---|---|
| Tag-based operator message (auto) | Tag properties → "Operator message" column | WinCC automatically emits a message every time the tag is written by a user action | Setpoint tags, mode selectors, recipe selection tags |
| Manual operator message via VBS | Button → Event → Mouse click → VBS action | Script calls HMIRuntime.AlarmLogging.CreateOperatorMessage
|
Button press, screen change, custom audit event |
| Manual operator message via C | Button → Event → Mouse click → C action | Script calls printf("User msg", ...) via the AlarmLogging API |
Same as VBS, used when C is preferred for performance |
4.3 Auto-Generated Operator Messages for IO Fields
For I/O fields this is the simplest path. In the Graphics Designer, open the I/O field properties and tick Operator messages → Generate with the format "%s changed <TagName> from %s to %s". Every operator-driven write then produces a structured operator message automatically, with the user identity, computer name, old value, and new value inserted by WinCC. No script is required.
4.4 Manual Operator Message via VBS
Use this when the action is a button press, recipe confirm, or any non-tag event.
' WinCC VBS - Button event: "Confirm Recipe"
Sub OnClick(ByVal Item)
Dim sUser, sRecipe, sResult
sUser = HMIRuntime.Tags("@CurrentUser").Read
sRecipe = HMIRuntime.Tags("RecipeName").Read
sResult = HMIRuntime.Tags("ConfirmResult").Read
' 10 process-value slots supported
HMIRuntime.AlarmLogging.CreateOperatorMessage _
hmiMsgBox, _ ' message class object
"USER_AUDIT", _ ' message class name
1, _ ' message number
sUser, sRecipe, sResult, _
Now, HMIRuntime.ActiveScreen.Name
End Sub
4.5 Querying the Operator Message Archive
Operator messages land in dbo.MSG in the standard alarm archive. The relevant columns:
| Column | Meaning |
|---|---|
MSGTIME |
Trigger time (UTC on the WinCC server) |
MSGSTATE |
1 = came in, 2 = went out, 3 = acknowledged, 6 = operator message |
USERNAME |
Operator identity (if SIMATIC Logon is configured) |
COMPUTERNAME |
Client computer name |
TEXT1 … TEXT10
|
Process values embedded in the message |
CLASSNAME |
Message class — filter on USER_AUDIT for the audit messages |
SELECT MSGTIME, USERNAME, COMPUTERNAME, TEXT1, TEXT2, TEXT3, TEXT4
FROM dbo.MSG
WHERE CLASSNAME = 'USER_AUDIT'
AND MSGTIME > DATEADD(DAY, -7, GETDATE())
ORDER BY MSGTIME DESC;
Reference: Siemens Support FAQ 24325381: Operator Messages in WinCC.
5. Method C: Script-Based Action Logging
When Audit Trail is over-licensed and operator messages are not flexible enough, scripts give full control. The two main targets are user archives and external text/CSV logging. The trade-off is the loss of built-in tamper evidence.
5.1 Writing to a User Archive
User archives (dbo.UA#<ArchiveName>) are flexible SQL tables freely defined in WinCC Explorer with up to 500 columns. They are well suited for high-frequency, schema-fixed audit data.
' VBS - Tag change handler
Sub OnChange(ByVal Item)
Dim oUA
Set oUA = HMIRuntime.UserArchives.Item("UserActions")
oUA.Connect
oUA.InsertField "dtTime", Now
oUA.InsertField "sUser", HMIRuntime.Tags("@CurrentUser").Read
oUA.InsertField "sStation", HMIRuntime.Environment.ProcessHost
oUA.InsertField "sScreen", HMIRuntime.ActiveScreen.Name
oUA.InsertField "sObject", Item.Name
oUA.InsertField "sTag", Item.OutputValue
oUA.InsertField "sOldVal", Item.InputValue
oUA.InsertField "sNewVal", Item.OutputValue
oUA.InsertField "sComment", ""
oUA.Insert ' one row committed
oUA.Disconnect
End Sub
5.2 Appending to a CSV / TXT File
When a database is undesirable (e.g. small edge HMI without SQL), the simplest approach is a file append. Wrap it in a global VBS function:
' Module: LogAction.bas
Const LOG_PATH = "C:\WinCC_Audit\actions.csv"
Sub LogAction(sAction, sParam1, sParam2, sParam3)
Dim fso, ts, sLine
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(LOG_PATH, 8, True) ' 8 = ForAppending
sLine = Format(Now, "yyyy-mm-dd hh:nn:ss") & ";" & _
HMIRuntime.Environment.ProcessHost & ";" & _
HMIRuntime.Tags("@CurrentUser").Read & ";" & _
sAction & ";" & sParam1 & ";" & sParam2 & ";" & sParam3
ts.WriteLine sLine
ts.Close
End Sub
5.3 Calling HMIRuntime.Trace for Development
HMIRuntime.Trace writes to the WinCC diagnostic file WinCC_Sys_<Date>.log in C:\Program Files (x86)\Siemens\Automation\WinCC\Diagnostics. It is enabled in Computer → Properties → Graphics Runtime → Trace and is invaluable for development but should not be considered a long-term audit log because the file is rotated and not checksummed.
6. Method Comparison
| Criterion | Audit Trail | Operator Messages | Scripts (User Archive / File) |
|---|---|---|---|
| License | Yes, separate | No (part of Alarm Logging) | No |
| 21 CFR Part 11 compatible | Yes (SHA-256 chain) | No | No |
| Captures user identity | Automatic | Automatic (with SIMATIC Logon) | Must be read via @CurrentUser
|
| Captures computer | Automatic | Automatic | Must be read via HMIRuntime.Environment.ProcessHost
|
| Captures old / new value | Yes, for audited tags | Only via 10 text placeholders | Yes, any structure |
| Configuration effort | Tick “Audit” per tag / message | Create message class, optional per-IO field | Write VBS for each event |
| Performance overhead | Low, async batched | Low, async batched | 5–25 ms / write to user archive |
| SQL archive table |
AUDIT_TCV, AUDIT_TCM
|
MSG |
User-defined UA#<name>
|
| Tamper-evident | Yes (hash chain) | No | No |
| Display in Alarm Control | Yes (via Audit Viewer control) | Yes (standard Alarm Control filter) | No (requires custom control) |
| Typical regulator use | Pharma, FDA, GxP | General operator logging | Lightweight, ad-hoc |
7. Displaying the Audit in the WinCC Archive Table
The phrase “archive table” in WinCC can mean any of four artifacts:
-
Process value archive table —
dbo.ARCHIVEwith tag values. This is the table accessed through WinCC Online Trend Control and WinCC Online Table Control. -
Alarm archive table —
dbo.MSG, shown through the WinCC Alarm Control. - User archive — custom table shown through the WinCC User Archive Control.
-
Audit archive —
dbo.AUDIT_TCV/dbo.AUDIT_TCM, shown through the WinCC Audit Viewer control.
To present a single screen with all user actions regardless of origin, use a single WinCC Alarm Control with a filter on the USER_AUDIT class and additionally include the Audit Viewer OCX on the same screen, or query both tables through a database connection and a custom ActiveX / WPF panel.
7.1 Alarm Control Filter for Operator Messages
- Insert a WinCC Alarm Control on the screen.
- Open the configuration dialog and add a Message Block for User Name, Computer Name, and the embedded Text1..Text4 columns.
- Open Selection and apply a server-side filter:
- Filter on
Class = USER_AUDIT - Time range: last 24 h, 7 d, 30 d, or user-defined
- Filter on
- Enable Acknowledgeable = No to keep the audit log from being acknowledged (which would itself generate another event).
7.2 Configuring a User Archive Table Control
For the script-based approach, drag a User Archive Table Control onto the screen, point it at the UserActions user archive, and define the columns to display. The control supports filter, sort, export to CSV, and a print button. This is the natural place to show the script-generated audit data.
8. Verification Procedure
- On the WinCC server, start the runtime and log in as a configured user. In a second client, log in as a different user.
- Trigger a controlled action: change a setpoint from each client. Record the time of the change to the second.
- Open the Audit Viewer (if licensed) and confirm that two records appear with the correct user and computer names. Verify the hash chain validates (status bar reads "Audit trail valid").
- Open the Alarm Control filtered on
USER_AUDITand confirm that the operator message is listed with the correct Text1..Text4 content. - For the script path, query the user archive table directly:
SELECT * FROM dbo.UA#UserActions WHERE dtTime > <time-of-action>and verify one record per action with the correct user. - From a third station that is not logged in, repeat the same action and confirm that no user identity is captured (i.e. the audit log shows <unknown> or <No user>), validating that the user filter is working.
9. Troubleshooting Matrix
| Symptom | Probable Cause | Diagnostic | Resolution |
|---|---|---|---|
| Audit records show user <unknown> | SIMATIC Logon not configured or the user logged in outside Logon | Check @CurrentUser tag in diagnostics screen |
Configure SIMATIC Logon, assign user to WinCC group, re-login |
| Operator messages not appearing in alarm control | Message class not set to archive; or alarm control filter excludes the class | Check Alarm Logging → Properties → Archive on the class | Enable long-term archive, clear filter in alarm control |
| Audit Viewer shows "Audit trail invalid" | Hash chain broken; database restored from inconsistent backup | Check dbo.AUDIT_TC for TC_EVENT = 4 entries |
Restore both archive and audit database from same point-in-time; never restore only the archive DB |
VBS CreateOperatorMessage returns nothing |
Message number 1 not defined for the class, or class not visible at runtime | Check the Alarm Logging editor for the class and number | Create the message number, rebuild, redeploy runtime |
| User archive inserts slow (> 200 ms) | Per-insert connect/disconnect, or archive on remote SQL | Profile with SQL Profiler, count sp_UAInsertField calls |
Batch in a 1 s timer, move archive DB to local SSD, raise SQL RAM |
| CSV log file grows unbounded | No rotation | Inspect file size | Add size-based rotation in VBS (e.g. 50 MB per file) or use a scheduled archiving job |
| Operator messages show only Text1, others empty | Placeholder string has fewer than 10 fields, or values not passed correctly | Inspect the format string in the message definition | Use 10 explicit placeholders, pass empty strings for unused |
| Audit records missing on the alarm client but present on the server | Client-server filtering; only one client requests the audit data | Check package assignment of the Audit Viewer OCX | Publish the Audit Viewer OCX in the server package |
10. Security, Retention, and Performance Considerations
- User identity source. Use SIMATIC Logon rather than internal users when the plant has an Active Directory. The internal user table cannot be synchronized with the badge system, and operator accountability breaks the moment the same person is in two operator stations with two different local accounts.
-
Storage sizing. A typical operator action audit record is 0.5–1 kB in
AUDIT_TCVand 0.3–0.5 kB inMSGas an operator message. For a plant with 10 000 actions per day, plan 5–10 MB per day or 2–4 GB per year of audit data. Set archive backup accordingly. - SQL maintenance. The audit database must be included in the same SQL maintenance plan as the rest of the archive (rebuild index weekly, statistics daily). Skipping this causes the audit query in the Alarm Control to slow down over months.
- Time synchronization. All WinCC servers, clients, and SIMATIC Logon servers should be synchronized to the same NTP source within 1 second. Audit times that drift make correlation impossible.
-
Access control on the archive database. Grant
db_datareaderon the archive database to the engineering reporting account only. Never grantdb_owner; that allows deletion of audit rows. - Redundancy. For WinCC/PCS 7 redundant servers, audit data is replicated only if both archive databases are set to Redundant in the WinCC project. Verify the redundancy settings before commissioning.
11. Frequently Asked Questions
Do I need a license for operator messages in WinCC?
No. Operator messages are part of the base WinCC Alarm Logging subsystem and are dispatched like any bit-level alarm. Only the Audit Trail (SHA-256 chain, 21 CFR Part 11) requires a separate license (article 6AV6371-1DX07-4AX0 / 6AV6371-1DX07-4CX0 for the advanced option).
Where exactly do operator messages land in the SQL archive?
In dbo.MSG with MSGSTATE = 6 and the configured message class. The 10 embedded process values are written to TEXT1 through TEXT10; the user identity is in USERNAME and the client in COMPUTERNAME.
How do I show user actions inside the WinCC archive table on an HMI screen?
For operator messages, add a WinCC Alarm Control, enable the User Name, Computer Name, and Text1..Text4 message blocks, and filter on your audit message class. For Audit Trail, use the WinCC Audit Viewer OCX. For script-based logs, use the User Archive Table Control.
Can I track user actions without Audit Trail and without writing to SQL?
Yes. A VBS routine that appends to a CSV file (or to the WinCC trace log via HMIRuntime.Trace) is enough for non-regulated environments. Wrap the call in a global function and invoke it from each button or IO field event that you need to track.
Why does the Audit Viewer report "Audit trail invalid"?
The SHA-256 hash chain in dbo.AUDIT_TC has been broken, almost always because the archive database was restored from a backup taken at a different time than the audit database. Restore both databases from the same point-in-time and re-verify. In V7.4 and earlier, switching from SHA-1 to SHA-256 on an existing project also invalidates the chain and requires re-baselining.
What is the overhead of writing to a user archive for every operator action?
A user-archive insert takes 5–25 ms on a typical WinCC server. For workloads above ~30 actions/second, batch inserts in a 1-second timer rather than one transaction per action; the connect/disconnect pair is the dominant cost, not the actual insert.