Cải thiện hiệu suất của Microsoft Graph PowerShell bằng tính năng Batching
Có thể sử dụng tính năng tạo khối (còn được gọi là tạo khối JSON) với Microsoft Graph PowerShell để cải thiện hiệu suất của các tập lệnh hiện có cần tương tác với các dịch vụ trong Microsoft 365, Microsoft Entra hoặc Microsoft Intune.
Khái niệm phân khối khá đơn giản. Bạn thu thập thông tin để thực hiện nhiều yêu cầu rồi gửi chúng dưới dạng 'lô' tới API Microsoft Graph. Điều này cho phép bạn thực hiện nhiều yêu cầu cùng lúc, do đó cải thiện tổng thời gian của tập lệnh.
Phân nhóm yêu cầu là gì?
Việc phân nhóm yêu cầu cho phép các ứng dụng kết hợp nhiều yêu cầu với Microsoft Graph để cải thiện hiệu suất và giảm độ trễ. Nó cũng có thể được sử dụng trong Microsoft Graph PowerShell để giúp quản trị viên cải thiện hiệu suất của các tác vụ và tập lệnh quản lý.
Lô yêu cầu là tập hợp các yêu cầu bên trong một đối tượng JSON duy nhất, trong PowerShell, có thể được lưu trữ trong một biến. Đối tượng JSON có thể được tạo theo nhiều cách, bao gồm:
- Bằng cách xác định thủ công giữa các chuỗi ở đây.
- Bằng cách xác định một bảng băm và chuyển đổi nó thành JSON.
- Bằng cách xây dựng một đối tượng thông qua mã và chuyển đổi nó thành JSON (hiệu quả nhất)
Sau đó, lô này có thể được gửi tới Microsoft Graph bằng cách sử dụng lệnh ghép ngắn Invoke-RestMethod hoặc Invoke-MgGraphRequest bằng phương thức POST.
Khi nào bạn nên sử dụng yêu cầu hàng loạt?
Việc sử dụng cơ chế tạo khối yêu cầu trong Microsoft Graph sẽ làm tăng thêm độ phức tạp cho tập lệnh của bạn. Vì vậy, mặc dù nó có thể cải thiện hiệu suất mã của bạn và 'thời gian xuất ra', nhưng nó thường làm cho mã của bạn khó đọc hơn đối với những người khác có thể cần đọc hoặc kế thừa mã đó. Vì vậy, tôi chỉ khuyên bạn nên gửi yêu cầu theo nhóm khi bạn phải gửi nhiều yêu cầu tới Microsoft Graph (trên 20).
Một ví dụ về nơi nó có thể mang lại lợi ích cho bạn là nếu bạn đang xóa nhiều người dùng hoặc thiết bị khỏi môi trường của mình. Mặc dù việc sử dụng tính năng lọc bằng Microsoft Graph để truy xuất danh sách các đối tượng rất dễ dàng nhưng việc xóa chúng sẽ yêu cầu các yêu cầu xóa riêng lẻ. Giả sử bạn cần xóa 100 đối tượng khỏi thư mục của mình, thay vì gửi 100 yêu cầu riêng lẻ tới Microsoft Graph và đợi mỗi yêu cầu thực thi trước khi bắt đầu yêu cầu tiếp theo. Trong trường hợp đó, chúng có thể được nhóm thành nhóm 20, vì vậy bạn chỉ cần thực hiện 5 yêu cầu tới Microsoft Graph.
Lợi ích về hiệu suất của việc tạo khối trong PowerShell
Tôi đã thực hiện một số thử nghiệm thực tế về việc sử dụng tính năng theo đợt và các lợi ích về hiệu suất. Để làm được điều này, tôi đã tạo 2000 người dùng thử nghiệm trong Microsoft Entra (những người dùng này không được cấp phép hoặc cung cấp). 1000 người dùng tôi đã lưu trữ trong biến $1to1000 và 1000 người dùng còn lại được lưu trữ trong biến $1001to2000.
Đây là đoạn script đầu tiên bên dưới được chạy để xóa 1000 người dùng. Tập lệnh này đã gửi một yêu cầu riêng lẻ để xóa từng người dùng.
Foreach ($user in $1to1000){
Remove-MgUser -UserId $user.id
}Sử dụng lệnh ghép ngắn Measure-Command, tổng thời gian để hoàn thành việc xóa người dùng mất 33 giây
Sau đó, tôi chạy đoạn mã sau, sắp xếp các yêu cầu theo nhóm 20 rồi gửi chúng dưới dạng một yêu cầu duy nhất.
for($i=0;$i -lt $1001to2000.count;$i+=20){
$batch = @{}
$batch['requests'] = ($1001to2000[$i..($i+19)] | select @{n='id';e={$_.id}},@{n='method';e={'DELETE'}},`
@{n='url';e={"/users/$($_.id)"}})
Invoke-mggraphrequest -Method POST -URI "https://graph.microsoft.com/v1.0/`$batch" -body ($batch | convertto-json) -OutputType PSObject
}Bạn có thể thấy tổng thời gian hoàn thành là 12 giây, đây là một sự cải thiện đáng kể.
Ví dụ về yêu cầu phân nhóm
Dưới đây là một ví dụ về yêu cầu hàng loạt JSON cho Microsoft Graph. Bạn có thể thấy rằng nội dung của yêu cầu được bao quanh bởi các chuỗi ở đây (@’ ‘@).
Chuỗi ở đây có thể được chỉ định bằng một dấu ngoặc đơn (như bạn thấy bên dưới) hoặc thay vào đó sử dụng dấu ngoặc kép. Sự khác biệt là trích dẫn duy nhất lấy văn bản theo nghĩa đen và sẽ không mở rộng các biến. Tuy nhiên, dấu ngoặc kép sẽ cho phép các biến có thể mở rộng.
Sau đó, lệnh ghép ngắn Invoke-MgGraphRequest được sử dụng với phương thức POST. Tôi cũng đã sử dụng dấu backtick ( ` ) trong đường dẫn web URI. Điều này đảm bảo chuỗi $batch được hiểu theo nghĩa đen và không được mở rộng dưới dạng biến, điều này bắt buộc đối với yêu cầu hàng loạt.
Sau đó, biến $batch chứa nội dung yêu cầu sẽ được sử dụng cùng với biến -body để gửi yêu cầu.
$batch = @'
{
"requests": [
{
"id": "1",
"method": "GET",
"url": "/users/[email "
},
{
"id": "2",
"method": "GET",
"url": "/users/[email "
},
{
"id": "3",
"method": "GET",
"url": "/users/[email "
}
]
}
'@
$response = Invoke-MgGraphRequest `
-Method POST `
-URI "https://graph.microsoft.com/beta/`$batch" `
-body $batch `
-OutputType PSObjectViệc lưu phản hồi vào một biến sẽ đảm bảo bạn có thể tham khảo lại dữ liệu bằng ký hiệu dấu chấm. Bạn có thể sử dụng ví dụ bên dưới để trích xuất tên người dùng và địa chỉ email của những người dùng được xác định trong yêu cầu hàng loạt.
$response.responses.body | Select UserPrincipalName, proxyaddresses | ftTạo yêu cầu hàng loạt
Trong ví dụ trước đây, tôi đã chứng minh lợi ích về hiệu suất của việc sử dụng yêu cầu hàng loạt. Với điều này, tôi đã sử dụng vòng lặp PowerShell For để tạo lô JSON cho mỗi yêu cầu, trong đó quan trọng là mỗi yêu cầu lặp lại đối với một đối tượng khác cùng loại. Điều này cho phép bạn sử dụng hiệu quả tính năng tạo khối với PowerShell, nếu không thì việc này sẽ không thực tế. Đây là mã mẫu:
for($i=0;$i -lt $objects.count;$i+=20){
$batch = @{}
$batch['requests'] = ($objects[$i..($i+19)] | select @{n='id';e={$_.id}},@{n='method';e={'DELETE'}},`
@{n='url';e={"/users/$($_.id)"}})
invoke-mggraphrequest -Method POST -URI "https://graph.microsoft.com/v1.0/`$batch" -body ($batch | convertto-json) -OutputType PSObject
}Để phân tích logic đằng sau điều này, vòng lặp For (hoặc câu lệnh For) có ba phần thông tin chính trong cú pháp của nó mà tôi đã đánh dấu trong hình ảnh bên dưới ở dòng đầu tiên.
$i=0. Lệnh này sẽ chạy trước khi vòng lặp bắt đầu. Nó được sử dụng để tạo và khởi tạo một biến có giá trị bắt đầu là 0.
$i -lt $obects.count. Câu lệnh này là điều kiện (hoặc quy tắc) và nó yêu cầu tiếp tục thực hiện vòng lặp này trong khi biến ban đầu $i nhỏ hơn tổng số lượng đối tượng trong bộ sưu tập (hoặc mảng).
$i+=20. Đây là tuyên bố trở lại. Điều này sẽ được thực thi trên mỗi vòng lặp và 20 sẽ được thêm vào giá trị của $i. Vì vậy, ở vòng lặp đầu tiên $i=0, sau đó ở vòng lặp tiếp theo $i=20, rồi 40, v.v.
Điều này cho phép mã lặp trong khi thêm 20 vào $i trên mỗi vòng lặp, điều này rất cần thiết trong bước tiếp theo.
Mảng $objects được đánh dấu bên dưới và trong ngoặc vuông là bộ chọn phạm vi. Trong lần chuyển đầu tiên của vòng lặp $i=0 và $i+19=19, thao tác này sẽ chọn 20 đối tượng đầu tiên trong mảng để đưa vào đối tượng đầu tiên yêu cầu hàng loạt.
Câu lệnh return sau đó sẽ thêm 20 vào $i sẵn sàng cho vòng lặp thứ hai; trong vòng lặp thứ hai, $i=20 và $i+19=39, chọn 20 mục tiếp theo từ mảng và thêm chúng vào yêu cầu lô tiếp theo. Điều này sẽ tiếp tục cho đến khi $i nhỏ hơn tổng số đối tượng trong mảng. Kết quả là tất cả các đối tượng trong mảng sẽ được gửi tới Microsoft Graph trong một yêu cầu hàng loạt.
Kết thúc
Mặc dù yêu cầu hàng loạt có thể cải thiện đáng kể hiệu suất của tập lệnh nhưng hãy sử dụng chúng một cách khôn ngoan vì độ phức tạp tăng thêm có thể là vấn đề khi cộng tác làm việc trên tập lệnh, đặc biệt nếu tác động đến hiệu suất tổng thể là tối thiểu.
Ngoài ra còn có nhiều cách khác nhau để bạn có thể tạo yêu cầu hàng loạt. Tôi đã trình bày ở trên cách tạo yêu cầu theo chương trình bằng cách sử dụng câu lệnh For trong PowerShell. Điều này hoạt động để lặp lại các loại yêu cầu. Tuy nhiên, một phương pháp thay thế có thể lưu trữ thông tin yêu cầu bên ngoài tập lệnh của bạn (chẳng hạn như trong tệp CSV), sau đó nhập thông tin đó qua mã.



