通过非管理员用户帐户启动/停止Windows服务


121

我有一个名为BST的WindowsService。而且,我需要授予非管理员用户UserA启动/停止此特定服务的权限。从Windows Server 2003到Windows 7,我的服务可以在各种Windows操作系统上运行。

我怎样才能做到这一点?

我在Google上搜索了一下,发现了一些有关使用命令[sc sdset]授予权限的内容,但是我不确定这些参数。我不想为组设置权限,而只为特定用户(在这种情况下为UserA)设置权限。

Answers:


141

如果有人需要知道的话,下面我汇总了从非管理员用户帐户启动/停止Windows服务所学到的所有知识。

首先,有两种启动/停止Windows服务的方法。 1.通过登录Windows用户帐户直接访问服务。2.使用网络服务帐户通过IIS访问服务。

命令行命令启动/停止服务:

C:/> net start <SERVICE_NAME>
C:/> net stop <SERVICE_NAME>

C#代码启动/停止服务:

ServiceController service = new ServiceController(SERVICE_NAME);

//Start the service
if (service.Status == ServiceControllerStatus.Stopped)
{
      service.Start();
      service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10.0));
}

//Stop the service
if (service.Status == ServiceControllerStatus.Running)
{
      service.Stop();
      service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10.0));
}

注意1: 通过IIS访问服务时,创建一个Visual Studio C#ASP.NET Web应用程序并将代码放在其中。将WebService部署到IIS根文件夹(C:\ inetpub \ wwwroot \),一切顺利。通过URL http:///访问它。

1.直接访问方法

如果您从中发出命令或运行代码的Windows用户帐户是非管理员帐户,则需要为该特定用户帐户设置特权,以便它具有启动和停止Windows服务的能力。这就是你的做法。 登录到具有您要启动/停止服务的非管理员帐户的计算机上的管理员帐户。打开命令提示符并输入以下命令:

C:/>sc sdshow <SERVICE_NAME>

这样的输出将是这样的:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

它列出了此计算机上每个用户/组具有的所有权限。

A description of one part of above command is as follows:

    D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)

It has the default owner, default group, and it has the Security descriptor control flags (A;;CCLCSWRPWPDTLOCRRC;;;SY):

ace_type - "A": ACCESS_ALLOWED_ACE_TYPE,
ace_flags - n/a,
rights - CCLCSWRPWPDTLOCRRC,  please refer to the Access Rights and Access Masks and Directory Services Access Rights
CC: ADS_RIGHT_DS_CREATE_CHILD - Create a child DS object.
LC: ADS_RIGHT_ACTRL_DS_LIST - Enumerate a DS object.
SW: ADS_RIGHT_DS_SELF - Access allowed only after validated rights checks supported by the object are performed. This flag can be used alone to perform all validated rights checks of the object or it can be combined with an identifier of a specific validated right to perform only that check.
RP: ADS_RIGHT_DS_READ_PROP - Read the properties of a DS object.
WP: ADS_RIGHT_DS_WRITE_PROP - Write properties for a DS object.
DT: ADS_RIGHT_DS_DELETE_TREE - Delete a tree of DS objects.
LO: ADS_RIGHT_DS_LIST_OBJECT - List a tree of DS objects.
CR: ADS_RIGHT_DS_CONTROL_ACCESS - Access allowed only after extended rights checks supported by the object are performed. This flag can be used alone to perform all extended rights checks on the object or it can be combined with an identifier of a specific extended right to perform only that check.
RC: READ_CONTROL - The right to read the information in the object's security descriptor, not including the information in the system access control list (SACL). (This is a Standard Access Right, please read more http://msdn.microsoft.com/en-us/library/aa379607(VS.85).aspx)
object_guid - n/a,
inherit_object_guid - n/a,
account_sid - "SY": Local system. The corresponding RID is SECURITY_LOCAL_SYSTEM_RID.

现在,我们需要为所需的组或用户设置适当的权限,以启动/停止Windows服务。在这种情况下,我们需要当前的非管理员用户能够启动/停止服务,因此我们将为该用户设置权限。为此,我们需要该特定Windows用户帐户的SID。要获取它,请打开注册表(开始> regedit)并找到以下注册表项。

LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

在此之下,此计算机中的每个用户帐户都有一个单独的密钥,并且密钥名称是每个帐户的SID。SID通常格式为S-1-5-21-2103278432-2794320136-1883075150-1000。单击每个键,您将在右侧窗格中看到每个键的值列表。找到“ ProfileImagePath”,并通过其值找到SID所属的用户名。例如,如果帐户的用户名是SACH,则“ ProfileImagePath”的值将类似于“ C:\ Users \ Sach”。因此,记下要为其设置权限的用户帐户的SID。

注意2: 这里是一个简单的C#代码示例,可用于获取所述键及其值的列表。

//LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList RegistryKey
RegistryKey profileList = Registry.LocalMachine.OpenSubKey(keyName);

//Get a list of SID corresponding to each account on the computer
string[] sidList = profileList.GetSubKeyNames();

foreach (string sid in sidList)
{
    //Based on above names, get 'Registry Keys' corresponding to each SID
    RegistryKey profile = Registry.LocalMachine.OpenSubKey(Path.Combine(keyName, sid));

    //SID
    string strSID = sid;
    //UserName which is represented by above SID    
    string strUserName = (string)profile.GetValue("ProfileImagePath");
}

现在我们有了要为其设置权限的用户帐户的SID,让我们开始吧。假设用户帐户的SID是S-1-5-21-2103278432-2794320136-1883075150-1000。将[sc sdshow]命令的输出复制到文本编辑器。它看起来像这样:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

现在,复制(A ;; CCLCSWRPWPDTLOCRRC ;;; SY)上面的文字部分,然后将其粘贴之前S:(AU; ...文字的部分,那么该部分改变看起来是这样的: (A ;; RPWPCR ;;; S-1-5-21-2103278432-2794320136-1883075150-1000)

然后在前面添加sc sdset,并用引号将上面的部分括起来。您的最终命令应类似于以下内容:

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

现在,在命令提示符下执行此操作,如果成功,则应给出以下输出:

[SC] SetServiceObjectSecurity SUCCESS

现在我们可以出发了!您的非管理员用户帐户已被授予启动/停止服务的权限!尝试登录用户帐户并启动/停止服务,它应该可以使您执行此操作。

2.通过IIS方法访问

在这种情况下,我们需要将权限授予IIS用户“网络服务”,而不是登录Windows用户帐户。步骤相同,只是命令的参数将被更改。由于我们将权限设置为“网络服务”,因此在先前使用的最终sdset命令中,将SID替换为字符串“ NS” 。最终命令应如下所示:

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;NS)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

从管理员用户帐户在命令提示符下执行它,瞧!您有权使用WebMethod从任何用户帐户(无论它是否是管理员帐户)启动/停止服务。请参阅“注1”以了解操作方法。


11
注意:**您必须复制在您自己的计算机上执行的shshow命令的结果,然后根据我指定的内容进行编辑。**请勿仅从此处复制代码并按原样在计算机上执行。
萨克

5
我尝试了这种手动方法,并且效果出色。但是,如果您像我一样,并且需要在20多台计算机上执行此操作,那么您将需要一个程序或脚本来执行此操作。您可以使用Windows API调用QueryServiceObjectSecuritySetServiceObjectSecurity。MSDN上有一个将其应用于“来宾”帐户
Drew Chapin

1
大声!像魅力一样工作。
Horst Gutmann

2
为了不脱离该答案所付出的努力和关心,我认为其他一些答案提供了更简单,更直接的解决方案。除非我缺少这种优势?
Spike0xff

1
如果您是通过编程方式执行此操作并希望从中拆分输出,sc sdshow则可以使用此正则表达式拆分组件:(?:\D:)?\(.+?\)然后以SID作为倒数第二个插入新零件。
PhonicUK '18

115

我为此使用SubInACL实用程序。例如,如果我想使用户计算机VMX001上的作业能够启动和停止World Wide Web Publishing服务(也称为w3svc),我将以管理员身份发出以下命令:

subinacl.exe /service w3svc /grant=VMX001\job=PTO

您可以授予的权限定义如下(从此处获取列表):

F : Full Control
R : Generic Read
W : Generic Write
X : Generic eXecute
L : Read controL
Q : Query Service Configuration
S : Query Service Status
E : Enumerate Dependent Services
C : Service Change Configuration
T : Start Service
O : Stop Service
P : Pause/Continue Service
I : Interrogate Service 
U : Service User-Defined Control Commands

因此,通过指定PTO,我使作业用户有权暂停/继续,启动和停止w3svc服务。


18
这是最好的答案。它使用正确的工具完成工作,而不会在注册表中四处乱窜,翻译SID或依赖晦涩的ACL格式。提供足够的详细信息以快速,轻松地完成工作所需的所有内容,以将其推断出任何合理的情况。
pierce.jason 2014年

2
使用此工具时是否需要重新启动或注销/登录?
大卫说恢复莫妮卡

2
@DavidGrinberg我不记得曾经需要注销受影响的帐户然后再重新启动,或者仅在使用此处所述的subinacl时必须重新启动。
arcain 2015年

1
可以使用sc \\server start|stop|query servicename远程服务器确认这在2012服务器上正常工作。无需重新启动\注销需要
斯蒂格·艾德

这有助于在本地启动服务。但是,CouldNotAccessDependentServices使用远程powershell导致崩溃:Cannot access dependent services of '...'。添加E : Enumerate Dependent Services到ACL权限可以解决该问题。
威廉

42
  1. 以管理员身份登录。
  2. subinacl.exe从Microsoft 下载:http :
    //www.microsoft.com/en-us/download/details.aspx?id=23510
  3. 向普通用户帐户授予权限以管理BST服务。
    subinacl.exe在中C:\Program Files (x86)\Windows Resource Kits\Tools\)。
  4. cd C:\Program Files (x86)\Windows Resource Kits\Tools\
    subinacl /SERVICE \\MachineName\bst /GRANT=domainname.com\username=F 要么
    subinacl /SERVICE \\MachineName\bst /GRANT=username=F
  5. 注销并以用户身份重新登录。他们现在应该能够启动BST服务。

1
与手动操作配置相比,它看起来更容易和更好。
gsk 2013年

1
是否需要注销?
大卫说恢复莫妮卡

哎呀!失败...我收到“错误OpenSCManager:RPC服务器不可用。警告:/ grant = mike = f:未打开任何先前的对象”。我尝试的服务是MySQL。重新启动:访问被拒绝,一如既往。
迈克·啮齿动物

15

有一个免费的GUI工具ServiceSecurityEditor

允许您编辑Windows服务权限。我已经成功地使用它来授予非管理员用户启动和停止服务的权利。

在了解此工具之前,我曾使用过“ sc sdset”。

ServiceSecurityEditor感觉就像作弊一样,就这么简单:)


1
我根据此建议尝试了ServiceSecurityEditor,它非常好。
Guru Josh

11

使用以下工具之一向服务授予管理权限要容易得多:

  • 组策略
  • 安全模板
  • subinacl.exe命令行工具。

这是MSKB文章,其中包含有关Windows Server 2008 / Windows 7的说明,但是有关2000和2003的说明相同。


1

subinacl.exe命令行工具可能是这篇文章中唯一可行且非常易于使用的工具。您不能将GPO与非系统服务一起使用,而另一个选择只是太复杂了。


-2

Windows服务使用本地系统帐户运行,它可以在用户登录系统时自动启动,也可以手动启动,但是Windows服务说BST可以使用计算机上的特定用户帐户运行。如下所示:启动services.msc并转到Windows服务BST的属性。从那里可以提供所需用户的登录参数。然后该服务使用该用户帐户运行,其他用户则无法运行该服务。


1
感谢杰克的回复。但是,这不是我想要的。我需要我的服务BST像现在一样运行。我只需要不是管理员的任何用户就可以停止/启动它。
萨克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.