Programmatically grant a user the ability to log on using remote desktop

rdpwindows

I have several Windows Server 2022 hosts that I need to manage the user rights assignment through automation.

When I manually grant a domain user SeRemoteInteractiveLogonRight rights, they cannot log on using remote desktop, they receive an error stating they are not authorized. If I grant them membership in the local Remote Desktop Users group, they can log on successfully.

The Remote Desktop Users group is granted the SeRemoteInteractiveLogonRight right, but no other rights.

What other permission has that group been granted that I would also need to grant to individual users to enable the ability?

Best Answer

SeRemoteInteractiveLogonRight is a Privilege (you can grant this privilege with the following policy: Allow log on through Remote Desktop Services). As the documentation says:

This policy setting determines which users or groups can access the logon screen of a remote device through a Remote Desktop Services connection[...]

Great! However, as you saw it, the users still receives an error message unless they are members of Remote Desktop Users. That's documented too:

To use Remote Desktop Services to successfully log on to a remote device, the user or group must be a member of the Remote Desktop Users or Administrators group and be granted the Allow log on through Remote Desktop Services right.[...]

Well, this is because there are (at least) two layers:

  1. The Remote Desktop Service security descriptor: Remote Desktop service has its own access list.
  2. The SeRemoteInteractiveLogonRight privilege

The order is relevant here: The user connects to Remote Desktop Services first, and if this is allowed, then Windows will check that the user's token holds the SeRemoteInteractiveLogonRight before opening the user's session.

You can see the Remote Desktop Service security descriptor in the Win32_TSPermissionsSetting WMI class (StringSecurityDescriptor for RDP-Tcp). For example, you can give the StringSecurityDescriptor to the Powershell cmdlet ConvertFrom-SddlString to see its content in a prettier format :

$sddl = Get-WmiObject -class win32_tspermissionssetting -Namespace root\cimv2\terminalservices | where {$_.TerminalName -eq "RDP-Tcp"} |select StringSecurityDescriptor

ConvertFrom-SddlString -Sddl $sddl.StringSecurityDescriptor | select -ExpandProperty DiscretionaryAcl

The output will show you that the Remote Desktop Users group is allowed by default:

[...]
Remote Desktop Users: AccessAllowed
[...]

Basically, granting SeRemoteInteractiveLogonRight will not add the user/group to the Remote Desktop security descriptor, so, Remote Desktop Services denies the logon before Windows even had to check if the SeRemoteInteractiveLogonRight was granted.

You can manually add users or groups in the Remote Desktop Services security descriptor with the AddAccount method: the SDDL will be modified and you'll see your account/group in it. If you granted the SeRemoteInteractiveLogonRight privilege, then you should be able to log on (unless other restrictions are effective on this computer or user, of course).

Now, what happens if you add a user in the Remote Desktop Service security descriptor, without granting SeRemoteInteractiveLogonRight? Well, Remote Desktop Services will accept the connection, but you'll see an error when Windows tries to open your session, and as you can see, this is not an error thrown by the RDP client, the graphics channel is opened and the error is shown by the remote computer:

Unable to logon because the privilege is missing, error message shown

And that's what the security auditing logs tells us in this case (if you are auditing):

Event ID 4625 failed RDP logon

You'll not see this event if the user is not allowed to connect according to the Remote Desktop Service security descriptor because the logon operation fails before Windows had a chance to check privileges.

I strongly recommend you to use the Remote Desktop Users group, because this group is present by default in the Remote Desktop service security descriptor, and is allowed to use the SeRemoteInteractiveLogonRight privilege (unless the server is a DC). You should not need to fiddle with the RDS security descriptor.