1+ function Invoke-BatchWithRetry {
2+ param (
3+ [array ]$BatchRequests ,
4+ [int ]$MaxRetries = 3
5+ )
6+ $batchUri = " https://graph.microsoft.com/v1.0/`$ batch"
7+ $responses = @ {}
8+ $pending = @ ($BatchRequests ) # Ensure it's an array
9+ $retryCount = 0
10+
11+ while ($pending.Count -gt 0 -and $retryCount -le $MaxRetries ) {
12+ $batchBody = @ {
13+ requests = $pending
14+ } | ConvertTo-Json - Depth 5
15+
16+ $result = Invoke-MgGraphRequest - Method POST - Uri $batchUri - Body $batchBody - ContentType " application/json"
17+ foreach ($resp in $result.responses ) {
18+ " Id : $ ( $resp.id ) , Status : $ ( $resp.status ) " | Out-File - FilePath " Path\To\log.txt" - Append
19+ if ($resp.status -eq 429 ) {
20+ # Do nothing - will retry later
21+ } else {
22+ $responses [$resp.id ] = $resp
23+ # Remove from pending
24+ $pending = $pending | Where-Object { $_.id -ne $resp.id }
25+ }
26+ }
27+
28+ if ($pending.Count -gt 0 ) {
29+ Start-Sleep - Seconds 5
30+ $retryCount ++
31+ }
32+ }
33+ return $responses
34+ }
35+
36+ # Get Users
37+
38+ if (-not (Get-Command Connect-Entra - ErrorAction SilentlyContinue)) {
39+ Write-Error " Connect-Entra not found. Install Microsoft.Entra and run Connect-Entra."
40+ return
41+ }
42+
43+ if (-not (Get-EntraContext )) {
44+ $errorMessage = " Not connected to Microsoft Entra. Use 'Connect-Entra -Scopes User.Read.All' to authenticate."
45+ Write-Error - Message $errorMessage - ErrorAction Stop
46+ return
47+ }
48+
49+ $users = Get-EntraUser - All
50+
51+ # Prepare batch requests (20 per batch)
52+ $batchSize = 20
53+ $allResults = @ {}
54+ for ($i = 0 ; $i -lt $users.Count ; $i += $batchSize ) {
55+ $batch = @ ()
56+ $batchUsers = $users [$i .. ([Math ]::Min($i + $batchSize - 1 , $users.Count - 1 ))]
57+ foreach ($user in $batchUsers ) {
58+ $batch += @ {
59+ id = $user.id
60+ method = " GET"
61+ url = " /users/$ ( $user.id ) /authentication/methods"
62+ }
63+ }
64+ $responses = Invoke-BatchWithRetry - BatchRequests $batch - debug
65+ foreach ($id in $responses.Keys ) {
66+ $allResults [$id ] = $responses [$id ]
67+ }
68+
69+ $activity = " Processed Users - $i of $ ( $users.count ) - $ ( [System.Math ]::Round($i / $ ($users.count ) * 100 )) %"
70+
71+ Write-Progress - Activity $activity - Status " Fetching authentication methods" - PercentComplete (($i / $users.count ) * 100 )
72+ }
73+
74+ Write-Output " Completed fetching authentication methods for $ ( $users.count ) users. Returned results for $ ( $allResults.Count ) users."
75+
76+ # How to execute this script:
77+
78+ # . .\samples\batch\Invoke-BatchWithRetry.ps1
79+
80+ # To execute the script and measure performance, you can use the following command:
81+
82+ # Measure-Command { . .\samples\batch\Invoke-BatchWithRetry.ps1 }
0 commit comments