azure automation runbook 404 error when connecting to sharepoint online

Brad 0 Reputation points
2024-09-22T01:43:00.1233333+00:00

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.image

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: User's image

Brad

Microsoft Exchange Online
Azure Automation
Azure Automation
An Azure service that is used to automate, configure, and install updates across hybrid environments.
1,256 questions
SharePoint Development
SharePoint Development
SharePoint: A group of Microsoft Products and technologies used for sharing and managing content, knowledge, and applications.Development: The process of researching, productizing, and refining new or existing technologies.
2,972 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,510 questions
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.