I start this blog with a first article in a series I hope to extend about how to run Windows Server using unprivileged accounts.

By “unprivileged accounts” I mean user and service accounts that are not the system account, are not members of the Administrators group and do not hold so-called system privileges.

Note that absolutely none of this is authoritative or directly based on relevant documentation. It’s mostly what I found and figured out and guessed and (in some cases) made up. Some of it may be wrong or dangerous or lead to disaster or confusion. I am not taking responsibility here for anything, not even spelling. Read and digest at your own peril!

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\Administrator> net user

User accounts for \\CHAMPIGNAC

-------------------------------------------------------------------------------
Administrator            benoit                   DefaultAccount
Guest                    legrand                  luke
WDAGUtilityAccount
The command completed successfully.

PS C:\Users\Administrator>

System privileges are those privileges that allow further privilege escalation and typically cause User Account Control to trigger. Among them are SeTcbPrivilege and SeDebugPrivilege. I will cover those later.

PS C:\Users\Administrator> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                            Description                                                        State
========================================= ================================================================== ========
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
SeSystemProfilePrivilege                  Profile system performance                                         Disabled
SeSystemtimePrivilege                     Change the system time                                             Disabled
SeProfileSingleProcessPrivilege           Profile single process                                             Disabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Disabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Disabled
SeBackupPrivilege                         Back up files and directories                                      Disabled
SeRestorePrivilege                        Restore files and directories                                      Disabled
SeShutdownPrivilege                       Shut down the system                                               Disabled
SeDebugPrivilege                          Debug programs                                                     Enabled
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Disabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Disabled
SeUndockPrivilege                         Remove computer from docking station                               Disabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Disabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled
SeCreateGlobalPrivilege                   Create global objects                                              Enabled
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Disabled
SeTimeZonePrivilege                       Change the time zone                                               Disabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Disabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled
PS C:\Users\Administrator>

An “unprivileged account” (also called “restricted account”) does not necessarily have no special privileges and in fact often needs to have them to do its tasks. IT security experts refer to this idea as least privilege principle, the idea that every running program (and logged on users) should have the rights and privileges to do their specific tasks but no more than that.

Making Windows Server usable in a least privilege principle is, in theory, supremely simple, because Windows provides a very fine-grained permission system.

However, most software vendors do not attempt to use it at all and many simply tell users to run everything with Administrators privileges (and, ideally, with the firewall turned off). That’s how they tested their software, after all. (And with one user. They don’t know if it works with two or more users, like it probably would be used in your enterprise.)

There are various mechanisms built into Windows to allow least privilege principle operation, among them Access Control Lists (ACLs) and privileges.

There is also one mechanism built into Windows to allow a secondary layer of security if the first layer is being ignored by vendors (and, very often, MSFT themselves). That mechanism is called Just Enough Admin (JEA) and basically means running the Windows Remote Management Service with full system rights on behalf of restricted users using PowerShell to communicate with the Remote Management Service.

Using GeneralTestService as an example (download at [download generaltestservice]), I will try to explain how to run the service with appropriate privileges and how to access it from an unprivileged (restricted) account.

PS C:\GeneralTestService> dir


    Directory: C:\GeneralTestService


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         7/20/2024   6:57 PM          14848 GeneralTestService.exe
-a----         2/13/2025   1:00 PM             14 GeneralTestService.ps1


PS C:\GeneralTestService> cat .\GeneralTestService.ps1
whoami /groups
PS C:\GeneralTestService>

This shows the GeneralTestService.exe binary (sophisticated people call this an “image”) and a one-line PowerShell script the service will run to show the group members of the running account.

First step, install GeneralTestService:

PS C:\GeneralTestService> sc.exe create GeneralTestService binpath=C:\GeneralTestService\GeneralTestService.exe
[SC] CreateService SUCCESS
PS C:\GeneralTestService> sc.exe qc GeneralTestService
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: GeneralTestService
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 3   DEMAND_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\GeneralTestService\GeneralTestService.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : GeneralTestService
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem
PS C:\GeneralTestService>

This will create the GeneralTestService Windows service and prepare it run as LocalSystem. This is not desirable in the long run. However, start it once with those ridiculous rights to allow it to create registry keys for further configuration:

PS C:\GeneralTestService> sc.exe start GeneralTestService

SERVICE_NAME: GeneralTestService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 3188
        FLAGS              :
PS C:\GeneralTestService> Get-ItemProperty HKLM:\SOFTWARE\AB\GeneralTestService\generaltestservice.exe\

LogName         : Application
EventSourceName : GeneralTestService
TestScript      : A:\NotARealPath\TestScript.ps1
PSPath          : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\AB\GeneralTestService\generaltestservice.exe\
PSParentPath    : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\AB\GeneralTestService
PSChildName     : generaltestservice.exe
PSDrive         : HKLM
PSProvider      : Microsoft.PowerShell.Core\Registry

PS C:\GeneralTestService>

This will start the service and create a registry key
HKLM:\SOFTWARE\AB\GeneralTestService\generaltestservice.exe
(You can create copies of GeneralTestService.exe and install several instances that will result in several keys.)

Note that the service writes several entries to the Application event log:

PS C:\GeneralTestService> Get-WinEvent -LogName Application -MaxEvents 6


   ProviderName: GeneralTestService

TimeCreated                      Id LevelDisplayName Message
-----------                      -- ---------------- -------
2/16/2025 12:33:43 PM             0 Information      Service started successfully.
2/16/2025 12:33:43 PM             0 Information      That was all, folks.
2/16/2025 12:33:43 PM             0 Information      No test script is given and hence will not be executed. Find the script path at [HKLM:\SOFTWARE\AB\GeneralTestService\GeneralTestSer...
2/16/2025 12:33:43 PM             0 Information      I appear to hold the following privileges:...
2/16/2025 12:33:43 PM             0 Information      I am running and my image name is [GeneralTestService.exe]....
2/16/2025 12:33:43 PM             0 Error            I am beginning my run through the event log with an error message to be more noticeable and make things generally more interesting!


PS C:\GeneralTestService>

Point the TestScript property to the actual test script:

PS C:\GeneralTestService> Set-ItemProperty HKLM:\SOFTWARE\AB\GeneralTestService\generaltestservice.exe\ TestScript C:\GeneralTestService\GeneralTestService.ps1
PS C:\GeneralTestService> Get-ItemProperty HKLM:\SOFTWARE\AB\GeneralTestService\generaltestservice.exe\


LogName         : Application
EventSourceName : GeneralTestService
TestScript      : C:\GeneralTestService\GeneralTestService.ps1
PSPath          : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\AB\GeneralTestService\generaltestservice.exe\
PSParentPath    : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\AB\GeneralTestService
PSChildName     : generaltestservice.exe
PSDrive         : HKLM
PSProvider      : Microsoft.PowerShell.Core\Registry



PS C:\GeneralTestService>

Note the individual events GeneralTestService is causing:

1

I am beginning my run through the event log with an error message to be more noticeable and make things generally more interesting!

2

I am running and my image name is [GeneralTestService.exe].
I am running as [WORKGROUP\SYSTEM].

3

I appear to hold the following privileges:
SeAssignPrimaryTokenPrivilege
SeLockMemoryPrivilege
SeIncreaseQuotaPrivilege

(With LocalSystem this list goes on a bit.)

3

Test script [C:\GeneralTestService\GeneralTestService.ps1] found and it gives us this output and error:


GROUP INFORMATION
-----------------

Group Name                             Type             SID          Attributes                                        
====================================== ================ ============ ==================================================
BUILTIN\Administrators                 Alias            S-1-5-32-544 Enabled by default, Enabled group, Group owner    
Everyone                               Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users       Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
Mandatory Label\System Mandatory Level Label            S-1-16-16384                                                   

4

That was all, folks.

5

Service started successfully.

And when it is shut down, it writes a sixth and seventh message:

6

I am shutting down.

7

Service started successfully.


This service now runs with full system rights and absolutely shouldn’t.

There are several ways to tame the service, which fall into three broad categories:

  1. Deprivilege the service itself.
  2. Use a less privileged account to run the service.
  3. Use no account to run the service and assign further rights and privileges to the service itself.

The first way will continue running the service under the identity of the system (the computer) itself but with fewer privileges.


1.1. Reduce the privileges of the service itself.

This can be done with the service regardless of the identity it runs under but does nothing to stop the service from abusing rights given to the running account in ACLs.

PS C:\GeneralTestService> sc.exe privs GeneralTestService SeShutdownPrivilege
[SC] ChangeServiceConfig2 SUCCESS
PS C:\GeneralTestService> Restart-Service GeneralTestService
PS C:\GeneralTestService> sc.exe qprivs GeneralTestService
[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: GeneralTestService
        PRIVILEGES       : SeShutdownPrivilege
PS C:\GeneralTestService>

GeneralTestService now reports in the Application event log that the number of its privileges has been drastically reduced:

I appear to hold the following privileges:
SeShutdownPrivilege
SeChangeNotifyPrivilege

The system privileges are gone, only SeShutdownPrivilege and SeChangeNotifyPrivilege remain. (The reason SeChangeNotifyPrivilege remains is because absolutely everything has that privilege. It’s supposed to be this way.)

This is but an example, but this would make an efficient service to reboot a computer. Note that the service can still touch every object on the computer, including files, processes, registry keys etc.. Privilege dropping like this should only be used in combination with other restricting methods.


1.2. Use one of the less privileged versions of the local system account.

There are two such: LocalService and NetworkService. LocalService has slightly more rights than NetworkService but NetworkService can access the network.

First, let’s remove the privilege restriction the service and then switch it to the LocalService account:

PS C:\GeneralTestService> sc.exe privs GeneralTestService /
[SC] ChangeServiceConfig2 SUCCESS
PS C:\GeneralTestService> sc.exe qprivs GeneralTestService
[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: GeneralTestService
        PRIVILEGES       :
PS C:\GeneralTestService> sc.exe config GeneralTestService obj="NT AUTHORITY\LocalService"
[SC] ChangeServiceConfig SUCCESS
PS C:\GeneralTestService> Restart-Service GeneralTestService
PS C:\GeneralTestService>

The service now reports in the Application log:

I am running and my image name is [GeneralTestService.exe].
I am running as [NT AUTHORITY\LOCAL SERVICE].

and

I appear to hold the following privileges:
SeAssignPrimaryTokenPrivilege
SeIncreaseQuotaPrivilege
SeSystemtimePrivilege
SeAuditPrivilege
SeChangeNotifyPrivilege
SeImpersonatePrivilege
SeCreateGlobalPrivilege
SeIncreaseWorkingSetPrivilege
SeTimeZonePrivilege

The LocalService and NetworkService accounts are effective ways of reducing a service’s rights but still let it run under the identity of the computer itself.


1.3. Write-restrict the service.

A third way, which like the first can be combined with other methods, is to write-restrict the service. When this is done, the service has all the read rights you would expect it to have, but cannot write anywhere not specifically allowed. (The way it works is that a group NT AUTHORITY\WRITE RESTRICTED is implicitly in a deny entry at the top of every ACL in the system but if that group is added with write permissions or full access of if the service’s account or the service itself is added with write permissions or full access, the deny entry is overruled, i.e. never reached.)

PS C:\GeneralTestService> sc.exe config GeneralTestService obj="NT AUTHORITY\SYSTEM"
[SC] ChangeServiceConfig SUCCESS
PS C:\GeneralTestService> sc.exe sidtype GeneralTestService restricted
[SC] ChangeServiceConfig2 SUCCESS
PS C:\GeneralTestService> Restart-Service GeneralTestService
PS C:\GeneralTestService>

This reconfigured the service to run under LocalSystem again but with write-restrictions.

The service now reports in the Application log as a group membership (a result of the whoami /groups command in GeneralTestService.ps1):

NT AUTHORITY\WRITE RESTRICTED Well-known group S-1-5-33 Mandatory group, Enabled by default, Enabled group

This group membership will now stop the service from using its system rights for writing, anywhere; unless that group, the service’s account, or the service itself is specifically allowed to write to the object.

Note that this often doesn’t work as some software vendors make depecrated API calls that require write access.

To undo this:

PS C:\GeneralTestService> sc.exe sidtype GeneralTestService unrestricted
[SC] ChangeServiceConfig2 SUCCESS
PS C:\GeneralTestService>

There is also a third sidtype “none”.

unrestricted:
The service has a security identifier NT Service\ServiceName

restricted:
The service has a security identifier NT Service\ServiceName and is a member of NT AUTHORITY\WRITE RESTRICTED

none:
The service does not have a security identifier referring to the service itself


2.1 Use a local user account to run the service

This the method that basically came to Windows from Unix and can usually be found with ported services like PostgreSQL.

It is really not recommended.

PS C:\GeneralTestService> net user

User accounts for \\CHAMPIGNAC

-------------------------------------------------------------------------------
Administrator            benoit                   DefaultAccount
Guest                    legrand                  luke
WDAGUtilityAccount
The command completed successfully.

PS C:\GeneralTestService> sc.exe config GeneralTestService obj=.\benoit password=SomeSecretPassword
[SC] ChangeServiceConfig SUCCESS
PS C:\GeneralTestService> sc.exe start GeneralTestService
[SC] StartService FAILED 1069:

The service did not start due to a logon failure.

PS C:\GeneralTestService>

But the local account has to be allowed to log on as a service. This can be done in secpol.msc or using the AccountRights tool from ABTokenTools (see Introduction).

PS C:\GeneralTestService> & 'C:\Program Files\ABTokenTools\AccountRights.exe' benoit
0
PS C:\GeneralTestService> & 'C:\Program Files\ABTokenTools\AccountRights.exe' benoit SeServiceLogonRight
0
SeServiceLogonRight
1
PS C:\GeneralTestService> sc.exe start GeneralTestService

SERVICE_NAME: GeneralTestService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 4736
        FLAGS              :
PS C:\GeneralTestService>


2.2 Use a domain user account to run the service

This is equally not recommended and in some sense worse than using a local account. Recall that any user account password is known to someone and in the case of a user account used to run a service it is probably known to several people. Those people now all have the same access to the computer as the service does, and it will be difficult finding out who (ab)used the service’s account when and to do what.

Configuration of the service is done the same as for the local user account, just with the domain’s name (here “example”) replacing the “.”:

PS C:\GeneralTestService> sc.exe config GeneralTestService obj=example\benoit password=SomeEvenMoreSecretPassword


2.3 Use a domain service account to run the service

This is the recommended way to run a service on a domain-joined computer.

A domain service account, also known as a managed service account or group managed service account (gMSA) retrieves its current password from a domain controller when the service starts and there is no known (to the user) password for it. It also cannot log on interactively and is automatically assigned a few privileges required for normal services.

Prepare a managed service account in the domain:

PS C:\Users\Administrator> New-ADServiceAccount TestService -DNSHostName GeneralTestService.example.com
PS C:\Users\Administrator> Set-ADServiceAccount TestService -PrincipalsAllowedToRetrieveManagedPassword champignac$
PS C:\Users\Administrator>

And then configure the service to use the service account. Note that you likely have to reboot the target computer first.

PS C:\GeneralTestService> sc.exe config GeneralTestService obj=netneurotic\TestService$
[SC] ChangeServiceConfig SUCCESS
PS C:\GeneralTestService> sc.exe qmanagedaccount GeneralTestService
[SC] QueryServiceConfig2 SUCCESS

ACCOUNT MANAGED : TRUE
PS C:\GeneralTestService> sc.exe start GeneralTestService

SERVICE_NAME: GeneralTestService
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 1512
        FLAGS              :
PS C:\GeneralTestService>

You want to make sure that sc.exe qmanagedaccount says “TRUE” to ensure that the system understood that this is a managed account without a password known to a user.

To make sure that a domain controller is reachable for password retrieval when the service starts, configure dependencies on relevant services with an automatic start:

PS C:\GeneralTestService> sc.exe config GeneralTestService depend=netlogon/w32time start=auto
[SC] ChangeServiceConfig SUCCESS
PS C:\GeneralTestService> sc.exe qc GeneralTestService
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: GeneralTestService
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\GeneralTestService\GeneralTestService.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : GeneralTestService
        DEPENDENCIES       : netlogon
                           : w32time
        SERVICE_START_NAME : example\TestService$
PS C:\GeneralTestService>


3.1 Do not use an account to run the service

This is the recommended method to start a non-system service on a computer that is not domain-joined. It does not use an account at all but simply uses the service itself as a security principal which can then be added to groups and ACLs and can be assigned privileges.

PS C:\GeneralTestService> sc.exe config GeneralTestService obj="NT Service\GeneralTestService"
[SC] ChangeServiceConfig SUCCESS
PS C:\GeneralTestService> Restart-Service GeneralTestService
PS C:\GeneralTestService>

The event log now reports

I am running and my image name is [GeneralTestService.exe].
I am running as [NT Service\GeneralTestService].

and

I appear to hold the following privileges:
SeChangeNotifyPrivilege
SeImpersonatePrivilege
SeCreateGlobalPrivilege
SeIncreaseWorkingSetPrivilege

These are the three privileges a normal service needs plus SeChangeNotifyPrivilege which everyone has.

SeImpersonatePrivilege allows the service to impersonate users in threads, for example when a user uses the service and needs the services to act on his behalf.

SeCreateGlobalPrivilege allows the service to create objects that are visible in all sessions. If I ever find an example, I will write about it.


Giving access to controlling the service to users or groups

In most cases you want to allow someone to start and stop or otherwise manipulate a service.

This can be done in four different ways:

  1. Make every user a member of Administrators. This is the preferred solution recommended by software vendors who really could not care less about security on their customers’ computers.
  2. Use a Just-Enough-Admin configuration to allow certain users to manipulate certain services. This can quickly become very complicated.
  3. Write another service to control the service. This is stupid.
  4. Set permissions on the service to allow a user, better a specific group, whatever access they need.

I will only describe the fourth method. This should be done when the service is being installed.

We are assuming the user benoit needs access.

PS C:\GeneralTestService> sc.exe sdshow GeneralTestService

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
PS C:\GeneralTestService>

The output is a Security Descriptor Definition Language string.

To read it, simply note that what comes after D: is the Discretionary Access Control List (DACL) and what comes after S: is the System Access Control List (SACL).

The DACL is relevant to us. We can ignore the SACL.

Each bracketed part in the DACL is a Access Control Entry (ACE) and reads like this when split at “;”:

  1. A for Allow, D for Deny\
  2. empty/irrelevant\
  3. Permissions as a number of string of characters\
  4. empty/irrelevant\
  5. empty/irrelevant\
  6. Security Principal affected, given as Security Identifier (SID) or short name (“SY” is the system account)\

To add a new group giving it the same rights as the Administrators group we need to create a new group and find the entry for Administrators. The short name for Administrators is BA (for Builtin\Administrators). Then we add another entry to the DACL with our new group as the Security Principal affected.

A group specifically created to give access to a certain object that way is called a Resource Group. Perhaps it should be given a clear, memorable name.

PS C:\GeneralTestService> net localgroup RG_GeneralTestService_RW /add
The command completed successfully.

PS C:\GeneralTestService> net localgroup RG_GeneralTestService_RW /add benoit
The command completed successfully.

PS C:\GeneralTestService> Get-LocalGroup RG_GeneralTestService_RW

Name                     Description
----                     -----------
RG_GeneralTestService_RW


PS C:\GeneralTestService> Get-LocalGroup RG_GeneralTestService_RW|Format-List


Description     :
Name            : RG_GeneralTestService_RW
SID             : S-1-5-21-344341352-2539047333-2300305637-1007
PrincipalSource : Local
ObjectClass     : Group



PS C:\GeneralTestService> sc.exe sdshow GeneralTestService

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
PS C:\GeneralTestService> sc.exe sdset GeneralTestService "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-344341352-2539047333-2300305637-1007)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"
[SC] SetServiceObjectSecurity SUCCESS
PS C:\GeneralTestService> sc.exe sdshow GeneralTestService

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-344341352-2539047333-2300305637-1007)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
PS C:\GeneralTestService>

User benoit via the group RG_GeneralTestservice_RW now has the same right to manipulate the service as Administrators do.

Resource groups are a powerful tool to make granting access easier. Whenever you create an object, like a service, that is not a file, like a service, you should probably create one or two resource groups to manage access.