Script to save email attachments


I have a client that has faxes sent to a shared mailbox What I am trying to accomplish is having those fax attachments automatically saved to a shared network location when they come in. For example \server\faxes

I’ve been searching and have not come up with a solution. Any help would be appreciated.

Thank you!

Hi, welcome to the forum :wave:

What have you tried so far? Do you have any code to share? Where’s the mailbox?

It’s hard to offer advice when we don’t know what you’re working with.

1 Like

No clue what your setup is like, hard to what exactly you’re trying to do. Could you run a powershell script on a client system on a scheduled task and have that be accessible?

maybe a place to start: Saving Outlook attachments with PowerShell - Mikey Bronowski - Blog talks about saving attachments using mapi

I am not going to write out the full solution but I think I can get you on the right track. I will be assuming your organization is using exchange online and will therefore be using the Microsoft Graph Powershell SKD for this.

As this sounds like it will be an automated process you can use an App Registration with a client secret to generate a Graph access token and authenticate with graph using Connect-MgGraph commandlet


#Declare Microsoft Graph authentication information
$myTenantId = "********-****-****-****-************"
$clientID = "********-****-****-****-************"
$clientSecret = "********-****-****-****-************" | ConvertTo-SecureString -AsPlainText -Force

#Get Access token
$myToken = Get-MsalToken -clientID $clientID -clientSecret $clientSecret -tenantID $myTenantId
$AccessToken = $MyToken.AccessToken | ConvertTo-SecureString -AsPlainText -Force

#Connect to MGGraph
Connect-MgGraph -AccessToken $AccessToken >> $Null

Be aware that you will not want to keep the client secret in the final version of the script. It should be placed in a file as a secure string by the service account you will use to run the process

Once you are connected into Graph you can get the Inbox folder ID. For this example I am using as the Shared Mailbox. Just replace it with your mailbox.


Get-MGUserMailFolder -UserID | Select DisplayName, ID

DisplayName          Id                                                                                                                      
-----------          --                                                                                                                      
Archive              AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************
Conversation History AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************
Deleted Items        AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************
Drafts               AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1j*****************************************************************************************************************************
Inbox                AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************
Junk Email           AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************
Outbox               AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************
Sent Items           AQMkAGNhZWQyMWRkAC00YjdkLTQwMmUtYWQ0Yy1*****************************************************************************************************************************

You should now be able to get the inbox ID and place it in a variable.

So now you will want to get all the messages out of that mailbox. we will use the Get-MGUserMailFolderMessage command.

$Messages = Get-MGUserMailFolderMessage -UserID -MailFolderId $InboxID

If you want to see what that object lookes like just put it into a Select *.

Now that we have our messages we will want to get the attachments for them. This will use the Get-MGUserMessageAttachment commandlet.

$Attachment = Get-MgUserMessageAttachment -UserID -MessageId $Messages.ID

Be aware that this will give you all attachments to the message including any imbedded image files. You can filter this list as you like to find the specific file or just download all of them.

To download the file we will be pulling the Base64 bytes. The filename will be the final path of the attachment.

$Base64 = $Attachment.AdditionalProperties.contentBytes
$Filename = "C:\utils\" + $
$Bytes = [Convert]::FromBase64String($Base64)
[IO.File]::WriteAllBytes($Filename, $Bytes)

Hope that helped a bit.

You don’t really need to generate your own access token. If creating an azure app, may as well setup certificate-based authentication and just connect to graph directly using it.

Using Certificate-based Authentication with the Microsoft Graph PowerShell SDK | Practical365 this guide is probably good enough, though the general concept is just 1) create a self-signed cert 2) install that cert with he private key on a system, 3) upload the cert without the private key (.cer) to the app registration and then 4) connect using the cert using Connect-MGgraph using the TenantID, AppID, and Certificate thumbprint.

1 Like