I'm using Powershell to get some emails from Office 365. This is how I set my token, and it works great for reading emails. Now I want to mark an email as read.
if ($token -ne $null)
{
$body = @{
client_id = $clientID
scope = "https://graph.microsoft.com/.default"
client_secret = $clientSecret
grant_type = "client_credentials"
}
$URL = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
try { $tokenRequest = Invoke-WebRequest -Method Post -Uri $URL -ContentType "application/x-www-form-urlencoded" -Body $body -UseBasicParsing -ErrorAction Stop }
catch {
Write-Host "Unable to obtain access token, aborting..."
Write-Host "Error Message: $($Error[0])"
return
}
$token = ($tokenRequest.Content | ConvertFrom-Json).access_token
#Write-Host("Got Token=$token")
}
$authHeader1 = @{
'Content-Type'='application\json'
'Authorization'="Bearer $token"
}
This is my function to mark one specific email as read:
function MarkSingleEmailAsRead ($emailId, $headers)
{
<# This is what we need to post as an example
POST https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/messages/markRead
Content-Type: application/json
{
"messageIds": ["MC172851", "MC167983"]
}
#>
$graphApiPostUrl = "https://graph.microsoft.com/v1.0/admin/serviceAnnouncement/messages/markRead"
$body = @{
"messageIds" = @($emailId)
}
Write-Host "Headers="
$headers | ConvertTo-Json | Write-Host
Write-Host "Body="
$body | ConvertTo-Json | Write-Host
try {
$results = Invoke-WebRequest -Method Post -Uri $graphApiPostUrl-ContentType "application/x-www-form-urlencoded"
-Body $body -Headers $headers -UseBasicParsing -ErrorAction Stop
}
catch {
Write-Host "Error Message: $($Error[0])"
return
}
}
I'm able to retrieve a list of emails, but when I try to mark one as read, I'm getting this error:
Error Message: The remote server returned an error: (401) Unauthorized.
Specifically, can I or how can I change this line to specify the scope I need. I would like to use the same token for both the retrieval and the update (mark as read). I think I'm limited to accessing one specific email, and not entirely sure if there needs to be a change on the Azure side to give some update permissions as well.
scope = "https://graph.microsoft.com/.default"
I have tried these two, but I'm not sure which scope to use, or exactly where it goes:
scope = "https://graph.microsoft.com/AdministrativeUnit.ReadWrite.All"
scope = "https://graph.microsoft.com/.default AdministrativeUnit.ReadWrite.All"