ค้นหาเว็บไซต์

การรายงานกล่องจดหมายของห้องกำหนดการรายสัปดาห์ด้วย PowerShell


ใช้ PowerShell เพื่อแยก จัดรูปแบบ และส่งอีเมลกำหนดการห้องรายสัปดาห์ไปยังผู้รับที่กำหนด

ผู้อ่านถามเกี่ยวกับความเป็นไปได้ในการส่งอีเมลรายละเอียดกิจกรรมที่กำหนดไว้สำหรับกล่องจดหมายของห้องไปยังรายชื่อการแจกจ่าย เป็นเรื่องง่ายที่จะจินตนาการถึงสถานการณ์ที่ความสามารถนี้จะมีประโยชน์ ตัวอย่างเช่น ทีมงานอาจรับผิดชอบในการดูแลห้องประชุมในสถานที่หนึ่งๆ และต้องการทราบเกี่ยวกับกิจกรรมในหนึ่งสัปดาห์หรือหนึ่งวันข้างหน้า ไม่ว่าในกรณีใด ไม่มีฟีเจอร์ดังกล่าวใน Exchange Online ดังนั้นเรามาดูกันว่า PowerShell เป็นไปได้อย่างไร

ขั้นตอนเริ่มต้นในสคริปต์อาจเป็น:

  • คำนวณรอบระยะเวลาการรายงาน ตัวอย่างนี้รายงานเหตุการณ์ในสัปดาห์หน้า เริ่มตั้งแต่วันจันทร์
  • ค้นหากล่องจดหมายของห้องทั้งหมด (อาจจำกัดเฉพาะบางตำแหน่ง)
  • สำหรับแต่ละห้อง ให้ตรวจสอบว่ามีเหตุการณ์ใดๆ เกิดขึ้นในช่วงเวลาการรายงานหรือไม่ หากพบให้ดึงรายละเอียดออกมา

หลังจากค้นหาข้อมูลแล้ว ก็กลายเป็นเรื่องของการทำให้ข้อมูลมีอยู่ในรูปแบบต่างๆ ตัวอย่างเช่น คุณอาจต้องการพิมพ์รายงานกิจกรรมประจำสัปดาห์ หรือตามที่ร้องขอในตอนแรก สคริปต์ควรส่งอีเมลเพื่ออัปเดตผู้คนเกี่ยวกับกิจกรรมสำหรับห้องที่เฉพาะเจาะจง

สคริปต์ใช้แอป Entra ID ที่ลงทะเบียนเพื่อตรวจสอบสิทธิ์และรักษาความปลอดภัยโทเค็นการเข้าถึงเพื่อให้สามารถสืบค้นข้อมูลกราฟได้ แอปจะต้องได้รับความยินยอมให้ใช้สิทธิ์กราฟต่อไปนี้:

  • Calendar.Read: อ่านกิจกรรมจากโฟลเดอร์ปฏิทิน
  • Place.Read.All: อ่านรายละเอียดของสถานที่ เช่น ตู้จดหมายของห้อง
  • User.Read.All: อ่านรายละเอียดบัญชีผู้ใช้
  • MailSend.All: ส่งกำหนดการรายสัปดาห์ทางอีเมล

สิทธิ์ Mail.Send.All ช่วยให้สามารถส่งอีเมลจากกล่องจดหมายใดๆ ในผู้เช่าได้ หากต้องการจำกัดการเข้าถึง ให้พิจารณาใช้ RBAC สำหรับแอปพลิเคชันเพื่อจำกัดการเข้าถึงกล่องจดหมายที่ใช้ในการเผยแพร่การอัปเดตกำหนดการรายสัปดาห์

คุณสามารถดาวน์โหลดสคริปต์ได้จาก GitHub

การหาวันที่รายงาน

ปีที่แล้ว ฉันเขียนเกี่ยวกับการดึงข้อมูลสถิติสำหรับกล่องจดหมายของห้องจากข้อมูลกิจกรรมที่จัดขึ้นในปฏิทินของพวกเขา สคริปต์ใช้คำขอ Graph API เพื่อค้นหากล่องจดหมายของห้องและเหตุการณ์การค้นหา ตามแนวคิดแล้ว ขั้นตอนเริ่มต้นที่อธิบายไว้ข้างต้นเหมือนกับขั้นตอนที่ดำเนินการเพื่อแยกสถิติห้อง ข้อแตกต่างคือการวิเคราะห์การใช้ห้องเป็นการมองย้อนกลับไปในข้อมูล ในขณะที่สคริปต์นี้เกี่ยวกับการรู้ว่าเหตุการณ์ใดที่ห้องจะเป็นเจ้าภาพในอนาคต

ฉันตัดสินใจว่าระยะเวลาการรายงานควรเป็นตั้งแต่วันจันทร์ถัดไปถึงวันจันทร์หลังจากนั้น รหัสนี้รับวันที่ปัจจุบันและระบุว่าวันนี้เป็นวันจันทร์หรือไม่ หากเป็นเช่นนั้น วันที่เริ่มต้นสำหรับรอบระยะเวลารายงานคือวันนี้ ถ้าไม่เช่นนั้น วันที่เริ่มต้นคือวันจันทร์ถัดไป หลังจากค้นหาวันที่แล้ว โค้ดจะสร้างตัวแปรสองตัวในรูปแบบที่จัดเรียงได้เพื่อใช้เมื่อค้นหากล่องจดหมายของห้องสำหรับกิจกรรมในปฏิทิน

[datetime]$Today = (Get-Date).date
# If today is Monday, we report on the current week. Otherwise, we report on the next week
If ($Today.DayOfWeek.value__ -eq 1) {
    [datetime]$NextMonday = Get-Date($Today) -format 'dd-MMM-yyyy'
} Else {
    [datetime]$NextMonday = Get-Date($Today.AddDays(2 + $Today.DayOfWeek.value__)) -format 'dd-MMM-yyyy'
}
# Calculate the following Monday after the start date
[datetime]$NextMondayAfter = Get-Date($NextMonday).AddDays(7) -format 'dd-MMM-yyyy'

# Create sortable dates that can be used with the Graph request to find calendar data
$StartDate = Get-Date($NextMonday) -format s
$EndDate = Get-Date($NextMondayAfter) -format s

การค้นหากล่องจดหมายในห้อง

มีเทคนิคต่าง ๆ ในการค้นหาชุดกล่องจดหมายของห้อง คุณสามารถใช้ Get-ExoMailbox cmdlet จากโมดูลการจัดการ Exchange Online เพื่อเรียกใช้คำสั่งเช่น:

[array]$RoomMailboxes = Get-ExoMailbox -RecipientTypeDetails RoomMailbox -ResultSize Unlimited

ไม่จำเป็นต้องโหลดโมดูลการจัดการ Exchange Online เพียงเพื่อค้นหาชุดกล่องจดหมายของห้อง สคริปต์จะใช้ Graph Places API เพื่อดึงกล่องจดหมายของห้องที่มีโค้ดเช่น:

$Uri = "https://graph.microsoft.com/V1.0/places/microsoft.graph.room"
[Array]$RoomMailboxes = Get-GraphData -Uri $Uri -AccessToken $Token

การอ้างอิงถึง Get-GraphData ไม่ได้มีไว้สำหรับ cmdlet แต่เป็นฟังก์ชันที่ช่วยให้ดำเนินการตามคำขอกราฟได้ง่ายขึ้น เนื่องจากฟังก์ชันจะดูแลการจัดการข้อผิดพลาดและการแบ่งหน้า ผลลัพธ์ที่ได้คืออาร์เรย์ที่ประกอบด้วยชุดกล่องจดหมายของห้อง หากคุณต้องการรายงานกิจกรรมในปฏิทินสำหรับบางห้องเท่านั้น ให้ใช้ตัวกรองเพื่อเลือกกล่องจดหมายเป้าหมาย

กำลังประมวลผลปฏิทิน

หากต้องการดึงข้อมูลกิจกรรมจากปฏิทินกล่องจดหมายของห้อง สคริปต์จะสร้าง URI พร้อมด้วยพารามิเตอร์ เช่น ที่อยู่อีเมลของกล่องจดหมายและวันที่เริ่มต้นและสิ้นสุดสำหรับช่วงเวลาที่จะสืบค้น

$Uri = ("https://graph.microsoft.com/V1.0/users/{0}/calendar/calendarView?startDateTime={1}&endDateTime={2}" -f $Room.emailAddress, $StartDate, $EndDate)
[array]$CalendarData = Get-GraphData -Uri $Uri -AccessToken $Token

ตัวอย่างของ URI ที่สร้างขึ้นเพื่อสอบถามโฟลเดอร์ปฏิทินคือ:

https://graph.microsoft.com/V1.0/users/SFRoom101@Office365itpros.com/calendar/calendarView?startDateTime=2024-04-08T00:00:00&endDateTime=2024-04-15T00:00:00

หลังจากดึงกิจกรรมในปฏิทินที่ตรงกับระยะเวลาการรายงาน สคริปต์จะแยกรายละเอียดต่างๆ เช่น ชื่อและที่อยู่อีเมลของผู้จัดงาน เรื่องการประชุม เวลาเริ่มต้นและสิ้นสุด ระยะเวลา (เป็นนาที) และจำนวนผู้เข้าร่วม ตามค่าเริ่มต้น Exchange Online จะแทนที่หัวข้อการประชุมด้วยชื่อของผู้จัดงาน สิ่งนี้ทำเพื่อรักษาความเป็นส่วนตัวของการประชุมเมื่อบุคคลที่มีสิทธิ์เข้าถึงปฏิทินห้องเท่านั้นดูรายละเอียดได้ (ผู้เข้าร่วมแต่ละรายจะเห็นข้อมูลทั้งหมดเกี่ยวกับการประชุม)

มีกรณีที่โต้แย้งได้ว่าการประชุมที่กำหนดไว้ในทรัพยากรทางกายภาพที่ใช้ร่วมกันควรเปิดเผยหัวข้อใดก็ตามที่ผู้จัดการประชุมมอบให้กับกิจกรรม ถ้าคุณยอมรับ คุณสามารถอัปเดตการตั้งค่าการประมวลผลปฏิทินสำหรับกล่องจดหมายของห้องเพื่อรักษาหัวข้อการประชุมได้

ผลลัพธ์ที่สร้างโดยกล่องจดหมายของห้องประมวลผลคือรายงาน HTML (รูปที่ 1) อาจเป็นไปได้ว่าแต่ละห้องไม่จำเป็นต้องมีการแจ้งเตือนทางอีเมล ดังนั้นรายงานนี้จึงทำหน้าที่เป็นข้อมูลสรุปโดยรวม

การส่งอีเมลกำหนดการรายสัปดาห์

คำขอเดิมขอให้ส่งกำหนดการรายสัปดาห์ไปยังรายชื่อการแจกจ่าย รายการแรกที่ต้องแก้ไขคือวิธีการจัดเก็บที่อยู่อีเมลของรายชื่อการแจกจ่ายเพื่อรับการอัปเดตสำหรับกล่องจดหมายของห้อง วิธีแก้ปัญหาง่ายๆ คือจัดเก็บที่อยู่อีเมลไว้ในแอตทริบิวต์ที่กำหนดเอง 15 รายการสำหรับผู้รับที่เปิดใช้งานอีเมล รวมถึงกล่องจดหมายของห้องด้วย ฉันเลือกใช้ CustomAttribute13

ก่อนหน้านี้สคริปต์ดึงรายละเอียดของกล่องจดหมายของห้อง ข้อมูลนี้รวมถึงที่อยู่ SMTP หลักของแต่ละกล่องจดหมาย แต่ไม่มีชื่อผู้ใช้หลักหรือตัวระบุบัญชี แม้ว่าแนวทางปฏิบัติที่ดีที่สุดคือมีค่าเดียวกันสำหรับที่อยู่ SMTP หลักและชื่อผู้ใช้หลัก แต่แนวทางดังกล่าวมีแนวโน้มที่จะได้รับการเคารพสำหรับบัญชีผู้ใช้มากกว่ากล่องจดหมายของห้อง ดังนั้น สคริปต์จึงใช้การค้นหาที่กรองแล้วกับ Users API เพื่อดึงชุดแอตทริบิวต์ที่กำหนดเอง (เรียกว่า onPremisesExtensionAttributes ไปยัง Entra ID) และแยกค่าของ CustomAttribute13

$Uri = ("https://graph.microsoft.com/v1.0/users?`$filter=mail eq '{0}'&`$select=displayName,id,onPremisesExtensionAttributes" -f $Room.emailaddress)
        [array]$Data = Get-GraphData -Uri $Uri -AccessToken $Token
        If ($Data) {
            [array]$Attributes = $Data | Select-Object -ExpandProperty OnPremisesExtensionAttributes
            # Extract email address from custom attribute 13
            $EmailAddress = $Attributes.extensionAttribute13
        }

หากสคริปต์พบที่อยู่อีเมล สคริปต์จะสร้างและส่งข้อความอีเมล โดยปกติ ฉันจะใช้ Send-MgUserMail cmdlet จาก Microsoft Graph PowerShell SDK เพื่อส่งอีเมล แต่สคริปต์นี้ใช้คำขอ Graph ดังนั้นจึงโพสต์เนื้อหา JSON ไปยัง SendMail API โดยใช้กล่องจดหมายที่ใช้ร่วมกันเป็น ผู้ส่ง นี่คือรหัส:

$MsgSubject = ("Weekly Schedule for the {0} room from {1} to {2}" -f $Room.DisplayName, $StartDate, $EndDate)
$MsgBody = @{
   Content = "$($HtmlMsgBody)"
   ContentType = 'html'  
}
[array]$Recipient = @{
   emailAddress = @{address = $EmailAddress}
}  
$Message =  @{subject           = $MsgSubject}
$Message += @{toRecipients      = $Recipient } 
$Message += @{body              = $MsgBody}
$Params   = @{'message'         = $Message}
$Params  += @{'saveToSentItems' = $True}
$Params  += @{'isDeliveryReceiptRequested' = $True}
$Uri = ("https://graph.microsoft.com/v1.0/users/{0}/sendMail" -f $msgfrom)
$BodyParams = $Params | ConvertTo-Json -Depth 10
Invoke-RestMethod -Uri $Uri -Method POST -Body $BodyParams -Headers $Headers -ContentType 'application/JSON'

รูปที่ 2 คือตัวอย่างอีเมลที่ส่งพร้อมกำหนดการรายสัปดาห์ของห้อง

บรรลุเป้าหมาย

สคริปต์ถูกรวบรวมโดยการรวบรวมส่วนประกอบจากสคริปต์ต่างๆ และปรับแต่งผลลัพธ์ นี่เป็นงานประเภทที่ Copilot สำหรับ GitHub มีประโยชน์ เนื่องจากสามารถใช้ประโยชน์จากคอลเลกชันสคริปต์ PowerShell จำนวนมากที่จัดเก็บไว้ในที่เก็บ GitHub อย่างไรก็ตาม generative AI สามารถสร้างโค้ดตามสิ่งที่หายไปก่อนหน้านี้เท่านั้น การรู้ว่า Microsoft 365 ทำงานอย่างไรและการใช้ข้อมูลอย่างสร้างสรรค์ที่มีอยู่ในผู้เช่ายังคงเป็นทักษะของมนุษย์ ซึ่งฉันไม่คิดว่า AI จะเชี่ยวชาญได้ในอนาคต

บทความที่เกี่ยวข้อง