1

How can I download the attachment from the Microsoft Graph API for Mail message?

'$attachment=Get-MgUserMessageAttachment -MessageId AAMkAGIzZWEyN2MxLWJmNTktNDBkMi05ZWY2LWE3YjFhYWJjNmEwOABGAAAAAAA2OVriHzx8TL2ku-KbIgYgBwChRsRs-pG2QpRCaG5OA-T0FcAAA= -UserId abcd@gmail.com

$attachment
ContentType          : application/octet-stream
Id                   : AAMkAGIzZWEyN2MxLWJmNTktNDBkMi05ZWY2LWE3YjFhYWJjNmEwOABGAAAAAAA2OVriHzx8TL2ku-KbIgYgBwChRsRs-pG2QpRCaG5OgRLxAAAAAAEMAAChRsRs-pG2QpRCaG5OgRLxAAA-T0FcAAABEg
                       AQANUHCnnWvO5Dr-D2VilhKP8=
IsInline             : False
LastModifiedDateTime : 4/14/2020 7:21:32 PM
Name                 : report.csv
Size                 : 707'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dss.pisces
  • 15
  • 1
  • 7

2 Answers2

2

The Microsoft graph API is based on Web API. So if you want to download an attachment you can use the HTTP GET command directly with the Microsoft Graph API Get Attachment API.

In PowerShell, if you want to use an HTTP call natively, you can use Invoke-WebRequest (for more details you can see How can I use HTTP GET in PowerShell?).

But Microsoft provides some facilities (modules) for making Microsoft Graph API easy to use in PowerShell. That say Microsoft.Graph Module. This module is in the preview stage, but it is very useful.

If you want to use this module and download an attachment, you can use the below command:

Get-MgUserMessageAttachment -MessageId <String> -UserId <String> [-Count] [-Expand <String[]>]
 [-Filter <String>] [-Orderby <String[]>] [-Search <String>] [-Select <String[]>] [-Skip <Int32>]
 [-Top <Int32>] [<CommonParameters>]

For more information about this command, you can see the Microsoft Graph SDK PowerShell documentation.

Get-MgUserMessageAttachment returns IMicrosoftGraphAttachment that has some properties like below (JSON representation):

{
  "contentType": "string",
  "id": "string (identifier)",
  "isInline": true,
  "lastModifiedDateTime": "String (timestamp)",
  "name": "string",
  "size": 1024
}

But this type is based type of fileAttachment that has some properties like below (JSON representation):

{
  "contentBytes": "string (binary)",
  "contentId": "string",
  "contentLocation": "string",
  "contentType": "string",
  "id": "string (identifier)",
  "isInline": true,
  "lastModifiedDateTime": "String (timestamp)",
  "name": "string",
  "size": 1024
}

For file download, you can use the ContentBytes property. This property is Base64 encoded so you have to decode it and then save to a file with some of commands like Out-File.

As you can see in the GitHub repository of PowerShell Module, in the current state of this PowerShell you cannot use it directly with this SDK to download an attachment, and you have to use Web API directly in PowerShell for downloading the attachment.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sorosh_sabz
  • 2,356
  • 2
  • 32
  • 53
  • Yes, Im using the graph SDK powershell module, not sure how to download the attachment from graph module here there is no content attribute for saveasfile or export from Get-MgUserMessageAttachment – dss.pisces May 14 '20 at 14:39
  • I update my answer as you can see in https://github.com/microsoftgraph/msgraph-sdk-powershell/issues/228#issuecomment-634295436 you cannot do it – sorosh_sabz May 28 '20 at 17:46
0

This works ("Log" basically just calls write-verbose):

# Install Microsoft Graph API PowerShell module if not already installed
if (Get-Module 'Microsoft.Graph' -ListAvailable) {
    Log 'PowerShell Module Microsoft.Graph is already installed.'
} else {
    Log 'PowerShell Module Microsoft.Graph not installed. Installing...'
    try {
        Install-Module 'Microsoft.Graph' -Force
        Log 'Installed successfully.'
    }
    catch {
        throw 'Error: unable to install PowerShell Module Microsoft.Graph Module.'
    }
}

$UserId     = ''
$FolderId   = ''
$Filename   = "$( $env:USERPROFILE )\Downloads\test.pdf"
$TId        = ''
$AppId      = ''
$CertThumb  = ''

# Connect to Microsoft Graph API
$null = Connect-MgGraph -TenantId $TId -AppId $AppId -CertificateThumbprint $CertThumb
# Using null suppresses the output

# Get Message from Folder in User
$Msgs = Get-MgUserMailFolderMessage -UserId $UserId -MailFolderId $FolderId
$MsgId = $Msgs[0].Id

# Get Attachment
$Attachm = Get-MgUserMailFolderMessageAttachment -UserId $UserId -MailFolderId $FolderId -MessageId $MsgId

# Get Attachment as Base64
$Base64B = ($Attachm).AdditionalProperties.contentBytes
# Works also: Get-MgUserMessageAttachment

# Save Base64 to file
$Bytes = [Convert]::FromBase64String($Base64B)
[IO.File]::WriteAllBytes($Filename, $Bytes)

Disconnect-MgGraph
Michael
  • 3
  • 1