by on January 4, 2021, in

Per-User Services in Windows: Info & Configuration

It’s a little-known fact that Windows comes with per-user services, background processes that complement the well-known per-machine system services. This article explains what per-user services are, how to create your own, and which configuration options there are.

What Are Per-User Services?

A per-user service is a background process that is started automatically when a user logs on and stopped when the user logs off. Per-user services are run in user context (with the user’s account) as part of the user session. This contrasts with system services that are typically started when the machine is booted, and which run in session 0 with special service accounts such as Local Service or Network Service.

Why Implement Per-User Services?

Some applications need access to data that is only available in user context or in a user session. Other programs need a background process to complement their application window’s functionality. Traditional solutions rely on Explorer to auto-start processes via the registry (HKCU\Software\Microsoft\Windows\CurrentVersion\Run) or the start menu (%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup), to name two popular locations. Per-user services provide an alternative that does not depend on Explorer.

Implementation Details

Requirements

Per-user services are supported on Windows 10 as well as Windows Server 2016 or newer. Windows Server requires Desktop Experience to be installed.

Parent Process of Per-User Services

Per-user services are managed by Service Control Manager (SCM). Their parent process is services.exe.

Templates and Instances

Per-user services are configured via template entries in the service configuration registry key (see below). As the name implies, templates are used as blueprints to create per-user services.

Per-User Service Instance Creation and Deletion

When a user logs on, SCM creates (and starts) per-user service instances on the fly from their respective templates. When a user logs off, per-user service instances are stopped and deleted.

Per-User Service Instance Naming

For each service or driver, a registry entry in the service configuration registry key is required. Since two adjacent registry keys cannot have the same name, SCM needs a scheme to provide individual names to per-user service instances. It does so by appending the logon session’s LUID to the template service’s name. Example:

  • Per-user service template: WpnUserService
  • Per-user service instance: WpnUserService_1080e4

Listing Per-User Service Templates

Many tools and commands, including PowerShell’s Get-Service, omit per-user service templates, returning only instances. To list templates you need to iterate the registry. Here’s a PowerShell snippet for that:

Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services" | ForEach-Object { Get-ItemProperty $_.pspath } | Where-Object {$_.Type -eq 80 -or $_.Type -eq 96} | Format-Table PSChildName, Type, UserServiceFlags

The output looks like this:

PSChildName                        Type UserServiceFlags
-----------                        ---- ----------------
AarSvc                               96                3
BcastDVRUserService                  96
BluetoothUserService                 96
CaptureService                       96                3
cbdhsvc                              96                3
CDPUserSvc                           96                3
ConsentUxUserSvc                     96                3
CredentialEnrollmentManagerUserSvc   80
DeviceAssociationBrokerSvc           96                3
DevicePickerUserSvc                  96                3
DevicesFlowUserSvc                   96                3
LxssManagerUser                      96                3
MessagingService                     96
OneSyncSvc                           96
PimIndexMaintenanceSvc               96                3
PrintWorkflowUserSvc                 96
UdkUserSvc                           96                3
UnistoreSvc                          96                3
UserDataSvc                          96                3
WpnUserService                       96                3

Note that Type is printed as a decimal value (80 corresponds to 0x50 and 96 to 0x60).

Configuring Per-User Services: Registry Settings

Just like system services, per-user services are configured via the subkeys of HKLM\SYSTEM\CurrentControlSet\Services.

Type

SCM uses the Type value to differentiate between per-user services on the one hand and system services and drivers on the other, all of which are configured via the same registry location.

Templates

Per-user service templates have one of the following numbers as Type value:

  • 0x50: individual process (SERVICE_USER_OWN_PROCESS)
  • 0x60: shared process (SERVICE_USER_SHARE_PROCESS)
Instances

Per-user service instances have one of the following numbers as Type value:

  • 0xd0: individual process (SERVICE_USER_OWN_PROCESS + SERVICE_USERSERVICE_INSTANCE + 0x10)
  • 0xe0: shared process (SERVICE_USER_SHARE_PROCESS + SERVICE_USERSERVICE_INSTANCE + 0x10)

Before you ask: I do not know what the meaning of the 0x10 constant is.

When querying all services with a command like sc queryex some per-user services show a Type of 0xf0, even though the Type stored in the service’s registry key is 0xe0. The reason for this is unclear.

UserServiceFlags

To prevent the creation (and subsequent start) of per-user service instances at logon add the following registry value to a per-user service’s template registry key:

  • Value name: UserServiceFlags
  • Value type: REG_DWORD
  • Value name: 0

To revert to the default behavior, delete the UserServiceFlags value or set it to its default of 3.

Creating Per-User Services

To create your own per-user service, specify one of the following as the dwServiceType parameter in the call to CreateService:

  • SERVICE_USER_OWN_PROCESS (0x50)
  • SERVICE_USER_SHARE_PROCESS (0x60)

Per-User Services in Windows 10

Microsoft’s documentation lists various per-user services, but it does not seem to be up to date. At the time of writing this article, the doc’s timestamp read 2017-09-14.

I found the following per-user service templates on my workstation running Windows 10 2009 (20H2):

Key name Display name
AarSvc Agent Activation Runtime
BcastDVRUserService GameDVR and Broadcast User Service
BluetoothUserService Bluetooth User Support Service
CaptureService CaptureService
cbdhsvc Clipboard User Service
CDPUserSvc Connected Devices Platform User Service
ConsentUxUserSvc ConsentUX
CredentialEnrollmentManagerUserSvc CredentialEnrollmentManagerUserSvc
DeviceAssociationBrokerSvc DeviceAssociationBroker
DevicePickerUserSvc DevicePicker
DevicesFlowUserSvc DevicesFlow
LxssManagerUser LxssManagerUser
MessagingService MessagingService
OneSyncSvc Sync Host
PimIndexMaintenanceSvc Contact Data
PrintWorkflowUserSvc PrintWorkflow
UdkUserSvc Udk User Service
UnistoreSvc User Data Storage
UserDataSvc User Data Access
WpnUserService Windows Push Notifications User Service

Questions

I do not have answers to all my questions regarding per-user services. For the sake of completeness, I am listing the open questions here.

User Interactivity

Can per-user services interact with the user? Do they have access to the desktop, can they create windows?

As you may remember, Microsoft moved system services to session 0 for security purposes starting with Vista. The old practice of bundling background code with UI logic in a single system service has been severely restricted. Developers are encouraged to split their code into two components: a system service for the background code and a separate executable for the UI logic. This is where per-user services fit in perfectly. They provide the “missing link” that, up until Windows 10, had to be substituted with one of the per-user auto-start mechanisms.

Therefore I postulate – without having this tested – that per-user services can indeed interact with the user.

Further Reading

Microsoft’s documentation on per-user services can be found here.

Previous Article JavaScript Linting (Static Code Analysis) in VS Code