private/new-ExOQuery.ps1
function New-ExOQuery { <# Author = "Jos Lieben (jos@lieben.nu)" CompanyName = "Lieben Consultancy" Copyright = "https://www.lieben.nu/liebensraum/commercial-use/" #> [CmdletBinding()] Param( [parameter(Mandatory = $True)]$cmdlet, $cmdParams, [Switch]$NoPagination, $retryCount = 3 ) $token = Get-AccessToken -Resource "https://outlook.office365.com" if ($cmdParams) { $Params = $cmdParams }else { $Params = @{} } $ExoBody = ConvertTo-Json -Depth 15 -InputObject @{ CmdletInput = @{ CmdletName = $cmdlet Parameters = $Params } } if(!$global:OnMicrosoft){ $global:OnMicrosoft = (New-GraphQuery -Method GET -Uri 'https://graph.microsoft.com/v1.0/domains?$top=999' | Where-Object -Property isInitial -EQ $true).id } $Headers = @{ Authorization = "Bearer $token" "Accept-Charset" = "UTF-8" "X-ResponseFormat" = "json" "Accept" = "application/json" "X-ClientApplication" ="ExoManagementModule" "Prefer" = "odata.maxpagesize=1000" "X-CmdletName"= $cmdlet "X-SerializationLevel" = "Partial" 'X-AnchorMailbox' = "UPN:SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@$($global:OnMicrosoft)" "Content-Type" = "application/json" } $nextURL = "https://outlook.office365.com/adminapi/beta/$($global:OnMicrosoft)/InvokeCommand" $ReturnedData = do { try { $attempts = 0 while ($attempts -lt $retryCount) { try { $Data = Invoke-RestMethod -Uri $nextURL -Method POST -Body $ExoBody -Headers $Headers -Verbose:$false $attempts = $retryCount }catch { $attempts++ if ($attempts -eq $retryCount) { $nextUrl = $null Throw $_ } $sleepTime = $attempts * 2 Write-Verbose "EXO request failed, sleeping for $sleepTime seconds..." Start-Sleep -Seconds $sleepTime } } if($NoPagination){ $nextURL = $null }elseif($Data.'@odata.nextLink'){ $nextURL = $Data.'@odata.nextLink' }elseif($Data.'odata.nextLink'){ $nextURL = $Data.'odata.nextLink' }else{ $nextURL = $null } if($Data.psobject.properties.name -icontains 'value' -or $Data.Keys -icontains 'value'){ ($Data.value) }else{ ($Data) } }catch { $ReportedError = ($_.ErrorDetails | ConvertFrom-Json -ErrorAction SilentlyContinue) $Message = if ($ReportedError.error.details.message) { $ReportedError.error.details.message } else { $ReportedError.error.innererror.internalException.message } if ($null -eq $Message) { $Message = $($_.Exception.Message) } throw $Message } }until($null -eq $nextURL) [System.GC]::GetTotalMemory($true) | out-null [System.GC]::Collect() return $ReturnedData } |