azure automation runbook 404 error when connecting to sharepoint online

Brad 0 Reputation points
2024-09-22T01:56:54.6+00:00

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:

User's image

ExchangeOnlineManagement, Microsoft.Graph.Authentication and SharePointPnPPowerShellOnline all loaded with RT 7.2.

API permissions set:

User's image

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

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.