Microsoft Exchange Online
A Microsoft email and calendaring hosted service.
1,842 questions
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Hi,
I have a Powershell script that runs fine in my local ISE, but fails with a 404 in the Azure Automation runbook.
The script checks a specific inbox in Exchange online for new emails with attachments, saves and renames the attachments to a specific Onedrive folder ID, removes the attachment, moves the email to a "processed" subfolder, and leaves a hyperlink in the message body.
I've loaded modules: Microsoft.Graph.Authentication RT 7.2, SharePointPnPPowerShellOnline and ExchangeOnlineManagement.
Auth Microsoft Graph
$TenantId = "62c95cb0-c41c-4b58-8e43-33333332db"
$ClientId = "243755bf-6b6c-49aa-a333-333333336bdf"
$ClientSecret = "gW08Q~k-------------33333333"
# Authentication and OAuth
$Scope = "https://graph.microsoft.com/.default"
# Get OAuth token
$authBody = @{
client_id = $ClientId
scope = $Scope
client_secret = $ClientSecret
grant_type = "client_credentials"
}
$authResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" -ContentType "application/x-www-form-urlencoded" -Body $authBody
$accessToken = $authResponse.access_token
# Define the authorization headers
$headers = @{
Authorization = "Bearer $accessToken"
}
# Define OneDrive folder
$driveId = "b!vAeeku-5w0GqnHnRIAkKuiX-333333333333333333333333333-8R"
$oneDriveFolder = "Incident Reports"
Write-Host "Using OneDrive folder: $oneDriveFolder"
# Function to upload file to OneDrive
function Upload-ToOneDrive {
param (
[string]$newFileName,
[byte[]]$fileContent
)
# Prepare the upload URL
$uploadUrl = "https://graph.microsoft.com/v1.0/drives/${driveId}/root:/${oneDriveFolder}/${newFileName}:/content"
Write-Host "Uploading file to OneDrive at: $uploadUrl"
# Prepare the headers for upload
$uploadHeaders = @{
Authorization = "Bearer $accessToken"
"Content-Type" = "application/octet-stream"
}
# Upload the file
try {
$uploadResult = Invoke-RestMethod -Uri $uploadUrl -Method PUT -Headers $uploadHeaders -Body $fileContent
Write-Host "File successfully uploaded to OneDrive: $newFileName"
}
catch {
Write-Host "Error uploading file to OneDrive: $_.Exception.Message"
}
}
# Fetch all emails with attachments from the Inbox folder (pagination added)
$messagesUrl = "https://graph.microsoft.com/v1.0/users/$mailbox/mailFolders/$inboxId/messages?\$filter=hasAttachments eq true&\$top=100"
Write-Host "Fetching emails with attachments from Inbox: $messagesUrl"
$messagesResponse = Invoke-RestMethod -Uri $messagesUrl -Headers $headers -Method Get
$messages = $messagesResponse.value
# Pagination - fetch all messages if there are more than 100
while ($messagesResponse.'@odata.nextLink') {
$nextUrl = $messagesResponse.'@odata.nextLink'
Write-Host "Fetching next batch of emails: $nextUrl"
$messagesResponse = Invoke-RestMethod -Uri $nextUrl -Headers $headers -Method Get
$messages += $messagesResponse.value
}
Write-Host "Retrieved" $messages.Count "emails with attachments from Inbox"
# Loop through each message to fetch attachments
foreach ($message in $messages) {
# Get sender's address and received date for renaming
$receivedDateTime = [DateTime]::Parse($message.receivedDateTime).ToString("yyyyMMddHHmmss")
$senderAddress = $message.from.emailAddress.address.Split("@")[0]
$attachmentUrl = "https://graph.microsoft.com/v1.0/users/$mailbox/messages/$($message.Id)/attachments"
$attachments = Invoke-RestMethod -Uri $attachmentUrl -Headers $headers -Method Get
foreach ($attachment in $attachments.value) {
# Check if the attachment is inline (embedded in the email)
if ($attachment.isInline -eq $true) {
Write-Host "Skipping embedded image: $($attachment.name)"
continue
}
# Otherwise, process as a regular attachment
# Extract the base name and extension separately
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($attachment.name)
$extension = [System.IO.Path]::GetExtension($attachment.name)
# Create the new file name with the correct format
$newFileName = "$baseName" + "_" + "$receivedDateTime" + "_($senderAddress)" + "$extension"
# Convert the attachment content from Base64
$content = [System.Convert]::FromBase64String($attachment.ContentBytes)
# Upload the attachment directly to OneDrive
Upload-ToOneDrive -newFileName $newFileName -fileContent $content
}
}
The only result I see is:
Brad