Overview of Microsoft Planner

A Microsoft Planner is represented by a group of tasks that are assigned to different team members. Each task represents a piece of work or other activity that must be completed by a certain date and time.
More information can be read here.

Microsoft Planner data are distributed across several places in Office 365.
• The Microsoft Planner metadata is held in an Azure-based service
• Comments for tasks within a plan are stored in the Exchange Online mailbox for the Office 365 Group associated with the plan.
• Documents and other attachments are held in the SharePoint Online document library belonging to the Office 365 Group.

Every plan in Planner is associated with an Office 365 Group. When you create a plan, you will create new Office 365 Groups with Office 365 mailbox

How to migrate Microsoft Planner data from one tenant to another Office 365 tenant?

Microsoft does not provide any migration path for Microsoft Planner from tenant to new tenant, Here is how migration should look like.
You will need to migrate:

  1. Office 365 Group migrate Conversations
    You can use MigrationWiz to migrate Conversations
  2. SharePoint Online document library belonging to Group.
    You can use MigrationWiz to migrate Office 365 Documents
  3. Planner Data
    You can use Apps4. Pro Planner Manager to migrate Planner metadata from Azure.
    We are going to show you how to migrate Microsoft Planner data using Apps4  Pro Planner Manager.

The following paragraph outlines steps for Microsoft Planner metadata migration.


Purchase two licences for Apps4.Pro Planner Manager from the following site.
You will need one licence for the source tenant and one licence for the target tenant.

Source Tenant

Grant access to all Office 365 groups and planner data.

  1. Login to source tenant.
    Export all Office 365 Groups properties to file using the PS1 file from Appendix A
  2. We will add an admin account (admin@source.onmicrosoft.com ) to the member in each Office 365 Group.
  3. Paste the following command in empty column BT in c:\reports\Office365Groups-Export.csv
    copy/paste command to the bottom of the document.
    =CONCATENATE(“Add-UnifiedGroupLinks -ID “””,A2,””” -LinkType Member -Links admin@source.onmicrosoft.com “)Save file to local drive.
  4. Login to the Source tenant’s PowerShell and paste and execute PowerShell lines (Add-UnifiedGroupLinks ) from BT Column.
  5. Now admin@source.onmicrosoft.com has access to all Planner data on the old tenant.
    If you log in to the admin@source.onmicrosoft.com account, you will see all Office 365 groups and all Planner Data attached to their portal in Office 365.

Export Microsoft Planner Data on source tenant.

We will export planner data to an Excel file using Apps4.Pro Planner Manager

Run apps4.pro manager and login to the old source tenant using admin@source.onmicrosoft.com account.

Go to Settings and select Manage Plans.

Add all available plans to right

Go to the Home Tab and select All Tasks – SYNC .

Go to Home Tab and select Export to Excel. Export Data to My Task.xmls file.

Target Tenant

Import Data target tenant.

If you already provisioned Office 365 Group for Planner, you will need to add an admin account to each group, log into the planner and click each plan to create plans.

Otherwise, you will get the following message when you start importing tasks.

Failed to create a Group for this plan, One or more errors occurred. Code: Request_BadRequest
Message: Another object with the same value for the property mailNickname already exists.
Inner error

Apps4.Pro cannot see the plan and it will try to create a new Office 365 Group. The creation of a group will fail because there is already Office 365 with the same name presented in Office 365.

Follow these steps to create plans for already created Office 365Groups.

Go to Planner Portal (https://tasks.office.com) -> Planner hub -> All plans.
Search, click and open the group entry (already created group), it will create a new plan with the same name.

If you do not have Office 365 Groups provision, there is an option in APPS4.Pro Planner manager to provision Office 365 groups and Plans for you.
This will not add any other members of Office 365 groups who are not included in plans.
Options are presented when you in little gear icon before you start importing the task.

Import Tasks in Target Tenant.

Lunch Apps4.Pro Planner Manager.

Login to the target tenant using admin@target.onmicrosoft.com account.

Go to the Plan Tab and select All Plans SYNC to sync all plans to an application.

Go to the Home Tab and select Import Tasks and select My Plan.xlsx file created in previous steps.

After a file is imported, click the little gear icon and change the import options to match the selected options in this picture.

Save import settings and press OK button to start importing data from excel spreadsheet.

The next Page will show you the results of the import.

At this moment apps4.pro manager created all Office 365 groups,  added members and imported Planner Data.

The account that you used to import data to the target tenant is the owner of all Office 365 groups. You can change that if you wish.

We find out that attachment and links in tasks are not copied to a new tenant.

The Old Tenant is on the top and and new on the bottom picture.

Appendix A: Powershell Script to export Office 365 data from old tenant.

$UnifiedGroups = Get-UnifiedGroup -ResultSize Unlimited
$Count = $UnifiedGroups.Count
$i = 1
Foreach ($Group in $UnifiedGroups)
Write-Host “$($Group.Name) [$i of $Count]”
$Sub = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Subscribers
$Mem = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Members
$Own = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Owners
$Agg = Get-UnifiedGroupLinks -Identity $Group.Identity -LinkType Aggregators

# Resolve GrantSendOnBehalfTo
$GrantSendOnBehalfTo = @()
foreach ($addr in $Group.GrantSendOnBehalfTo) { $GrantSendOnBehalfTo += (Get-Recipient $addr).PrimarySmtpAddress }

#Resolve ManagedBy
$ManagedBy = @()
foreach ($addr in $Group.ManagedBy) { $ManagedBy += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve ManagedByDetails
$ManagedByDetails = @()
foreach ($addr in $Group.ManagedByDetails) { $ManagedByDetails += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve Members
$Members = @()
foreach ($addr in $Mem) { $Members += $addr.PrimarySmtpAddress }

# Resolve Subscribers
$Subscribers = @()
foreach ($addr in $Sub) { $Subscribers += $addr.PrimarySmtpAddress }

# Resolve Aggregators
$Aggregators = @()
foreach ($addr in $Agg) { $Aggregators += $addr.PrimarySmtpAddress }

# Resolve Owners
$Owners = @()
foreach ($addr in $Own) { $Owners += $addr.PrimarySmtpAddress }

# Resolve ModeratedBy
$ModeratedBy = @()
foreach ($addr in $Group.ModeratedBy) { $ModeratedBy += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve RejectMessagesFrom
$RejectMessagesFrom = @()
foreach ($addr in $Group.RejectMessagesFrom) { $RejectMessagesFrom += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve RejectMessagesFromSendersOrMembers
$RejectMessagesFromSendersOrMembers = @()
foreach ($addr in $Group.RejectMessagesFromSendersOrMembers) { $RejectMessagesFromSendersOrMembers += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve RejectMessagesFromDLMembers
$RejectMessagesFromDLMembers = @()
foreach ($addr in $Group.RejectMessagesFromDLMembers) { $RejectMessagesFromDLMembers += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve AcceptMessagesOnlyFrom
$AcceptMessagesOnlyFrom = @()
foreach ($addr in $Group.AcceptMessagesOnlyFrom) { $AcceptMessagesOnlyFrom += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve AcceptMessagesOnlyFromDLMembers
$AcceptMessagesOnlyFromDLMembers = @()
foreach ($addr in $Group.AcceptMessagesOnlyFromDLMembers) { $AcceptMessagesOnlyFromDLMembers += (Get-Recipient $addr).PrimarySmtpAddress }

# Resolve AcceptMessagesOnlyFromSendersOrMembers
$AcceptMessagesOnlyFromSendersOrMembers = @()
foreach ($addr in $Group.AcceptMessagesOnlyFromSendersOrMembers) { $AcceptMessagesOnlyFromSendersOrMembers += (Get-Recipient $addr).PrimarySmtpAddress }

$Group | Add-Member -TypeName NoteProperty -NotePropertyName Subscribers -NotePropertyValue ($Subscribers -join “,”) -Force
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Members -NotePropertyValue ($Members -join “,”) -Force
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Owners -NotePropertyValue ($Owners -join “,”) -Force
$Group | Add-Member -TypeName NoteProperty -NotePropertyName Aggregators -NotePropertyValue ($Aggregators -join “,”) -Force
$Group | Select Alias, Name, DisplayName, AccessType, @{
N = “AcceptMessagesOnlyFrom”; E = { $AcceptMessagesOnlyFrom -join “,” }
}, @{
N = “AcceptMessagesOnlyFromDLMembers”; E = { $AcceptMessagesOnlyFromDLMembers -join “,” }
}, @{ N = “AcceptMessagesOnlyFromSendersOrMembers”; E = { $AcceptMessagesOnlyFromSendersOrMembers -join “,” } }, AllowAddGuests, AlwaysSubscribeMembersToCalendarEvents, AutoSubscribeNewMembers, BypassModerationFromSendersOrMembers, CalendarMemberReadOnly, CalendarUrl, Classification, ConnectorsEnabled, CustomAttribute1, CustomAttribute2, CustomAttribute3, CustomAttribute4, CustomAttribute5, CustomAttribute6, CustomAttribute7, CustomAttribute8, CustomAttribute9, CustomAttribute10, CustomAttribute11, CustomAttribute12, CustomAttribute13, CustomAttribute14, CustomAttribute15, @{ N = “EmailAddresses”; E = { $_.EmailAddresses -join “,” } }, EmailAddressPolicyEnabled, ExtenstionCustomAttribute1, ExtenstionCustomAttribute2, ExtenstionCustomAttribute3, ExtenstionCustomAttribute4, ExtenstionCustomAttribute5, FileNotificationsSettings, @{ N = “GrantSendOnBehalfTo”; E = { $GrantSendOnBehalfTo -join “,” } }, HiddenFromAddressListsEnabled, HiddenGroupMembershipEnabled, InboxUrl, MailboxProvisioningConstraint, @{ N = “ManagedBy”; E = { $ManagedBy -join “,” } }, @{
N = “ManagedByDetails”; E = { $ManagedByDetails -join “,” }
}, @{
N = “Members”; E= { $Members -join “,” }
}, @{
N = “Owners”; E= { $Owners -join “,” }
}, @{
N = “Subscribers”; E = { $Subscribers -join “,” }
}, @{
N = “Aggregators”; E= { $Aggregators -join “,” }
},MaxReceiveSize, MaxSendSize, @{ N = “ModeratedBy”; E = { $ModeratedBy -join “,” } }, ModerationEnabled, Notes, PeopleUrl, PhotoUrl, PrimarySmtpAddress, ProvisioningOption, @{ N = “RejectMessagesFrom”; E = { $RejectMessagesFrom -join “,” } }, @{ N = “RejectMessagesFromDLMembers”; E = { $RejectMessagesFromDLMembers -join “,” } }, @{ N = “RejectMessagesFromSendersOrMembers”; E = { $RejectMessagesFromSendersOrMembers -join “,” } }, ReportToManagerEnabled, RequireSenderAuthenticationEnabled, SendModerationNotifications, SendOofMessageToOriginatorEnabled, SharePointDocumentsUrl, SharePointNotebookUrl, SharePointSiteUrl, SubscriptionEnabled, WelcomeMessageEnabled, YammerEmailAddress | Export-Csv -Append $File -NoTypeInformation
$Group = $null
} #End Foreach ($Group in UnifiedGroups)


By Dan Djurasovic

Dan is an Azure Technical Advisor, with over a dozen years of IT experience, specializing in Microsoft Office 365, Exchange Server Azure IaaS and Active Directory..

2 thought on “How to migrate Microsoft Planner data from one tenant to another Office 365 tenant.”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.