azure automation runbook 404 error when connecting to sharepoint online
I can't figure out why my new Azure Automation runbook is throwing a 404 error whe naccessing sharepoint online. Running the same code in local ISE works as expected.
The code does this: monitors a specific shared mailbox online for new mail with attachments. saves and renames attachments to Onedrive (sharepoint) moves the email to a "processed" folder, inserting a hyperlink to the file.
If I only have the Exchange portion of the code (move the email) it works fine online. Adding the Sharepoint part results in this:
ExchangeOnlineManagement, Microsoft.Graph.Authentication and SharePointPnPPowerShellOnline all loaded with RT 7.2.
API permissions set:
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
}
}
Any ideas? I've been trying for the past day to figure this out. ChatGPT hasn't helped.
Brad