I need to be able to retrieve email messages for particular multiple recipients inside sentitems, when i run my code, i get error bad request error 400
. Am looping thru each recipient who i need their emails retrieved. The goal is for me to input a number of recipients email addresses that I sent emails then retrieve the emails and save into csv.
The error is present in the request endpoint, my endpoint.
$nextLink = "https://graph.microsoft.com/v1.0/users/${mailuser}/mailFolders/SentItems/messages?`$filter=(sentDateTime ge ${startDate})&`$search='to:${recipientUser}'&`$select=sentDateTime,subject,toRecipients,bodyPreview,ccRecipients"
Below is the entire code.
# Azure AD app registration details
$appId = ""
$appSecret = ""
$tenantId = ""
# User to retrieve mail sent messages(your email, since you're the sender)
$mailuser = "myemail@mydomain.com"
# User email addresses that you sent emails to, separated by commas
$recipientUsers = "user1@theirdomain.com", "user2@externaldomain.com"
# Date range for filtering emails
$startDate = '2022-01-01T00:00:00Z'
# Define the folder path to store the results
$tempFolderPath = "C:\Temp"
# Check if the folder exists, if not, create it
if (-not (Test-Path $tempFolderPath)) {
New-Item -Path $tempFolderPath -ItemType Directory -Force
}
# Define CSV file path
$csvFilePath = "$tempFolderPath\sentitemsemail_data2.csv"
# Define API endpoint and parameters for authentication
$authEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
$authBody = @{
client_id = $appId
client_secret = $appSecret
scope = "https://graph.microsoft.com/.default"
grant_type = "client_credentials"
}
# Define function to get request headers for Graph API
function Get-RequestHeaders {
$tokenResponse = Invoke-RestMethod -Method Post -Uri $authEndpoint -Body $authBody
$accessToken = $tokenResponse.access_token
@{
'Authorization' = "Bearer $($accessToken)"
'Accept' = 'application/json'
}
}
# Define function to retrieve messages
function Get-Messages {
param (
[string]$url
)
$requestHeaders = Get-RequestHeaders
Invoke-RestMethod -Method Get -Uri $url -Headers $requestHeaders
}
# Define function to export email object to CSV
function Export-EmailObjectToCSV {
param (
[object]$emailObject
)
$emailObject | Export-Csv -Path $csvFilePath -Append -NoTypeInformation
}
# Loop through each recipient user
foreach ($recipientUser in $recipientUsers) {
# Initialize $nextLink variable with the initial endpoint URL, from $startDate to current date
$nextLink = "https://graph.microsoft.com/v1.0/users/${mailuser}/mailFolders/SentItems/messages?`$filter=(sentDateTime ge ${startDate})&`$search='to:${recipientUser}'&`$select=sentDateTime,subject,toRecipients,bodyPreview,ccRecipients"
# Loop until all pages are fetched
do {
# Retrieve messages for the current page
$messages = Get-Messages -url $nextLink
# Loop through each message
foreach ($message in $messages.value) {
$subject = $message.subject
$sentdatetime = $message.sentDateTime
$bodyPreview = $message.bodyPreview
# Initialize an array to store all CC recipient addresses
$ccRecipientAddresses = New-Object System.Collections.ArrayList
foreach ($recipient in $message.toRecipients) {
$recipientName = $recipient.emailAddress.name
$recipientAddress = $recipient.emailAddress.address
# Loop through each CC recipient and store their address
foreach ($torecipient in $message.ccRecipients){
[void]$ccRecipientAddresses.Add($torecipient.emailAddress.address)
}
# Create a new object to store the data
$emailObject = [PSCustomObject]@{
Subject = $subject
RecipientName = $recipientName
RecipientAddress = $recipientAddress
ToRecipientAddresses = $ccRecipientAddresses -join ", "
SentDateTime = $sentdatetime
BodyPreview = $bodyPreview
}
# Export each email object to the CSV file
Export-EmailObjectToCSV -emailObject $emailObject
}
}
# Check if there are more pages to fetch
if ($messages."@odata.nextLink") {
$nextLink = $messages."@odata.nextLink"
}
else {
$nextLink = $null # If no more pages, exit the loop
}
} while ($nextLink)
}
You can't combine $filter
and $search
query parameters for messages
.
Filter can be moved to $search
query parameter. Search value must be enclosed in double quotes.
GET /v1.0/users/${mailuser}/mailFolders/SentItems/messages?$search="to:${recipientUser} AND sent>=${startDate}"&$select=sentDateTime,subject,toRecipients,bodyPreview,ccRecipients
PS
$nextLink = "https://graph.microsoft.com/v1.0/users/${mailuser}/mailFolders/SentItems/messages?&`$search=""to:${recipientUser} AND sent>=${startDate}""&`$select=sentDateTime,subject,toRecipients,bodyPreview,ccRecipients"