การ Restart Service โดยอัตโนมัติ

การ Restart Service โดยอัตโนมัติ
มีศิษย์เก่าส่งคำถามเข้ามาหาผู้เขียนเกี่ยวกับการ Restart Service ของ Reporting Service โดยให้เกิดขึ้นอัตโนมัติในทุก ๆ เช้าซึ่งผู้เขียนยังไม่ทราบความจำเป็นถึงเหตุผลที่ชัดเจน
อย่างไรก็ตาม การ Restart Service ของ Reporting Service สามารถทำได้ 2 วิธี คือ
1.สามารถสั่งผ่าน Jobs บน SQL Server Agent Service
2.สามารถสั่งผ่าน Schedule Task ของ Microsoft Windows
ทั้งนี้ ผู้เขียนจึงจะแสดงให้ดูทั้ง 2 แบบเลย
ผู้อ่านต้องเข้าใจก่อนว่าการ Start, Stop หรือ Restart Service นั้นจะต้องทำผ่าน Users
ที่อยู่ในกลุ่ม Local Administrators ของ Microsoft Windows เครื่องที่ติดตั้ง Service ดังกล่าวอยู่
(อันที่จริงแล้วสามารถ Delegate ให้ user เป็นราย User สามารถ Start หรือ Stop Service เป็นราย Service ได้เป็นการเฉพาะแต่ไม่ขอกล่าวในบทความนี้)
สามารถดูได้ผ่านทาง Computer Management Console ภายใต้ Local Users and Groups ดังแสดง

จากนั้นดับเบิ้ลคลิกเข้าไปที่ Local Administrators
จะพบว่ามี User โดย Default อยู่ 2 คนก็คือ Local Administrator ของเครื่องนั้น ๆ
และ กรุ๊ป Domain Admins จาก Domain นั้นเอง
จะพบว่ามี User โดย Default อยู่ 2 คนก็คือ Local Administrator ของเครื่องนั้น ๆ
และ กรุ๊ป Domain Admins จาก Domain นั้นเอง

ในกรณีนี้ผู้เขียนจะสร้าง User แยกต่างหากจาก User ที่มีอยู่แล้ว
เพื่อแสดงให้เห็นว่าผู้อ่านสามารถนำเอา Local user หรือ Domain user มาใช้ได้ดังแสดง
เพื่อแสดงให้เห็นว่าผู้อ่านสามารถนำเอา Local user หรือ Domain user มาใช้ได้ดังแสดง

กรณีนี้ผู้เขียนเลือกสร้าง Local User ชื่อ Restarter ลงในเครื่องนั้น ๆ
จากนั้นทำการเพิ่ม Restarter ลงในกลุ่ม Local Administrators ดังแสดง
จากนั้นทำการเพิ่ม Restarter ลงในกลุ่ม Local Administrators ดังแสดง

เพียงแค่นี้เราก็จะได้ User ที่มีสิทธิ์ในการ Start และ Stop Service เรียบร้อยแล้ว
แบบที่ 1 สร้างเป็น Jobs บน SQL Server Agent Service
ผู้อ่านต้องเข้าใจเงื่อนไขเกี่ยวกับคนที่เรียกใช้ Job Steps อย่างถูกต้องเสียก่อนดัง Diagram ต่อไปนี้

กรณี Job Step เป็น Transact SQL Script จะรันโดย Job Owner เอง
หากว่า Job Owner นั้นไม่ครองบทบาทของ Sysadmin บนฝั่ง Database Engine
แต่ หาก Job Owner นั้นครองบทบาทของ Sysadmin บนฝั่ง Database Engine แล้วละก็จะรันภายใต้ Service Account ของฝั่ง SQL Server Agent Service
กรณี Job Step ไม่ใช่ Transact SQL Script จะรันโดย Service Account ของฝั่ง SQL Server Agent Service หรือ สามารถกำหนดให้รันภายใต้ Proxy Account ได้
ในครั้งนี้จะเลือกประเภท Job Step เป็น Operating System ซึ่งไม่ใช่ Transact SQL Script
ดังนั้น จึงมีทางเลือกคือรันภายใต้ Service Account ของฝั่ง SQL Server Agent Service
หรือไม่ก็รันภายใต้ Proxy Account หากต้องการให้ Service Account ของฝั่ง SQL Server Agent Service
สามารถ Start หรือ Stop Service ได้นั้นจำเป็นต้องนำเอา Service Account ดังกล่าวใส่ลงในกลุ่ม Local Administrators ซึ่งไม่ควรทำ เพราะไม่สอดคล้องกับ Security Best Practice
(สำหรับเรื่องนี้แนะนำให้เข้าอบรมหลักสูตร Microsoft SQL Server Database Administrator ของสถาบัน 9Expert)
ดังนั้นจึงเหลือทางเลือกเดียวคือสร้างและใช้งาน Proxy Account
ก่อนที่จะใช้งาน Proxy Account นั้นจำเป็นจะต้องสร้าง Credential ไว้ที่ฝั่ง Database Engine เสียก่อน ดังแสดง
หากว่า Job Owner นั้นไม่ครองบทบาทของ Sysadmin บนฝั่ง Database Engine
แต่ หาก Job Owner นั้นครองบทบาทของ Sysadmin บนฝั่ง Database Engine แล้วละก็จะรันภายใต้ Service Account ของฝั่ง SQL Server Agent Service
กรณี Job Step ไม่ใช่ Transact SQL Script จะรันโดย Service Account ของฝั่ง SQL Server Agent Service หรือ สามารถกำหนดให้รันภายใต้ Proxy Account ได้
ในครั้งนี้จะเลือกประเภท Job Step เป็น Operating System ซึ่งไม่ใช่ Transact SQL Script
ดังนั้น จึงมีทางเลือกคือรันภายใต้ Service Account ของฝั่ง SQL Server Agent Service
หรือไม่ก็รันภายใต้ Proxy Account หากต้องการให้ Service Account ของฝั่ง SQL Server Agent Service
สามารถ Start หรือ Stop Service ได้นั้นจำเป็นต้องนำเอา Service Account ดังกล่าวใส่ลงในกลุ่ม Local Administrators ซึ่งไม่ควรทำ เพราะไม่สอดคล้องกับ Security Best Practice
(สำหรับเรื่องนี้แนะนำให้เข้าอบรมหลักสูตร Microsoft SQL Server Database Administrator ของสถาบัน 9Expert)
ดังนั้นจึงเหลือทางเลือกเดียวคือสร้างและใช้งาน Proxy Account
ก่อนที่จะใช้งาน Proxy Account นั้นจำเป็นจะต้องสร้าง Credential ไว้ที่ฝั่ง Database Engine เสียก่อน ดังแสดง

Credentials เป็น Object เกี่ยวกับ Security ในระดับ Instance หรือระดับ Server ดังรูป

Credential เป็นการนำเอา Username และ Password ของผู้ใช้ใน Windows มาจัดเก็บไว้ในฐานข้อมูล
เมื่อต้องการเข้าถึงทรัพยากรตามสิทธิของผู้ใช้คนนั้น ๆ ก็สามารถนำเอา Credential ไปเข้าถึงทรัพยากรได้
เราไม่จำเป็นต้องเพิ่ม Windows User เข้าเป็น Login ใน SQL Server แต่อย่างใด
เมื่อผู้เขียนเพิ่ม Credential ลงในฝั่ง Database Engine เรียบร้อยแล้ว จะกลับไปที่ฝั่ง SQL Server Agent Service เพื่อสร้าง Proxy
เมื่อต้องการเข้าถึงทรัพยากรตามสิทธิของผู้ใช้คนนั้น ๆ ก็สามารถนำเอา Credential ไปเข้าถึงทรัพยากรได้
เราไม่จำเป็นต้องเพิ่ม Windows User เข้าเป็น Login ใน SQL Server แต่อย่างใด
เมื่อผู้เขียนเพิ่ม Credential ลงในฝั่ง Database Engine เรียบร้อยแล้ว จะกลับไปที่ฝั่ง SQL Server Agent Service เพื่อสร้าง Proxy
เปิดโฟลเดอร์ Proxies ภายใต้ SQL Server Agent Service จะพบโฟลเดอร์ของบรรดาชนิด Job Step
ให้คลิกขวาไปที่โฟลเดอร์ Proxies จากนั้นเลือก New Proxy

จะปรากฏหน้าต่างดังแสดง ให้กำหนด
- ชื่อ Proxy
- อ้างถึง Credential ที่สร้างไว้บน Database Engine

จะได้ผลลัพธ์ดังแสดง หมายความว่าหาก Job Step มีเลือกรันผ่าน Proxy ชื่อ Proxy-Restarter
ก็จะไปหยิบ Credential ชื่อ Credential-Restarter มาใช้นั่นเอง
ก็จะไปหยิบ Credential ชื่อ Credential-Restarter มาใช้นั่นเอง

จากนั้นผู้เขียนจะตรวจสอบว่า Reporting Service เปิดใช้งานอยู่หรือไม่ ผ่านทาง SQL Server Configuration Manager ดังแสดง

จากรูป หาก Reporting Service ไม่ได้อยู่ในสถานะ Running ให้ทำการ Start Service ขึ้นมา
ผู้อ่านโปรดสังเกตว่า Reporting Service ติดตั้งอยู่บน Named Instance ในที่นี้คือ SQL2
จากนั้นกลับไปที่ SQL Server Management Studio ในส่วนของ SQL Server Agent Service
ผู้เขียนทำสร้าง Job โดยการคลิกขวาไปที่โฟลเดอร์ Jobs และตั้งชื่อ Job เป็น STOP Reporting Service ดังแสดง
ผู้อ่านโปรดสังเกตว่า Reporting Service ติดตั้งอยู่บน Named Instance ในที่นี้คือ SQL2
จากนั้นกลับไปที่ SQL Server Management Studio ในส่วนของ SQL Server Agent Service
ผู้เขียนทำสร้าง Job โดยการคลิกขวาไปที่โฟลเดอร์ Jobs และตั้งชื่อ Job เป็น STOP Reporting Service ดังแสดง

จากนั้นให้สร้าง Job Step ชนิด Operating System โดยใช้ Script แนะนำดังนี้

เนื่องจาก Reporting Service เป็น Named Instance จึงต้องอ้างชื่อ Service ในรูปแบบ ReportServer$<InstanceName>
และ Reporting Service มักใช้ร่วมกับ Microsoft Sharepoint Server และ IIS Server
ดังนั้นจึงเพิ่มเติมการ Stop Service ที่เกี่ยวข้องเหล่านี้ลงไปได้ ดังแสดง
และ Reporting Service มักใช้ร่วมกับ Microsoft Sharepoint Server และ IIS Server
ดังนั้นจึงเพิ่มเติมการ Stop Service ที่เกี่ยวข้องเหล่านี้ลงไปได้ ดังแสดง

ผู้อ่านโปรดสังเกตว่าต้องระบุ Run as: เป็น Proxy Account ที่เราสร้างขึ้นมา (ที่มีสิทธิในการ Start หรือ Stop Service)
จากนั้นทดลองรัน Job โดยการคลิกขวาไปที่ชื่อ Job แล้วเลือกไปที่ Start Job at Step ดังแสดง
จากนั้นทดลองรัน Job โดยการคลิกขวาไปที่ชื่อ Job แล้วเลือกไปที่ Start Job at Step ดังแสดง

เมื่อกลับไปดูใน SQL Server Configuration Manager จะพบว่า Reporting Service มีสถานะเป็น Stopped ไปเรียบร้อยแล้ว ดังแสดง

เราสามารถติดตามดูประวัติการรันของ Job ได้ โดยคลิกขวาไปที่ชื่อของ Job ของเรา
จากนั้นเลือกไปที่ View History จะแสดงหน้าต่างดังต่อไปนี้
จากนั้นเลือกไปที่ View History จะแสดงหน้าต่างดังต่อไปนี้

จะพบว่า Job ถูกรันภายใต้ MIA-SQL\Restarter ที่เราสร้างไว้ และพบว่า SQL Server Reporting Service ได้ถูก Stop เป็นที่เรียบร้อย
แต่ หาก Stop เพียงอย่างเดียวก็อาจไม่ตรงกับที่มีผู้สอบถามเข้ามา ผู้เขียนเลยแก้ไขในส่วนของ Script เสียใหม่ให้เป็น
แต่ หาก Stop เพียงอย่างเดียวก็อาจไม่ตรงกับที่มีผู้สอบถามเข้ามา ผู้เขียนเลยแก้ไขในส่วนของ Script เสียใหม่ให้เป็น

เพียงเท่านี้ก็จะกลายเป็นการ Restart Service ตามต้องการแล้ว
แบบที่ 2 กำหนดให้ Restart Service ผ่านทาง Task Scheduler
แบบที่ 2 กำหนดให้ Restart Service ผ่านทาง Task Scheduler
อีกวิธีหนึ่งที่ผู้เขียนเห็นว่าเหมาะสมมากกว่าวิธีแรก ก็คือการสร้างเป็น Task ภายใต้ Task Scheduler ของ Microsoft Windows ดังแสดง

เมื่อเรียก Task Scheduler ขึ้นมาแล้ว ให้คลิกขวาไปที่ Task Scheduler Library เลือก Create Task จะปรากฏหน้าต่าง Create Task ดังแสดง

ในแท็บ General ทำการตั้งชื่อ Task ตามต้องการ
ตัวอย่างนี้ให้ชื่อว่า Restart Reporting Service
ในส่วนของ Security Options เป็นสิ่งสำคัญมาก จำเป็นต้องเลือก User หรือ Group ที่มีสิทธิ์เพียงพอในการ Restart Service
ในที่นี้ผู้เขียนการเลือกใช้ Local Administrators ซึ่งเป็น Group เป็นผู้รัน Task นี้เลย
จากนั้นเลือก Checkbox ชื่อ Run with highest Privileges (ในส่วนนี้ผู้อ่านสามารถทดลองไม่ Check ดูได้ ผู้เขียนแค่เกรงว่าสิทธิจะไม่เพียงพอเลยเลือกไว้เท่านั้น)
จากนั้นเปลี่ยนไปที่แท็บ Triggers เราสามารถกำหนดให้ Task รันตามตารางเวลาที่กำหนดได้ดังแสดง
ตัวอย่างนี้ให้ชื่อว่า Restart Reporting Service
ในส่วนของ Security Options เป็นสิ่งสำคัญมาก จำเป็นต้องเลือก User หรือ Group ที่มีสิทธิ์เพียงพอในการ Restart Service
ในที่นี้ผู้เขียนการเลือกใช้ Local Administrators ซึ่งเป็น Group เป็นผู้รัน Task นี้เลย
จากนั้นเลือก Checkbox ชื่อ Run with highest Privileges (ในส่วนนี้ผู้อ่านสามารถทดลองไม่ Check ดูได้ ผู้เขียนแค่เกรงว่าสิทธิจะไม่เพียงพอเลยเลือกไว้เท่านั้น)
จากนั้นเปลี่ยนไปที่แท็บ Triggers เราสามารถกำหนดให้ Task รันตามตารางเวลาที่กำหนดได้ดังแสดง


ผู้เขียนได้กำหนดให้ Task รันทุกวันในเวลา 12:00 PM อย่าลืมเลือก Checkbox ชื่อ Enabled ไว้ด้วย ไม่อย่างนั้นแล้ว Trigger นี้จะไม่ทำงาน
จากนั้นเลือกไปที่แท็บ Actions เราสามารถเลือกรันไปที่ไฟล์ Script อย่างเช่น Batch File ได้
โดยสร้างสคริปต์ในการ Start หรือ Stop Service เอาไว้ใน Batch File เดียวเลย
หรือจะเลือกรันคำสั่ง net ไปทีละคำสั่ง แล้วตามด้วยอาร์กิวเมนต์ในช่อง Add Arguments ดังแสดง
จากนั้นเลือกไปที่แท็บ Actions เราสามารถเลือกรันไปที่ไฟล์ Script อย่างเช่น Batch File ได้
โดยสร้างสคริปต์ในการ Start หรือ Stop Service เอาไว้ใน Batch File เดียวเลย
หรือจะเลือกรันคำสั่ง net ไปทีละคำสั่ง แล้วตามด้วยอาร์กิวเมนต์ในช่อง Add Arguments ดังแสดง


ทำแบบนี้จะกว่าหมดชุดของการ STOP โดยผลลัพธ์ที่ได้จะเป็นดังนี้

จากนั้นผู้เขียนจะตรวจสอบว่า Reporting Service เปิดใช้งานอยู่หรือไม่ ผ่านทาง SQL Server Configuration Manager ดังแสดง

จากรูป หาก Reporting Service ไม่อยู่ในสถานะ Running ให้ทำการ Start Service ขึ้นมาใหม่
หลังจากนั้นผู้เขียนกลับไปที่ Task Scheduler คลิกขวาไปที่ Task ที่สร้างไว้ แล้วเลือกไปที่ Run ดังแสดง
หลังจากนั้นผู้เขียนกลับไปที่ Task Scheduler คลิกขวาไปที่ Task ที่สร้างไว้ แล้วเลือกไปที่ Run ดังแสดง

เมื่อกลับไปดูใน SQL Server Configuration Manager จะพบว่า Reporting Service มีสถานะเป็น Stopped ไปเรียบร้อยแล้ว ดังแสดง

ทั้งหมดนี้เป็นการทดสอบว่า Task สามารถ Stop Service ลงได้หรือไม่ ซึ่งปรากฏว่าสำเร็จ
จากนั้นเราจะทำการเพิ่มเติม Actions ลงไปให้ครบถ้วนสำหรับการ Restart ผลลัพธ์ที่ได้ควรเป็นดังนี้
จากนั้นเราจะทำการเพิ่มเติม Actions ลงไปให้ครบถ้วนสำหรับการ Restart ผลลัพธ์ที่ได้ควรเป็นดังนี้

สรุป
หากเป็นผู้เขียนจะเลือกแนวทางที่ 2 เหตุผล ก็คือ Reporting Service เป็นบริการบน Microsoft Windows ก็ควรดูแลโดย Microsoft Windows เป็นหลักและ การจัดเก็บ Credential ของ User จะถูกดำเนินการโดย Active Directory Database ในกรณีเป็น Domain User
และ หากเป็นกรณี Local User ก็จะจัดเก็บโดย SAM File ถึงอย่างไรก็ยังดีกว่าการเพิ่มที่จัดเก็บ Credential ของคนที่มีสิทธิสูงไว้ที่อื่นโดยไม่จำเป็น
อย่างกรณีการสร้าง Credentials ภายใต้ Database Engine (ความเห็นส่วนตัว) อีกอย่างเมื่อ Credential เหล่านั้นมีการเปลี่ยนแปลงในต้นทาง
เช่น มีการเปลี่ยน Password จากฝั่ง Active Directory หรือจาก SAM File แล้ว แต่ Credential ที่เก็บไว้ใน Database Engine ไม่เปลี่ยนตาม Script ที่ใช้สิทธิผ่าน Credential เหล่านั้นก็จะใช้งานไม่ได้
บทความโดย
อาจารย์ภัคพงศ์ กฤตวัฒน์
วิทยากรดูแลและออกแบบหลักสูตร
กลุ่มวิชา SQL Server/Window Server