Tìm kiếm trang web

Viết tập lệnh dọn dẹp hộp thư bằng API đồ thị


Tập lệnh PowerShell để loại bỏ mảnh vụn khỏi hộp thư người dùng và hộp thư dùng chung

Đôi khi, cần phải xóa các mục khỏi hộp thư của người dùng. Có lẽ ai đó đã chia sẻ thông tin trong email mà lẽ ra họ không nên có hoặc có thể một số thư chứa phần mềm độc hại nguy hiểm đã xâm nhập Exchange Online Protection và đến hộp thư đến. Bạn có thể yêu cầu người dùng xóa các tin nhắn vi phạm theo cách thủ công, nhưng việc này thường hiệu quả và hiệu quả hơn nếu quản trị viên can thiệp và xóa vấn đề.

Trong môi trường tại chỗ, lệnh ghép ngắn Search-Mailbox sẽ thực hiện công việc này. Việc Microsoft nhiệt tình áp dụng các tính năng tuân thủ để hoạt động trên nhiều khối lượng công việc đôi khi gây ra những hậu quả đáng tiếc và quyết định ngừng sử dụng Search-Mailbox của họ vào tháng 7 năm 2020 đã loại bỏ một công cụ có giá trị. Tại thời điểm viết bài, Hộp thư tìm kiếm vẫn hoạt động nhưng nhiều người đã ngừng sử dụng nó vì tính chất không được hỗ trợ của nó.

Giải pháp thay thế được khuyến nghị của Microsoft cho Hộp thư tìm kiếm là sử dụng các hành động thanh lọc bằng các tìm kiếm tuân thủ để xóa các mục khỏi hộp thư Exchange Online. Phương pháp này sử dụng tìm kiếm tuân thủ để tìm các mục phù hợp, sau đó thực hiện hành động thanh lọc để xóa các mục đó. Nó hoạt động, nhưng quá trình xử lý chậm và dường như ngày càng chậm hơn khi thời gian trôi qua. Tuần trước, tôi đã dành chút thời gian làm việc với tập lệnh mẫu mà tôi đã viết vào năm 2019 để chỉ ra cách lặp qua các kết quả tìm kiếm tuân thủ để xóa các mục và hiệu suất rất tệ. Điều tra một tập lệnh để thực hiện công việc mà không cần sử dụng Hộp thư tìm kiếm hoặc tìm kiếm tuân thủ có vẻ là một điều hay, nếu chỉ để tìm hiểu cách giải quyết vấn đề bằng cách sử dụng các yêu cầu API Đồ thị.

Lập biểu đồ cho kịch bản

Các phác thảo cơ bản của kịch bản là:

  • Thu thập các tham số cho truy vấn tìm kiếm.
  • Tìm hộp thư để tìm kiếm.
  • Chạy truy vấn tìm kiếm đối với các hộp thư. Vì chúng tôi đang sử dụng các yêu cầu API Đồ thị nên chúng tôi cần ứng dụng Azure AD đã đăng ký và có sự đồng ý để sử dụng quyền ứng dụng Mail.ReadWrite. Quyền truy cập đọc là cần thiết để lấy dữ liệu tin nhắn. Cần có quyền ghi để xóa thư khỏi hộp thư.
  • Áp dụng hành động cho các thư được truy vấn tìm thấy. Tôi muốn có các tùy chọn để báo cáo tin nhắn và xóa tin nhắn.

Bây giờ chúng ta đã biết những bước nào phải được thực hiện, hãy xem xét một số chi tiết.

Lần thử đầu tiên

Phiên bản gốc của kịch bản rất đơn giản. Tôi đã sử dụng loại tài nguyên thư Đồ thị để truy xuất thư từ hộp thư có bộ lọc nhằm tìm thư mong muốn. Áp dụng bộ lọc sẽ tìm thấy các thư có kết quả khớp chính xác. Ví dụ: yêu cầu này tìm thấy tất cả các thư có chủ đề “Dự án Ankara cần làm”:

https://graph.microsoft.com/v1.0/users/aff4cd58-1bb8-4899-94de-795f656b4a18/messages?$select=id,receivedDateTime,subject,from&$filter=subject eq 'Project Ankara To Do Items'

Yêu cầu chọn đã thành công nhưng chỉ trả về một tập hợp giới hạn (vì khớp chính xác), không giống với những tập hợp được truy xuất bởi Search-Mailbox hoặc tìm kiếm tuân thủ.

Trước khi tìm hiểu sâu hơn, hãy để tôi nhấn mạnh rằng Graph Explorer là một công cụ thiết yếu khi tìm hiểu chi tiết về các yêu cầu API đồ thị. Bạn có thể lấy URI được tập lệnh tính toán và nhập nó vào Graph Explorer để xem điều gì sẽ xảy ra. Sau khi yêu cầu hoạt động trong Graph Explorer, bạn biết rằng yêu cầu đó sẽ hoạt động trong tập lệnh.

Lọc so với tìm kiếm

Sau đó tôi chuyển sang Microsoft Search API, đây có lẽ là nơi tôi nên bắt đầu. API tìm kiếm sử dụng truy vấn Ngôn ngữ truy vấn từ khóa (KQL) để quét hộp thư nhằm tìm thư phù hợp dựa trên siêu dữ liệu (thuộc tính) hoặc nội dung (nội dung thư và tệp đính kèm) của chúng. Mặc dù các máy khách khác nhau trong cách triển khai nhưng API này là thứ mà máy khách Outlook sử dụng để tìm kiếm.

Thử thách ban đầu là soạn một truy vấn KQL phù hợp. Nếu bạn đã quen với việc soạn tiêu chí tìm kiếm cho các tìm kiếm tuân thủ (hoặc cho Hộp thư tìm kiếm) thì bạn biết rằng KQL hỗ trợ một tập hợp các thuộc tính cụ thể để tìm kiếm các mục email. Tập lệnh chấp nhận một loạt tham số bao gồm chủ đề thư, từ khóa, phạm vi ngày và địa chỉ người gửi mà nó xử lý để tạo truy vấn.

# Prepare search filter
$SearchFilter = "subject:$MessageSubject" 

If ($SenderAddress) {
  $SearchFilter = $SearchFilter + " AND from:$SenderAddress" }

If ($StartDate) {
   $StartDateFilter = (Get-Date $StartDate).toString('yyyy-MM-dd') }
 If (($StartDateFilter) -and (!($EndDate))) { # if we have a start date but no end date, set to today's date
   $EndDate = Get-Date }
 If ($EndDate) {
   $EndDateFilter = (Get-Date $EndDate).toString('yyyy-MM-dd') }

If (($StartDateFilter) -and ($EndDateFilter)) {
  $SearchFilter = $SearchFilter + " AND received>=$StartDateFilter AND received<=$EndDateFilter" }

If ($SearchQuery) {
  $SearchFilter = $SearchFilter + " AND '" + $SearchQuery + "'" }

Đây là giao diện của một truy vấn KQL đã được tổng hợp. Truy vấn này tìm kiếm các thư có “Cập nhật lên Sách Office 365” ở bất kỳ đâu trong chủ đề thư do Kim Akers gửi từ ngày 1 tháng 1 năm 2022 đến ngày 1 tháng 8 năm 2022:

subject:Update to Office 365 Book AND from:Kim.Akers@Office365itpros.com AND received>=2022-01-01 AND received<=2022-08-01

Một ví dụ khác tìm kiếm email Tóm tắt Viva hàng ngày

subject:Your daily briefing AND from:viva-noreply@microsoft.com AND received>=2021-01-01 AND received<=2022-08-02 AND 'Better with Microsoft Viva'

Để thực hiện tìm kiếm, chúng tôi soạn một yêu cầu API Đồ thị như sau. Bạn có thể thấy cách truy vấn KQL được chuyển và chúng tôi yêu cầu Biểu đồ trả về một tập hợp thuộc tính cho mỗi thông báo.

https://graph.microsoft.com/v1.0/users/aff4cd58-1bb8-4899-94de-795f656b4a18/mailfolders//messages?$search="subject:Update to Office 365 Book AND from:Kim.Akers@Office365itpros.com AND received>=2022-01-01 AND received<=2022-08-01"&$select=id,parentfolderid,receivedDateTime,subject,from

Tìm kiếm thư mục đích

Điều này đưa tôi đến các thư mục mục tiêu. Tập lệnh của tôi cho phép người dùng tìm kiếm một thư mục hoặc tất cả các thư mục trong hộp thư. Nếu tìm kiếm xử lý tất cả các thư mục thì kết quả sẽ giống như kết quả được tạo bởi tìm kiếm trong Outlook trên máy tính chỉ với một vấn đề. Tìm kiếm không quét các mục trong thư mục Các mục đã xóa. Điều này phụ thuộc vào việc thực hiện tìm kiếm ở các ứng dụng khách khác nhau. Máy tính để bàn Outlook không tìm kiếm thư mục Các mục đã Xóa trừ khi bạn tìm kiếm rõ ràng thư mục đó, nhưng OWA thì có. Cả hai ứng dụng khách đều sử dụng tính năng API Tìm kiếm của Microsoft để trình bày ba mục phù hợp nhất được tìm thấy trước tiên, trong khi tôi muốn có một danh sách đơn giản. Lệnh ghép ngắn Hộp thư tìm kiếm tìm thấy các mục trong tất cả các thư mục mà người dùng có thể nhìn thấy cùng với các thư mục trong cấu trúc Mục có thể phục hồi.

Giải pháp rất đơn giản: thực hiện một tìm kiếm cho thư mục Các mục đã Xóa và một tìm kiếm khác cho tất cả các thư mục khác rồi tổng hợp các kết quả. Có thể có cách tốt hơn để tìm kiếm tất cả các thư mục mà người dùng có thể nhìn thấy nhưng tôi không thể tìm thấy cách nào và cách giải quyết của tôi có hiệu quả.

Hiện tại, API Đồ thị không thể truy cập hộp thư lưu trữ. Nếu chức năng này là cần thiết, bạn cần phải viết nó bằng Dịch vụ Web Exchange.

Tên thư mục

Thông tin được trả về cho thư được tìm thấy bởi tìm kiếm trông giống như sau:

@odata.etag      : W/"FgAAAA=="
id               : AAMkADAzNzBmMzU0LTI3NTItNDQzNy04NzhkLWNmMGU1MzEwYThkNABGAAAAAAB_7ILpFNx8TrktaK8VYWerBwBe9CuwLc2fTK7W46L1SAp9AAAA2lHKAAA3tTkMTDKYRI6zB9VW59QNAASRem3ZAAA=
receivedDateTime : 2022-01-08T00:21:02Z
subject          : Office 365 Roadmap Updated: 2022-01-08
parentFolderId   : AAMkADAzNzBmMzU0LTI3NTItNDQzNy04NzhkLWNmMGU1MzEwYThkNAAuAAAAAAB_7ILpFNx8TrktaK8VYWerAQBe9CuwLc2fTK7W46L1SAp9AAAA2lHKAAA=

Thư mục chứa thư được lưu trữ trong parentFolderId. Giá trị này hoàn toàn có ý nghĩa đối với máy tính nhưng lại không có tác dụng nhiều đối với con người. Tôi cần một cách để giải quyết những giá trị này thành thứ gì đó có ý nghĩa, chẳng hạn như Inbox. Các mục đã xóa hoặc các mục đã gửi. Để diễn giải các mã định danh, tôi sử dụng API List mailFolders để tìm nạp tập hợp các thư mục trong hộp thư. Dữ liệu được trả về bao gồm mã định danh thư mục và tên hiển thị, vì vậy tôi có thể tạo bảng băm được khóa trên mã định danh thư mục để sử dụng làm tra cứu.

Xử lý thư mục con

Nhiều hộp thư có cấu trúc thư mục một cấp đơn giản nên chỉ cần tìm nạp danh sách thư mục từ thư mục gốc của hộp thư là đủ. Các hộp thư khác có các thư mục lồng nhau, giống như các thư mục được hiển thị trong Hình 1.

Thông tin được trả về bởi API List mailFolders bao gồm số lượng thư mục con, vì vậy thật dễ dàng để biết thư mục nào bao gồm các thư mục. Để xây dựng bảng băm nhằm bao gồm các mã nhận dạng thư mục và hiển thị tên của các thư mục lồng nhau, tập lệnh sẽ lặp lại bốn cấp độ để tìm và xử lý bất kỳ thư mục con nào mà nó có thể tìm thấy. Điều kỳ lạ là API List mailFolders không có bộ hạn định để hướng dẫn Đồ thị tìm nạp tất cả các thư mục trong hộp thư, nhưng đó là cách mọi thứ hoạt động.

Báo cáo hoặc Xóa

Hy vọng rằng khi tập lệnh chạy, nó sẽ tìm thấy một số thư trong hộp thư mục tiêu (Hình 2).

Một tham số sẽ xác định xem tập lệnh có báo cáo tin nhắn hay xóa (và báo cáo) tin nhắn hay không. Để xóa một tin nhắn, tập lệnh sẽ xây dựng một URI chứa mã định danh tin nhắn rồi thực hiện yêu cầu Xóa để xóa tin nhắn. Đây là giao diện của URI và yêu cầu API:

https://graph.microsoft.com/v1.0/users/aff4cd58-1bb8-4899-94de-795f656b4a18/messages/AAMkADAzNzBmMzU0LTI3NTItNDQzNy04NzhkLWNmMGU1MzEwYThkNABGAAAAAAB_7ILpFNx8TrktaK8VYWerBwBe9CuwLc2fTK7W46L1SAp9AAAA2lHKAAA3tTkMTDKYRI6zB9VW59QNAASRem3ZAAA=
$Status = Invoke-RestMethod $Uri -Method 'Delete' -Headers $Headers

Các tin nhắn đã xóa sẽ được chuyển vào thư mục con Xóa của các Mục có thể khôi phục. Người dùng có thể khôi phục các mục từ thư mục này. Nếu muốn chúng không thể khôi phục các mục, bạn có thể di chuyển thư vào một thư mục ẩn (chẳng hạn như thư mục con Thanh lọc trong các Mục có thể khôi phục).

Tất cả đã được thiết lập để xóa (Sau khi kiểm tra)

Bạn có thể tải xuống phiên bản mới nhất của tập lệnh từ GitHub. Vui lòng kiểm tra kỹ lưỡng trước khi bạn thực hiện bất kỳ thiệt hại thực sự nào. Đừng rơi vào cái bẫy mà rất nhiều người mắc phải trước đây khi chạy một tiện ích xóa email mà không biết mình đang làm gì. Đặc biệt, hãy chú ý đến các từ khóa được sử dụng trong truy vấn KQL vì chúng có thể tìm thấy những mục mà bạn không mong đợi.

Tôi thường chạy tập lệnh ở chế độ báo cáo để xem những thông báo nào được tìm thấy (Hình 3) trước khi cho phép nó xóa bất cứ thứ gì. Mặc dù người dùng có thể khôi phục các mục đã xóa nhưng sẽ tốt hơn nếu quản trị viên không xóa các mục họ không cần. Hãy thoải mái sống ở rìa và xóa tin nhắn mà không cần kiểm tra xem đó có phải là điều bạn muốn làm hay không.

Nếu bạn tìm thấy lỗi, vui lòng gửi vấn đề lên GitHub. Tốt hơn nữa, hãy sửa lỗi và cho tôi biết bạn đã làm gì. Tôi đánh giá cao bất kỳ sự giúp đỡ nào bạn có thể cung cấp!

Quản lý đường dẫn tấn công và chuỗi tiêu diệt Microsoft 365

Một chiến lược an ninh mạng hiệu quả đòi hỏi sự hiểu biết rõ ràng và toàn diện về cách thức các cuộc tấn công diễn ra. Đọc báo cáo nghiên cứu chuyên sâu này để có được thông tin chuyên sâu mà bạn cần để bảo vệ tổ chức của mình!

Bài viết liên quan