เริ่ม / หยุดบริการ Windows จากบัญชีผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบ


121

ฉันมี WindowsService ชื่อ BST และฉันต้องการให้ผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบ UserA สิทธิ์ในการเริ่ม / หยุดบริการเฉพาะนี้ บริการของฉันทำงานบน Windows OS ที่หลากหลายเริ่มตั้งแต่ Windows Server 2003 ไปจนถึง Windows 7

ฉันจะทำเช่นนี้ได้อย่างไร?

ฉัน Googled และพบบางอย่างเกี่ยวกับการให้สิทธิ์โดยใช้คำสั่ง [sc sdset] แต่ฉันไม่แน่ใจเกี่ยวกับพารามิเตอร์ ฉันไม่ต้องการตั้งค่าการอนุญาตสำหรับกลุ่ม แต่สำหรับผู้ใช้บางราย UserA ในกรณีนี้เท่านั้น

คำตอบ:


141

ด้านล่างนี้ฉันได้รวบรวมทุกสิ่งที่ฉันได้เรียนรู้เกี่ยวกับการเริ่ม / หยุดบริการ Windows จากบัญชีผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบหากใครต้องการทราบ

โดยพื้นฐานแล้วมีสองวิธีในการเริ่ม / หยุดบริการ Windows 1. เข้าถึงบริการโดยตรงผ่านเข้าสู่ระบบบัญชีผู้ใช้ Windows 2. การเข้าถึงบริการผ่าน IIS โดยใช้บัญชี Network Service

คำสั่งบรรทัดคำสั่งเพื่อเริ่ม / หยุดบริการ:

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 Application และใส่รหัสลงในนั้น ปรับใช้ WebService กับ IIS Root Folder (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 Services ให้กับกลุ่มหรือผู้ใช้ที่เราต้องการ ในกรณีนี้เราต้องการให้ผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบปัจจุบันสามารถเริ่ม / หยุดบริการได้ดังนั้นเราจะตั้งค่าการอนุญาตให้กับผู้ใช้นั้น ในการทำเช่นนั้นเราจำเป็นต้องมี SID ของบัญชีผู้ใช้ Windows นั้น ๆ ในการรับมันให้เปิด Registry (Start> 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 ของบัญชีผู้ใช้ที่คุณต้องการตั้งค่าการอนุญาต

Note2: นี่คือตัวอย่างโค้ด 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 "Network Services" แทนการเข้าสู่ระบบบัญชีผู้ใช้ Windows ขั้นตอนจะเหมือนกันเฉพาะพารามิเตอร์ของคำสั่งเท่านั้นที่จะเปลี่ยนแปลง เนื่องจากเราตั้งค่าการอนุญาตเป็น "Network Services" ให้แทนที่ SID ด้วยสตริง "NS" ในคำสั่งsdsetสุดท้ายที่เราใช้ก่อนหน้านี้ คำสั่งสุดท้ายควรมีลักษณะดังนี้:

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)"

ดำเนินการในพรอมต์คำสั่งจากบัญชีผู้ใช้ Admin และ voila! คุณได้รับอนุญาตให้เริ่ม / หยุดบริการจากบัญชีผู้ใช้ใด ๆ (ไม่ว่าจะเป็นบัญชีผู้ดูแลระบบหรือไม่ก็ตาม) โดยใช้ WebMethod อ้างอิงถึง Note1 เพื่อดูวิธีการดังกล่าว


11
หมายเหตุ: ** คุณต้องคัดลอกผลลัพธ์ของคำสั่งshshow ที่ดำเนินการในเครื่องของคุณเองจากนั้นแก้ไขตามที่ฉันได้ระบุไว้ ** อย่าเพียงแค่คัดลอกโค้ดจากที่นี่และดำเนินการบนคอมพิวเตอร์ของคุณเหมือนเดิม
Sach

5
ฉันลองใช้วิธีการแบบแมนนวลนี้แล้วมันก็ใช้ได้ แต่ถ้าคุณชอบฉันและคุณต้องทำสิ่งนี้บนคอมพิวเตอร์มากกว่า 20 เครื่องคุณจะต้องมีโปรแกรมหรือสคริปต์เพื่อทำสิ่งนี้ คุณสามารถใช้ API ของ Windows เรียกQueryServiceObjectSecurityและSetServiceObjectSecurity MSDN มีตัวอย่าง
Drew Chapin

1
รุ่งโรจน์ใหญ่! ทำงานอย่างมีเสน่ห์
Horst Gutmann

2
ฉันคิดว่าคำตอบอื่น ๆ บางคำจะเป็นวิธีที่ง่ายและตรงประเด็นกว่า เว้นแต่ว่าฉันจะพลาดประโยชน์จากสิ่งนี้ไปบ้าง?
Spike0xff

1
หากคุณกำลังทำสิ่งนี้โดยใช้โปรแกรมและต้องการแยกเอาต์พุตจากsc sdshowคุณสามารถใช้ regex นี้เพื่อแยกส่วนประกอบ: (?:\D:)?\(.+?\)จากนั้นแทรกส่วนใหม่ด้วย SID เป็นลำดับที่สองต่อท้าย
PhonicUK

116

ฉันใช้ยูทิลิตี้SubInACLสำหรับสิ่งนี้ ตัวอย่างเช่นถ้าฉันต้องการให้งานผู้ใช้บนคอมพิวเตอร์VMX001สามารถเริ่มและหยุดบริการการเผยแพร่เวิลด์ไวด์เว็บ (หรือที่เรียกว่า 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

2
ฉันต้องรีสตาร์ทหรือออกจากระบบ / เข้าสู่ระบบเมื่อใช้สิ่งนี้หรือไม่?
David กล่าวว่า Reinstate Monica

2
@DavidGrinberg ฉันจำไม่ได้ว่าจำเป็นต้องให้บัญชีที่ได้รับผลกระทบออกจากระบบแล้วเปิดใหม่หรือต้องรีสตาร์ทเมื่อใช้เฉพาะ subinacl ตามที่อธิบายไว้ที่นี่
arcain

1
สามารถยืนยันได้ว่าใช้งานได้บนเซิร์ฟเวอร์ 2012 โดยใช้sc \\server start|stop|query servicenameจากเซิร์ฟเวอร์ระยะไกล ไม่จำเป็นต้องรีสตาร์ท \ ออกจากระบบ
Stig Eide

วิธีนี้ได้ผลเพื่อเริ่มให้บริการในพื้นที่ อย่างไรก็ตามมันกระแทกกับCouldNotAccessDependentServicesใช้ PowerShell Cannot access dependent services of '...'ระยะไกล: การเพิ่มE : Enumerate Dependent Servicesสิทธิ์ ACL ได้รับการแก้ไข
Willem

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

1
จำเป็นต้องออกจากระบบหรือไม่
David กล่าวว่า Reinstate Monica

ขออภัย! ล้มเหลว ... ฉันได้รับ "ข้อผิดพลาด OpenSCManager: เซิร์ฟเวอร์ RPC ไม่พร้อมใช้งานคำเตือน: / Grant = mike = f: ไม่มีการเปิดวัตถุก่อนหน้านี้" บริการที่ฉันลองคือ MySQL Reboot: การเข้าถึงถูกปฏิเสธเช่นเคย
หนูไมค์

15

มี GUI Tool ServiceSecurityEditorฟรี

ซึ่งช่วยให้คุณแก้ไขสิทธิ์ Windows Service ได้ ฉันได้ใช้มันเพื่อให้สิทธิ์แก่ผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบในการเริ่มต้นและหยุดบริการ

ฉันเคยใช้ "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
ขอบคุณสำหรับคำตอบของ Jack อย่างไรก็ตามมันไม่ใช่สิ่งที่ฉันต้องการทำ ฉันต้องการให้บริการ BST ของฉันทำงานเหมือนตอนนี้ ฉันต้องการเพียงผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบเท่านั้นจึงจะสามารถหยุด / เริ่มได้
Sach
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.