Monday, December 16, 2019

Copying files between Microsoft Teams using Microsoft Graph

In  2018 I attended a session held by Luis Manez about Microsoft Graph. The session's title  was: Domina la Graph API, domina el mundo. Translating it to English means "Take over the world by dominating the Graph API". The session's title is a little bit ambitious, but there is some truth in that. Luis did not show us how to take over the world, but he did explain Microsoft Graph to us really well and the advantages you have using it. Since then, I have started implementing Graph more and more in my projects. For instance, I created a provision engine completely based on Graph that is capable of entirely provisioning Microsoft Teams. At that time, PnP did not provide support for provisioning Teams. So, thank you Luis for helping me keep the Graph flame burning in my heart 😊 I'm feeling so poetic right now!

In this blog post, I will demonstrate how to copy files between Microsoft Teams using Graph. Maybe you have a file that must be in different Teams. For instance, each Team in your company represents a project which must contain a PDF document called Rules of Communication. In addition, this document must be available as a Team's tab so Team members can easily find it. The picture below shows the process that I'll demonstrate to you in the next steps:


1. Register an Azure app
2. Install the PowerShell module "AzureAD"
3. Metadata required
4. The PowerShell logic
5. Logic's limitation
6. Ideas how you could enhance the script's logic

1. Register an Azure app

 1. Go to
 2. Register an app using your Office 365 account (the account must have permissions to add applications to your Azure AD)
 3. Give the app the proper scope permissions - Groups.ReadWrite.All (delegated permission). Don't forget to consent the permission
 4. Configure Desktop + Devices as the platform
 5. Set an arbitrary Redirect URI (e.g. https://localhost/)
 6. Note your Redirect URI and Application ID since these values will be used in the PowerShell logic

2. Install the PowerShell module "AzureAD"

Install AzureAD module if you haven't done it yet in your environment, since you will need it for authentication against Graph. Here is how the command to install looks:

Install-Module -Name AzureAD

3. Metadata required

- ClientID: The application ID assigned by the Azure app registration portal
- ID of the source team
- ID of the target team
- Filename (including extension): File to copy from source team to target team

4. The PowerShell logic

The script below copies a file from a source team to a target team. In detail, it copies a file from the General source's channel to the General target's channel. After the file has been successfully uploaded, it will be added as a Team's tab! For better understanding, I added comments to the logic. In addition, I made notes of important aspects that you must keep in mind when developing such a solution. Instead of using the new Microsoft Graph PowerShell (MS Graph PS) module or the existing Microsoft Teams PowerShell (MS Teams PS) module, I'm directly using REST to communicate with Graph. The new Microsoft Graph PowerShell is still in beta, but looks very powerful. I will give it a try it in further implementations. The existing MS Teams PS module is very limited. I assume, it will be replaced with the new MS Graph PS module. Here is how the script looks:

- entityId must be uppercase. The entityId is the sourceDoc ID of the file
- you find the entityId in the @microsoft.graph.downloadUrl property
- contentUrl must be a decoded URL, otherwise file's content won't display in Team's tab

The code below shows how to request this PowerShell logic:

-ClientId '1002ec18-ab42-4369-9e4d-f4221e7fdb40' 
-SourceTeamId '5a5cc296-ebcd-4fac-b3c6-619f8bfa7363' 
-TargetTeamId '7b2d81da-0010-45c6-bbfb-bbadccb06e75' 
-Filename 'Rules of Communication.pdf'

5. Logic's limitations

- Graph Search API works with delay. The specified file must be first indexed before the API can find it. This process can take a few minutes. For instance, if you have just uploaded a file to Teams, it takes a few minutes until the Search API can find it
- Target Teams must exist. This logic won't create the team if it doesn't exist
- Target Channel must exist. This logic won't create the channel within the team if it doesn't exist
- Copying file into folder is not supported
- The file to copy is a PDF document
- Source and target channel are General

6. Ideas how you could enhance the script's logic:

- Find teams by mailNickname instead of working with teams' ID
- Create the target team if it doesn't exist
- Create the target channel within the target team if it doesn't exist
- Define the document's teamAppId depending of the file extension. This current script uses the one for PDF
- Replace the search API with a reliable solution

Did you implement some of these ideas? Then share it with the community :)


The Microsoft Graph API provides extensive support for working with documents and teams. Take advantage of Graph in combination with PowerShell using it to simplify and automate recurring tasks!

No comments:

Post a Comment