Entra / Microsoft 365 · Exchange Online
Test batch processing
A script to demonstrate how to use batch processing with Microsoft Graph API by using mailboxes fetched from Exchange.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes "User.Read.All" -NoWelcomeConnect-ExchangeOnline -SkipLoadingCmdletHelp
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
$CSVOutputFile = "C:\Temp\UserReport.csv"$SkuDataPath = "C:\temp\SkuDataComplete.csv"If ((Test-Path $SkuDataPath) -eq $False) {Write-Host ("Can't find the product data file ({0}). Exiting..." -f $SkuDataPath) ; break}$ImportSkus = Import-CSV $SkuDataPath$SkuHashTable = @{}ForEach ($Line in $ImportSkus) {$SkuHashTable.Add([string]$Line.SkuId, [string]$Line.DisplayName)}# Connects to the Graph (to read user data) and Exchange Online (to get mailboxes)Connect-MgGraph -Scopes "User.Read.All" -NoWelcomeConnect-ExchangeOnline -SkipLoadingCmdletHelp# Fetch all mailboxesWrite-Host "Fetching mailboxes..."[array]$Mbx = Get-ExoMailbox -RecipientTypeDetails UserMailbox -ResultSize UnlimitedIf ($Mbx.Count -eq 0) {Write-Host "No mailboxes found"Break} Else {Write-Host ("Total of {0} mailboxes found" -f $Mbx.Count)}# Define batch size (maxiumum 20)$BatchSize = 20# Define output list (concurrent bag to store user details)$UserDetails = [System.Collections.Concurrent.ConcurrentBag[System.Object]]::new()$Batches = For($i = 0; $i -lt $Mbx.count; $i += $BatchSize) {$End = $i + $BatchSize - 1If ($end -ge $Mbx.count) {$end = $Mbx.count}$Index = $i# Create requests from the next batch of mailboxes$Index = $i$Requests = $Mbx[$i..($end)]# For each mailbox in the batch, create a request to get user details$RequestData = [System.Collections.Generic.List[Object]]::new()ForEach ($Request in $Requests) {# the URL is the Graph lookup request to fetch user account details$Url = "users/{0}?`$select=id,displayname,assignedLicenses,country,city,jobtitle,officelocation,userprincipalname,businessphones,employeeid,employeehiredate" -f $Request.ExternalDirectoryObjectId$ReportLine = [PSCustomObject]@{Id = $Index++Method = 'GET'Url = $Url}$RequestData.Add($ReportLine)}# Create a batch request@{'Method' = 'Post''Uri' = 'https://graph.microsoft.com/v1.0/$batch''ContentType' = 'application/json''Body' = @{'requests' = @($RequestData)} | ConvertTo-Json}}$Batches | ForEach-Object -Parallel {$Responses = $using:UserDetails$RequestSubmission = Invoke-MgGraphRequest @PSItem# Invoke-MgGraphRequest deserializes request to a hashtable$RequestSubmission.responses | ForEach-Object { $responses.Add([pscustomobject]$PSItem.Body) }}If ($UserDetails.Count -ne $Mbx.Count) {throw [System.Exception]::new()}Write-Host ("Total of {0} user accounts processed" -f $UserDetails.count)# Create a hash table containing the user data$UserHash = @{}ForEach ($User in $UserDetails) {$UserHash.Add($User.Id,$User)}# Create the report by combining mailbox and user data$UserReport = [System.Collections.Generic.List[Object]]::new()ForEach ($Mailbox in $Mbx) {$User = $UserHash[$Mailbox.ExternalDirectoryObjectId]# Resolve product license names from the SKU identifiers[array]$AssignedLicenses = $nullForEach ($License in $User.assignedLicenses.SkuId) {$SKUName = $SkuHashTable[$License]$AssignedLicenses += $SKUName}$UserReport.Add([PSCustomObject]@{DisplayName = $User.DisplayNameUserPrincipalName = $User.UserPrincipalNameSMTPAddress = $Mailbox.PrimarySmtpAddressCity = $User.CityCountry = $User.Country'Job Title' = $User.JobTitle'Office Location' = $User.OfficeLocation'Business Phones' = $User.BusinessPhones -join ', ''Assigned Licenses' = $AssignedLicenses -join ', 'EmployeeId = $User.EmployeeId'Employee Hire Date' = $User.EmployeeHireDate})}# Generate a CSV file and display the report in a grid view$UserReport | Export-CSV -Path $CSVOutputFile -NoTypeInformation -Encoding UTF8Write-Host ("CSV file available in {0}" -f $CSVOutputFile)$UserReport | Sort-Object DisplayName | Out-GridView -Title "User Account Information"
Attribution
Author
Office365itpros