- How to Allow Non-Admin Users to Start/Stop Windows Service?
- Setting Windows Service Permissions Using the SC.exe (Service controller) Tool
- Using the SubInACL to Allow a User to Start/Stop/Restart Service
- How to Change Windows Service Permission Using Process Explorer?
- Setting Windows Service Permissions Using PowerShell
- Using Security Templates to Manage Service Permissions
- How to Grant Users Rights to Manage a Service using GPO?
- Get-GPPermission
- Syntax
- Description
- Examples
- Example 1: Get the permission level for group on the specified GPO
- Example 2: Get the permission level for group on the specified GPO with the specified GUID
- Example 3: Get the permission level for all security principals on the specified GPO
- Example 4: Get the display name of each GPO for a specific permissions
- Parameters
- Inputs
- Outputs
- Notes
How to Allow Non-Admin Users to Start/Stop Windows Service?
By default, common (non-admin) users cannot manage Windows services. This means that users cannot stop, start, restart, or change the settings/permissions of Windows services. In some cases, it is necessary for a user to have the permissions to restart or manage certain services. In this article we’ll look at several ways to manage the permissions for Windows services. In particular, we’ll show you how to allow a non-admin user to start, stop and restart a specific Windows service by granting the appropriate permissions.
Suppose, you need to grant the domain account contoso\tuser the permissions to restart the Print Spooler service (service name – spooler). When the non-admin tries to restart the service, an error appears:
There is no simple and convenient built-in tool to manage services permissions in Windows. We’ll consider some ways to grant the permissions to a user to manage service:
Setting Windows Service Permissions Using the SC.exe (Service controller) Tool
A standard built-in Windows method to manage system service permissions supposes using the sc.exe (Service Controller) tool. The main problem with using this utility is the complex syntax of the service permissions format (the SDDL format — Security Description Definition Language).
You can get the current permissions for a Windows service as an SDDL string like this:
sc.exe sdshow Spooler
What do all these symbols mean?
The first letter after brackets means: allow (A) or deny (D).
The next set of symbols is assignable permissions.
The last 2 characters are the objects (user, group or SID) that are granted permissions. There is a list of predefined groups.
Instead of a predefined group, you can explicitly specify a user or group by SID. To get the SID for the current user, you can use the command:
Or you can find the SID for any domain user using the Get-ADUser cmdlet:
Get-ADUser -Identity ‘sadams’ | select SID
You can get the SID of the AD security group using the Get-ADGroup cmdlet:
In order to assign the SDDL permissions string for a specific service, you can use the sc sdset command. For example, the permissions can be granted to a user with the following command:
sc sdset Spooler «D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;S-1-5-21-2133228432-2794320136-1823075350-1000)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)»
Using the SubInACL to Allow a User to Start/Stop/Restart Service
It is easier to use a command line tool SubInACL from the Sysinternals (by Mark Russinovich) to manage the service permissions. The syntax of this tool is much easier and more convenient. Here is how you can grant the restart permissions for a service using the SubInACL:
- Download subinacl.msi from this webpage (https://www.microsoft.com/en-us/download/details.aspx?id=23510) and install it on the target system;
- In the elevated command prompt, go to the directory containing the tool: cd “C:\Program Files (x86)\Windows Resource Kits\Tools\»
- Run the command: subinacl.exe /service Spooler /grant=contoso\tuser=PTO
If you did everything right, the service should restart.
subinacl.exe /service Spooler /revoke=contoso\tuser
How to Change Windows Service Permission Using Process Explorer?
You can change Windows service permissions using one more Sysinternals utility – Process Explorer. Run the Process Explorer as administrator and find the process of the service you need. In our example, this is spoolsv.exe (the spooler executable – C:\Windows\System32\spoolsv.exe ). Open the process properties and click the Services tab.
Click the Permissions button and add the user or group in the window that opens. After that select the permissions that you want to assign (Full Control/Write/Read).
Setting Windows Service Permissions Using PowerShell
In TechNet gallery there is a separate unofficial PowerShell module for managing permissions for different Windows objects – PowerShellAccessControl Module (you can download it here). This module also allows you to manage the service permissions. Install this module and import it into your PS session:
You can get the effective permissions for a specific Windows service from PowerShell like this:
Get-Service spooler | Get-EffectiveAccess -Principal corp\tuser
To allow non-admin user to start and stop spooler service, run the command:
Get-Service spooler | Add-AccessControlEntry -ServiceAccessRights Start,Stop -Principal corp\tuser
Using Security Templates to Manage Service Permissions
A visual (but requiring more actions) graphical way to manage service permissions is using Security Templates. Open mmc.exe console and add the Security Templates snap-in.
Create a new security template (New Template).
Specify the name for the new template and go to the System Services section. In the list of services select the service Print Spooler and open its properties.
Select the startup mode (Automatic) and click Edit Security.
Using the Add button, add a user account or a group to grant permissions to. In our case, Start, stop and pause permission is enough.
Save this template.
If you open this file, you can see that the information about the permissions is saved in the SDDL format, mentioned earlier. The string obtained in this way can be used as an argument of the sc.exe command.
[Unicode]
Unicode=yes
[Version]
signature=»$CHICAGO$»
Revision=1
[Service General Setting]
«Spooler»,2,»D:AR(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;RPWPDTRC;;;S-1-5-21-3243688314-1354026805-3292651841-1127)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)»
Now you only have to create a new database (Open Database) using the Security Configuration and Analysis snap-in and import your Security Template from the file Spooler User Rights.inf.
Apply this template by selecting Configure Computer Now option from the context menu.
Now you check that the user can allow manage the Print Spooler service under non-admin account.
How to Grant Users Rights to Manage a Service using GPO?
If you have to grant permissions to users to start/stop a service multiple servers or domain computer, it’s easier to use Group Policy (GPO) features:
- Create a new GPO or edit the existing one, link it to the necessary Active Directory container (OU) with the computer objects . Go to the policy section Computer configuration -> Windows Settings -> Security Settings -> System Services;
- Find the Spooler service and grant permissions to the users like in the method described above. Save the changes;
The security settings for all services for which you changed the default permissions are stored in their own registry key HKLM\System\CurrentControlSet\Services\ \Security in the Security parameter of the REG_BINARY type.
This means that one of the ways to set service permissions on other computers is to export/import this registry parameter (including through a GPO).
So, we looked at several ways to manage the Windows service permissions, which allow you to grant any permissions for system services to non-admin user. If the user requires remote access to the service, without granting it local logon or RDP access permissions, you must allow the user to connect remotely and enumerate services via Service Control Manager.
Get-GPPermission
Gets the permission level for one or more security principals on a specified GPO.
Syntax
Description
The Get-GPPermission cmdlet gets the permission level for one or more security principals on the specified Group Policy Object (GPO). You can use the TargetName and TargetType parameters to specify a user, security group, or computer for which to get the permission level. You can use the All parameter to get the permission level for each security principal that includes: user, security group, or computer. This only works for a user, security group, or computer that has permissions on the GPO. You can specify the GPO by its display name or by its GUID.
Examples
Example 1: Get the permission level for group on the specified GPO
This command gets the permission level for the Domain Users group on the GPO named TestGpo.
Example 2: Get the permission level for group on the specified GPO with the specified GUID
This command gets the permission level for the Domain Admins group on the GPO with the GUID fa4a9473-6e2a-4b78-175e68d97bde in the Sales.Contoso.com domain. The DC1.sales.contoso.com domain controller is contacted to complete the operation.
If the domain of the user that is running the session (or, for startup and shutdown scripts, the computer) is different from the sales.contoso.com domain, a trust must exist between the two domains, or the command fails.
Example 3: Get the permission level for all security principals on the specified GPO
This command gets the permission level for each security principal that has permissions on the GPO named TestGPO.
Example 4: Get the display name of each GPO for a specific permissions
This command lists the display name of each GPO (in the domain) on which the specified security principal has permissions.
First, Get-GPO is used to retrieve all the GPOs in the domain (Get-GPO -All). Then, the collection is piped into the foreach-object command. As each GPO is evaluated, it is piped into Get-GPPermissions. If a permission level is returned, the DisplayName property of the GPO is printed ($_.DisplayName).
Note: The ErrorAction parameter is set to SilentlyContinue for Get-GPPermissions. This is because a non-terminating error occurs if the specified security principal does not have permissions on the GPO. Specifying the ErrorAction as SilentlyContinue prevents the error messages from being printed for GPOS on which the security principal does not have permissions. For more information about the ErrorAction parameter, see about_CommonParameters.
Parameters
Indicates that the cmdlet gets the permission level for each user, group, or computer that has permissions on the GPO.
Type: | SwitchParameter |
Position: | Named |
Default value: | None |
Accept pipeline input: | False |
Accept wildcard characters: | False |
Specifies the domain for this cmdlet. You must specify the fully qualified domain name (FQDN) of the domain.
For the Get-GPPermission cmdlet, the GPO for which to get the permission level must exist in this domain.
If you do not specify the Domain parameter, the domain of the user that is running the current session is used. If the cmdlet is being run from a computer startup or shutdown script, the domain of the computer is used. For more information, see the Notes section in the full Help.
If you specify a domain that is different from the domain of the user that is running the current session (or, for a startup or shutdown script, the computer), a trust must exist between that domain and the domain of the user or the computer.
You can also refer to the Server parameter by its built-in alias, domain. For more information, see about_Aliases.
Type: | String |
Aliases: | Domain |
Position: | Named |
Default value: | None |
Accept pipeline input: | True |
Accept wildcard characters: | False |
Specifies the GPO from which to retrieve the permission level by its globally unique identifier (GUID). The GUID uniquely identifies the GPO.
You can also refer to the Guid parameter by its built-in alias, id. For more information, see about_Aliases.
Type: | Guid |
Aliases: | ID |
Position: | Named |
Default value: | None |
Accept pipeline input: | True |
Accept wildcard characters: | False |
Specifies the GPO from which to retrieve the permission level by its display name.
The display name is not guaranteed to be unique in the domain. If another GPO with the same display name exists in the domain an error occurs. You can use the Guid parameter to uniquely identify a GPO.
You can also refer to the Name parameter by its built-in alias, displayname. For more information, see about_Aliases.
Type: | String |
Aliases: | DisplayName |
Position: | 0 |
Default value: | None |
Accept pipeline input: | True |
Accept wildcard characters: | False |
Specifies the name of the domain controller that this cmdlet contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name.
If you do not specify the name by using the Server parameter, the PDC emulator is contacted.
You can also refer to the Server parameter by its built-in alias, dc. For more information, see about_Aliases.
Type: | String |
Aliases: | DC |
Position: | Named |
Default value: | None |
Accept pipeline input: | False |
Accept wildcard characters: | False |
Specifies the name of the security principal for which to get the permission level. You can specify a user, a security group, or a computer. You can use either the domain-qualified name of the security principal (domain\account) or just its name.
For instance, in the contoso.com domain, to specify:
The user «someuser», use «contoso\someuser» or «someuser».
The Domain Admins security group, use «contoso\Domain Admins» or «Domain Admins».
The computer «computer-01», use «contoso\computer-01» or «computer-01».
Type: | String |
Position: | Named |
Default value: | None |
Accept pipeline input: | False |
Accept wildcard characters: | False |
The type of security principal for which to get the permission level.
The acceptable values for this parameter are:
Type: | PermissionTrusteeType |
Accepted values: | Computer, User, Group |
Position: | Named |
Default value: | None |
Accept pipeline input: | False |
Accept wildcard characters: | False |
Inputs
Microsoft.GroupPolicy.Gpo
You can pipe a GPO to this cmdlet for which to get the permission level. Collections that contain GPOs from different domains are not supported.
Outputs
This cmdlet returns an object that represents permissions for the specified security principal (user, group, or computer) on the GPO.
Notes
You can use the DomainName parameter to explicitly specify the domain for this cmdlet.
If you do not explicitly specify the domain, the cmdlet uses the default domain. The default domain is the domain that is used to access network resources by the security context under which the current session is running. This domain is typically the domain of the user that is running the session. For example, the domain of the user who started the session by opening Windows PowerShell or the domain of a user that is specified in a runas command. However, computer startup and shutdown scripts run under the context of the LocalSystem account. The LocalSystem account is a built-in local account, and it accesses network resources under the context of the computer account. Therefore, when this cmdlet is run from a startup or shutdown script, the default domain is the domain to which the computer is joined.