How to report user access to a server.

This topic explains how to report user access to a server by using User Access Logging (UAL).


  • The example in this topic is provided in C++. A basic understanding of server roles is recommended.


  1. Register the server role by calling the UalRegisterProduct function. Call this function either at application setup or at first launch.
  2. Allocate and populate a UAL_DATA_BLOB structure.
  3. Start a UAL session by calling the UalStart function. Call this function each time the application starts.
  4. Call the UalInstrument function to log user access.
  5. Call the UalStop function to stop the UAL session and clean up resources.


By default, UAL is configured to update data every 24 hours. For testing purposes, you might want to shorten this interval. To do this, add a registry key of type DWORD that specifies the interval between updates. For example, to shorten the interval to 2 minutes, add the following registry value:

HKLM\System\CurrentControlSet\Control\WMI\Autologger\Sum\PollingInterval = 120000

                  Data type


Restart UAL after creating this registry key.

Complete example

// UalSample.cpp : Defines the entry point for the console application.

#include "stdafx.h"

#include <strsafe.h>
#include <ws2tcpip.h>
#include "ual.h"

GUID RoleIdentifier = { 0x3D1A8E20, 0xAD01, 0x457B, 0xB0, 0x44, 0x79, 0x11, 0x3F, 0x30, 0xC5, 0x4C };
GUID TenantIdentifier = { 0xEB3114F6, 0xD9D0, 0x41EF, 0x81, 0xE3, 0xD3, 0x24, 0xD3, 0xCE, 0x56, 0x62 };

int wmain(int argc, wchar_t* argv[])
    UalRegisterProduct(L"ProductName", L"RoleName", L"{3D1A8E20-AD01-457B-B044-79113F30C54C}");

    UAL_DATA_BLOB ualDataBlob;
    ZeroMemory(&amp;ualDataBlob, sizeof(UAL_DATA_BLOB));
    ualDataBlob.Size = sizeof(UAL_DATA_BLOB);
    ualDataBlob.RoleGuid = RoleIdentifier;
    ualDataBlob.TenantId = TenantIdentifier;

    if (S_OK == UalStart(&amp;ualDataBlob))
        // Log user access IPv4 address.
        ualDataBlob.Address.ss_family = AF_INET;
        InetPton(AF_INET, L"", &amp;(reinterpret_cast<SOCKADDR_IN *>(&amp;ualDataBlob.Address)->sin_addr));

        // Log user access IPv6 address.
        ualDataBlob.Address.ss_family = AF_INET6;
        InetPton(AF_INET6, L"2001:4898:2b:4:551d:3aaa:f951:b202", &amp;(reinterpret_cast<SOCKADDR_IN6 *>(&amp;ualDataBlob.Address)->sin6_addr));

        // Log user access IP address and name.
        StringCchCopy(ualDataBlob.UserName, ARRAYSIZE(ualDataBlob.UserName), L"ClientName");


    return 0;