Entra / Microsoft 365 · Exchange Online
Upload large attachment chunks
An example to show how to upload a large attachment in byte chunks for a draft message and then send the message.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes "Mail.Send", "Mail.ReadWrite" -NoWelcome
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
Connect-MgGraph -Scopes "Mail.Send", "Mail.ReadWrite" -NoWelcome# Custiomize this address!$RecipientAddress = 'Hans.Geering@Office365ITPros.com'# Customize this path to a large file that exists on your system$AttachmentFile = "C:\Temp\PowerShellBook.pdf"[int32]$MaxAttachmentSize = 146800640$FileStream = New-Object System.IO.StreamReader($AttachmentFile)$FileSize = $FileStream.BaseStream.Length# The maxiumum size of an attachment is 150 MB (157286400 bytes). There's some overhead, so we'll restrict this to 140 MB (146800640 bytes).If ($FileSize -gt $MaxAttachmentSize) {Write-Host ("Attachment {0} is too large ({1} bytes). Maximum size is {2} bytes (140 MB)" -f $AttachmentFile, $FileSize, $MaxAttachmentSize)Break}# Build structure for the attachment$AttachmentDetail = @{}$AttachmentDetail.Add("attachmentType", "file")$AttachmentDetail.Add("name", [System.IO.Path]::GetFileName($AttachmentFile))$AttachmentDetail.Add("size", $FileSize)$AttachmentParams = @{}$AttachmentParams.Add("AttachmentItem", $AttachmentDetail)# Create message structure$HtmlBody = "<b>Isn't it nice to get a large attachment?<b>"$MsgSubject = "A very large attachment for you to read"$MsgFrom = (Get-MgContext).Account$MsgParams = @{}$MsgParams.Add("Content", $HtmlBody)$MsgParams.Add("ContentType", "html")$EmailAddress = @{address = $RecipientAddress}$EmailRecipient = @{EmailAddress = $EmailAddress}Write-Host "Sending welcome email to Hans Geering"# Create a draft message in the signed-in user's mailbox$NewMessage = New-MgUserMessage -UserId $MsgFrom -Body $MsgParams -ToRecipients $EmailRecipient -Subject $MsgSubject# Create an upload session$UploadSession = New-MgUserMessageAttachmentUploadSession -UserId $MsgFrom -MessageId $NewMessage.Id -BodyParameter $AttachmentParams# Define chunk size for uploading attachments. Must be a multiple of 320 KB ( 327680 bytes)[Int32]$uploadChunkSize = 983040# Upload the attachment file in chunks$FileOffsetStart = 0$FileBuffer = [byte[]]::new($uploadChunkSize)do {$FileChunkByteCount = $FileStream.BaseStream.Read($FileBuffer, 0, $FileBuffer.Length)Write-Verbose ($FileStream.BaseStream.Position)$FileOffsetEnd = $FileStream.BaseStream.Position - 1if ($FileChunkByteCount -gt 0) {$UploadRangeHeader = "bytes " + $FileOffsetStart + "-" + $FileOffsetEnd + "/" + $FileSizeWrite-Verbose $UploadRangeHeader$FileOffsetStart = $fileStream.BaseStream.Position$BinaryContent = New-Object System.Net.Http.ByteArrayContent -ArgumentList @($FileBuffer, 0, $FileChunkByteCount)$FileBuffer = [byte[]]::new($uploadChunkSize)$Headers = @{'AnchorMailbox' = $MsgFrom'Content-Range' = $UploadRangeHeader}$Result = (Invoke-RestMethod -Method Put -Uri $UploadSession.UploadUrl -UserAgent "UploadAgent" -Headers $Headers -Body $BinaryContent.ReadAsByteArrayAsync().Result -ContentType "application/octet-stream")Write-Verbose $Result}} while ($FileChunkByteCount -ne 0)# Send the messageTry {Send-MgUserMessage -UserId $MsgFrom -MessageId $NewMessage.Id -ErrorAction StopWrite-Host "Message sent to $RecipientAddress"}Catch {Write-Host "Error sending message: $_"}
Attribution
Author
Office365itpros