Overview
Siemens WinCC (TIA Portal WinCC, WinCC Professional, WinCC Runtime Advanced, and WinCC V7) exposes a small set of system tags that reflect the current operator session. By binding visibility, enable, or operator-input permissions on graphical objects to those system tags, engineers can build role-based HMI screens without writing complex user-management code. The two system tags at the center of this pattern are:
-
@CurrentUser– character string with the internal user name currently logged in to the runtime. -
@CurrentUserName– character string with the display name of the user, typically the full name entered in the user administration.
Both tags are updated automatically by WinCC when an operator logs in, logs out, or is switched by User-Change. Any global C action or VBS action triggered by a change of @CurrentUser can translate that user name into a Boolean tag, which is then used as a dynamization source for the Visibility or Enable property of buttons, screens, and other objects.
This article shows two production-ready implementations (one in C, one in VBS), the required project settings, and the diagnostics used to verify the wiring. Examples target WinCC V7.5 / V7.5 SP2 and WinCC Professional V16-V18, but the same system tags exist in TIA Portal WinCC from V13 onward.
Prerequisites
- WinCC Runtime installed and configured with at least one operator station.
- User administration enabled in the WinCC project. The project must contain a user group (for example Administrators) with at least one user (for example admin) and a second group (for example Operators) with at least one user (for example operator).
- Runtime licensing that supports the number of simultaneous users (WinCC V7: 128, 256, 512, 1024 power tags and corresponding user licenses).
- Internal tags of correct data type:
- Character tag
CurrentUserMirror(Type: Text tag, 8-bit character set, Length 32) bound to@CurrentUserif you want a copy available to VBS. - Boolean tags
ShowAdminButton,ShowOperatorButton,EnableAckButton(Type: Binary tag).
- Character tag
- For the C implementation, the project must be configured to use the WinCC API; the
PWRT_api.hheader is included in every standard WinCC installation under...\Siemens\Automation\WinCC\aplib\.
strcmp. The runtime itself is case-sensitive for @CurrentUser. Always store user names exactly as configured in the user administration to avoid failed comparisons.Step 1: Configure User Administration and Authorization Levels
Open the WinCC Explorer (V7) or the TIA Portal project tree (V16+) and configure two user groups. The example below uses the standard UserAdministrator role concept extended with operator-level visibility.
| Group | Authorization (No.) | Typical Member | Password Policy |
|---|---|---|---|
| Administrators | WebUX / Higher Level / Change Runtime | admin | Strong, 8+ chars, upper/lower/digit |
| Operators | Operator level (read-only process values) | operator | Standard, 6+ chars |
| Service | Service / Configuration | service | Strong, rotation every 90 days |
In WinCC V7 use the User Administrator editor (right-click the WinCC Explorer root → Open User Administration). In TIA Portal WinCC, navigate to Runtime settings → User administration. For guidance on the underlying user/role model, refer to the Siemens manual WinCC V7.5 SP2 Documentation and the TIA Portal WinCC Professional V18 System Manual.
Step 2: Create the Boolean Tags and the User Mirror
Inside the tag management, create the following internal tags. They will be used as the source for property dynamization.
| Tag Name | Data Type | Length | Purpose |
|---|---|---|---|
| ShowAdminButton | Binary | 1 bit | Drives visibility of admin-only buttons |
| ShowOperatorButton | Binary | 1 bit | Drives visibility of operator buttons |
| EnableAckButton | Binary | 1 bit | Enables the alarm acknowledge button |
| CurrentUserMirror | Text tag 8-bit | 32 | Mirror of @CurrentUser for VBS access |
To mirror @CurrentUser to CurrentUserMirror, open a global C action and add a single line:
strcpy(CurrentUserMirror, GetTagChar("@CurrentUser"));
Trigger this action on change of @CurrentUser (recommended) or cyclically every 2 seconds. A 2 s cyclic trigger is the de-facto safe default because it absorbs the runtime overhead of GetTagChar and avoids hammering the tag manager during a logout storm.
Step 3: Implement the Global C Action
The reference solution uses a single global C action that evaluates the current user and writes the visibility bits. Save the file as UserAuth.c in the WinCC project library, then create a global action with a 2 s cyclic trigger.
#include "apdefap.h"
#include "PWRT_api.h"
int gscAction( void )
{
char* CUser = NULL;
CUser = GetTagChar("@CurrentUser");
if ( CUser == NULL )
{
SetTagBit("ShowAdminButton", 0);
SetTagBit("ShowOperatorButton", 0);
SetTagBit("EnableAckButton", 0);
return 0;
}
/* Administrator role */
if ( strcmp(CUser, "admin") == 0 )
{
SetTagBit("ShowAdminButton", 1);
SetTagBit("ShowOperatorButton", 0);
SetTagBit("EnableAckButton", 1);
}
/* Operator role */
else if ( strcmp(CUser, "operator") == 0 )
{
SetTagBit("ShowAdminButton", 0);
SetTagBit("ShowOperatorButton", 1);
SetTagBit("EnableAckButton", 1);
}
/* Service role */
else if ( strcmp(CUser, "service") == 0 )
{
SetTagBit("ShowAdminButton", 1);
SetTagBit("ShowOperatorButton", 1);
SetTagBit("EnableAckButton", 1);
}
/* Unknown or logged-out state */
else
{
SetTagBit("ShowAdminButton", 0);
SetTagBit("ShowOperatorButton", 0);
SetTagBit("EnableAckButton", 0);
}
return 0;
}
The C compiler in WinCC requires the #pragma code directives around any call that uses WinCC-API functions exported from useadmin.dll. The pattern from the original community sample is:
#pragma code("useadmin.dll")
#include "PWRT_api.h"
#pragma code()
Insert this block at the top of the C file. Without it, the linker cannot resolve GetTagChar and SetTagBit at compile time and the action will return runtime errors of the form GetTagChar: function not found (Error 0x80040438).
Step 4: Implement the Equivalent in VBS
VBS is the preferred language for TIA Portal WinCC and is also supported in WinCC V7 from V7.3 onward. The script below performs the same role-to-bit mapping and is triggered on the change of @CurrentUser:
Sub OnChange_Trigger(ByVal Item)
Dim strValue
Dim intRet
strValue = HMIRuntime.Tags("@CurrentUser").Read(1)
Select Case strValue
Case "admin"
HMIRuntime.Tags("ShowAdminButton").Write 1
HMIRuntime.Tags("ShowOperatorButton").Write 0
HMIRuntime.Tags("EnableAckButton").Write 1
Case "operator"
HMIRuntime.Tags("ShowAdminButton").Write 0
HMIRuntime.Tags("ShowOperatorButton").Write 1
HMIRuntime.Tags("EnableAckButton").Write 1
Case "service"
HMIRuntime.Tags("ShowAdminButton").Write 1
HMIRuntime.Tags("ShowOperatorButton").Write 1
HMIRuntime.Tags("EnableAckButton").Write 1
Case Else
HMIRuntime.Tags("ShowAdminButton").Write 0
HMIRuntime.Tags("ShowOperatorButton").Write 0
HMIRuntime.Tags("EnableAckButton").Write 0
End Select
End Sub
Attach this script to the @CurrentUser change trigger by opening the tag's properties in the Graphics Designer, switching to the Events tab, selecting Change, and binding the VBS action. This pattern is documented in the Siemens Knowledge Base article WinCC Professional V18 System Manual, section 11.4 "User-dependent operator control".
Step 5: Bind the Bits to Object Visibility
Open the screen that should hide or show controls based on role. For each button or object:
- Right-click the object → Properties → Miscellaneous → Visibility (or Appearance / Display in TIA Portal).
- Select Dynamic dialog for V7 or Animation → Visibility for TIA Portal.
- Choose the Boolean tag (e.g.
ShowAdminButton). - Map
0 = Invisible,1 = Visible. - Confirm with OK and repeat for the other buttons.
For the Enable property (greyed-out but still visible), repeat the process but select Enable / Operator enable in the property tree. Some safety-critical functions should use Operator enable rather than Visibility to remain audit-trail compliant.
Verification
Run the project in runtime (RT) mode and execute the following checklist:
- Open the WinCC Tag Simulation (V7) or the HMI Tag Table (TIA) and confirm
CurrentUserMirrortracks@CurrentUserwithin one trigger cycle. - Log in as
operator. The Operator button should be visible within 2 s; the Admin button should remain hidden. - Log out. All three role bits must drop to 0 within 2 s. This protects against the well-known "ghost user" problem on shared panels.
- Log in as
admin. The admin-only button should appear, the operator-only button should disappear (per the mapping table in Step 3). - Trigger an Autologout from the user administration (default 15 min). Confirm the visibility state returns to "no user".
For an additional automated check, attach a button with the following one-line VBS to any diagnostics screen:
MsgBox "User: " & HMIRuntime.Tags("@CurrentUser").Read(1) & vbCrLf & _
"ShowAdmin: " & HMIRuntime.Tags("ShowAdminButton").Read(1)
Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
| Bits never change; user is logged in | Global action not triggered or trigger cycle too long | Set trigger to change of @CurrentUser or reduce cycle to 1 s; verify the action is Active in the project properties |
C action: GetTagChar returns NULL continuously |
User administration disabled or no active session | Enable User administration in project properties; verify at least one user is configured |
| Bits toggle but button still visible | Wrong dynamization source selected | Open the property dialog and confirm the tag name is the internal ShowXxx bit, not the @CurrentUser string |
| VBS error 0x8004A005 at startup | VBS action attached to a tag that does not exist in the project | Verify all tag names in the script exist in the tag management; TIA Portal requires exact spelling including case |
| Login acknowledged but bits delayed by 30 s | Cyclic trigger set to 30 s by default | Reduce the trigger cycle; consider the 2 s default from this guide |
| One user sees all buttons (no role mapping) | Case mismatch: "Operator" vs "operator" | Match the string exactly. Use strcmpi in C or LCase in VBS for case-insensitive comparison |
| Logout does not hide the buttons | Action not re-evaluated on logout | Trigger on change of @CurrentUser, not on a fixed cycle that may miss the empty-string transition |
Security Considerations
Object visibility is a usability feature, not a security boundary. If the HMI action that the button triggers writes back to a controller tag (for example, setting a setpoint or acknowledging an alarm), the same write must be guarded by an authorization check in the PLC or by a WinCC Operator enable tied to the user group. Siemens explicitly recommends this defense-in-depth model in the WinCC Security Guidelines. The current user name is also available in the S7-1500 via the OPC UA ServerInterface so that the PLC can validate the operator's role before accepting a write.
Avoid hard-coding cleartext passwords in any C or VBS file. WinCC stores user passwords in the User Administrator database, and a script that reads @CurrentUser only sees the user name, not the password. If your project integrates with Active Directory, configure WinCC to use Windows authentication; this lets the IT department enforce password rotation, complexity, and account lockout policies defined in your corporate directory.
Performance and Scalability Notes
Each GetTagChar and SetTagBit call in C crosses the WinCC API boundary and acquires the tag manager mutex. A 2 s cycle with three SetTagBit calls and one GetTagChar call adds approximately 0.4-0.8 % CPU on a typical WinCC V7 server (Intel Xeon E3, 8 GB RAM, 5000 tags). For projects with hundreds of users or 50+ role-dependent screens, prefer the change-triggered VBS variant: it executes only on real role transitions and consumes no background CPU.
If your project also exposes screens through WinCC Unified or WebUX, replicate the same ShowXxx bits in the Unified tag namespace and use JavaScript animations on the WebUX client. The C/VBS server-side logic is unchanged; only the WebUX client animation differs.
Alternative: Dynamize Visibility Directly from a String Tag
When the visibility rule is a simple comparison, the visibility property of a WinCC object can be dynamized directly from @CurrentUser using an indirect tag or a Dynamic dialog with a C expression:
GetTagChar("@CurrentUser") == "admin"
This avoids the extra boolean tag for simple cases. However, it re-executes the API call on every repaint of the object, which can be costly for screens that contain many dynamic objects. The boolean-tag approach in Step 3 is therefore preferred for production screens.
Field-Commissioning Checklist
- RT license: Confirm the user count covers all simultaneous operators.
- Cycle: Trigger the action on change of @CurrentUser first; fall back to 2 s cyclic only if the change event proves unreliable in the field.
- Audit trail: Enable the User Administrator change log in the project properties to log every login, logout, and failed attempt.
-
PLC mirror: Write
@CurrentUserinto a string tag on the controller every 5 s so that the PLC can apply role-based write protection on critical setpoints. -
Backup user: Always configure a fallback user (for example
master) with the User Administrator role so that a forgotten password can be recovered with the Siemens support tool.
Which WinCC versions support the @CurrentUser system tag?
All WinCC V7 versions from V7.0 SP3 and all TIA Portal WinCC variants from V13 onward expose @CurrentUser and @CurrentUserName. WinCC flexible RT and the Comfort/MTP panels use a similar but not identical tag set; check the panel's manual for the exact tag name on those devices.
Is a 2 s cyclic trigger fast enough for logout?
For most operator panels, yes. The 2 s cycle is the standard practice to balance CPU load and reactivity. If the application must react to logout within 250 ms (for example, safety lockouts), trigger the action on the change of @CurrentUser event instead of cyclically.
Can the C action compare the user against a group instead of a name?
Yes. Use GetGroupName from PWRT_api.h to retrieve the group membership of the current user and compare against group names. The API also exposes GetUserAuthorization to query the authorization number assigned to a group, which is the recommended way to drive role-based access in production code.
What happens if the action writes to a tag that is being read by a faceplate at the same instant?
WinCC's tag manager serializes tag access, so there is no torn read. The faceplate may observe a one-cycle-old value, which is acceptable for visibility bits because they are evaluated at the next repaint interval.
Can I combine C and VBS in the same project?
Yes. Most production projects use C for high-frequency tag manipulation (alarm logging, archive compression) and VBS for screen-level events. The two languages coexist; just make sure they do not write to the same tag from competing triggers, otherwise a race condition can occur.