Planner Migration Tenant to Tenant

Recently I was involved in an Office 365 Tenant to Tenant migration. The project dates were very tight and a lot of decisions have been made already. My original task was to migrate teams data to a new tenant. Despite our better knowledge, we had to use BitTitan to migrate Teams. As feared the process and the results didn’t fulfill the expectations of the admins and the users. We tried our best to mitigate the limitations of the migration tool by doing some pre- and post-processing, like setting the Teams and related resources to read-only, separate the document migration from BitTitan migration, adjust the user mapping, reapply Teams settings assisted by scripts etc…

One of the requests which came up while we started the Teams migration was to migrate existing Planner from the source Tenant to the destination Tenant. The migration tools we used for Teams and SharePoint Migration didn’t allow the migration of this O365 Group Feature.

To be honest, I’m not a big fan of tools for tasks we can also solve with onboard resources or well-known methods. After a short research I found Alexander Holmeset’s great blog article ( how to migrate plans from one tenant to another which nearly fulfilled our requirements for the migration. Because we didn’t want to migrate all plans and had some issues with umlauts, we made to some adjustments and fixes to get the script running smoothly.

What I’ve adjusted in short:

  • added handling for umlauts
  • fixed errors in the task creation related to the date format
  • added parameters to make the script more universal
  • changed the authentication process to get away from the device login
  • changed the scope from all groups in the source Tenant to explicit groups
  • adjusted the user-mapping settings
  • added some error handling for user assignment errors
  • added a synopsis to the script to make it better usable for migrations

Feel free to download the script and use it to migrate plans from one Tenant to another. There are a few prerequisites to be done which are described in the script-based help.

When the preparations are done you can use the script to migrate one or all plans from one O365 Group of the source Tenant to a O365 Group in the destination tenant as follows:

.\migrate-planner_doc.ps1 -SourceGroupID 927e47e7-09f4-4b38-8aac-80f68d121801 -DestinationGroupID dba6eaa0-e714-4f81-8cb8-8295611a3cfa -sourceDomain "" -destinationDomain ""

Make use of the parameter „singleplanid“ if you only want to migrate a single plan from a O365 Group.
Make use of the parameter „usercheck“ to be able to interact when a task assignment can’t find a related assignee.

Here you can find my „Interpretation“ of Alexanders great planner migrations script:

15 Kommentare zu „Planner Migration Tenant to Tenant

  1. Hello ! We are in the process of doing a Tenant to Tenant migration also. We read in your blog post that you had issue with BitTitan… What was the big issues ? we have a big limitation on our side since we migrate to a GCC high tenant. There’s not much tools who have all the capabilities of migrating to GCC high and that’s why we go with BitTitan.

    Thanks in advance !

    1. Hi Yvan,
      the results of the migration doesn´t satisfies the user expectation and the migration itself is hard to handle as an admin.
      E.g. is the migration of private Channels. If the migaccount has permissions for the private channel, the channel is migrated, but not private anymore. This could lead to data protection issues. So you might want to exclude private channels. You can do this only via regex filtering (for every single folder – so you have to find out the names before) which is not really handy. The license consumption is also sometimes very confusing, but here the support was very helpful and adjusted/reseted the licenses again (and again, and again).
      We decided to exclude the SPO Migration of Files from bittitan, because bittitan doesn´t handle file versions etc., and in big migrations it also not handles the throttling issues well.
      The result of the conversation history was also really bad. Some inline images were migrated, some not. We didn´t figured out why, and how to solve it. Also the support could not help us there.
      Bittitan is also not migrating the teams settings, which are very easy to handle via api, neither it can handle the best practices like set the source teams to „Read-only“ before.
      We had a lot of work with pre- and postmigration stuff because bittitan could not handle it. We used bittitan only the move the conversations. Meanwhile the Graph API has some restricted commands to migrate the conversations also. I´m sure that with some scripting experience you can get a similar or better result by scripting it yourself, than using that migration tool.

    1. Hi Ryan,
      thank you for your feedback. I just voted for the uservoice.
      Till now I was not aware of this limitation. I will reproduce it and check if we could use a filter or something similar as a workaround.

  2. Hello I have been having some problems with the screen with the fact that it cannot properly see the tasks with the error Schema Validation has failed. Validation for field ‚PlanId‘ on entity task has failed. unfortunately im not very versed with powershell so any advice on what to look would be helpfull.

    1. Hi Aleksandar,
      to use this script for planner migrations you will need some PS background. It’s not the simplest way to get warm with PS and a lot of components are in the game.
      You only need the ’singlePlanID‘ if you want to migrate a single plan only. If you want to migrate all plans in a group, you don’t have to specify it.
      If you need more help, please contact me via Teams Chat or mail (jakob.schaefer AT

  3. To get more than 400 tasks use the XML runtimeConfiguration statement in the GraphAPI GET statement to turn on Pagination and set the minimumItemCount to a number greater than your maximum number of tasks.

    „runtimeConfiguration“: {
    „paginationPolicy“: {
    „minimumItemCount“: 800

    Also there are now 25 categories so lines 274 to 309 will need to be expanded to cover all 25 category cases.

  4. Great script, when testing one issue I am having is that the user’s are not matching in the destination domain, even through parameters are set. Usercheck switch allows me to manually enter the same UPN replacing with new domain suffix and it works ok. Any reason why the matching is not taking place?

    sourcedomain =
    destindationdomain =

    Is it anything to do with the domain?

    1. The script uses Powershell’s String.Replace function, which is case-sensitive. So make sure your domain values are written exactly as they are in your Admin Center.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.