in Azure, Flow

How to delete a Planner task with Power Automate using a custom connector

If you're not new to Planner connector in Power Platform, you know that the connector is not exposing the Delete Task action.

To overcome this issue, you can create your own action and delete Planner tasks.

You may want to delete tasks when you run out of task quota and you get this error message:

{
"error": {
"code": "MaximumTasksCreatedByUser",
"message": "The request exceeded allowed limits.",
"innerError": {
"date": "2020-08-11T06:10:24",
"request-id": "bf50acd7-d2b7-47ee-a2b1-8965b57cf9a4"
}
}
}

This article explains how to create a custom connector that uses an AAD service principal (app registration) to delete tasks in Planner.

Create an app registration in AAD

First create a new app registration in Azure portal by going here: https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationsListBlade

On the App Registrations page click on New registration

Give the app a name, select Accounts in this organizational directory only (SuperTeam only – Single tenant), leave the Redirect URI empty, and click Register

On the app page, click on Authentication, Add a platform, and click on the Web tile

On the Web configuration flyout set the Redirect URIs field to https://global.consent.azure-apim.net/redirect, leave the Logout URL empty, leave the Access tokens and ID Tokens unchecked, and click Configure

Next go to API permissions, click on Add a permission, click on the Microsoft APIs tab, and then click on the Microsoft Graph tile

On the Microsoft Graph flyout click on the Delegated permissions tile, search for Group.ReadWrite.All, and select the Group.ReadWrite.All permission, and click Add permissions

On the same page, click on Grant admin consent and confirm

Observe the status change of the delegated permission

Note: we've added the Delegated permission because Planner doesn't support Application permissions. So we can't automate requests in Planner without impersonating a user (delegated), therefore the requests sent to the https://graph.microsoft.com/v1.0/planner/ resource must be delegated by an authenticated user. More details here.

Next create a client secret by going to Certificates & secrets, click on New client secret, give it a name, choose when you want to expire (Never would be best if you want low maintenance), and finish by clicking Add

Observe the secret and copy it and put it in a text file because you will need it later to configure your connector.

Note: the secrets exposed on my blog are already disposed

Next go to Overview and copy the Application ID and the Directory ID and store them in the same file because you will need these as well to configure the connector.

Create a custom connector

Go to Power Automate and create a custom connector from blank

On the General tab set the host to graph.microsoft.com

On the Security tab set the Authentication type to Oauth 2.0

On the same Security tab, configure the OAuth 2.0 authentication as follows:

  • Select Azure Active Directory in the Identity Provider dropdown
  • Paste the Application ID in the Client id field
  • Paste the Client Secret in the Client secret field
  • Paste the Directory ID in the Tenant ID field
  • Set the Resource URL field to https://graph.microsoft.com
  • Leave the rest of the fields as they are

After you're done with the OAuth 2.0 settings, click on Create connector

Once the connector is saved, observe the automatically generated Redirect URL on the bottom of the configuration settings. It must match the Redirect URL you have used in the app when you've added the Web platform. If the URLs don't match, copy the URL from the connector and paste it in the App's Web platform Redirect URL field (4th screenshot). The URL I'm observing while doing this tutorial is https://global.consent.azure-apim.net/redirect and it matches the one I configured in the app, so I don't have to change anything.

Next go to Definition tab, Add an action with the name Delete Task, set the Verb to DELETE, set the URL to https://graph.microsoft.com/v1.0/planner/tasks/{id}, set the Headers to If-Match, and click Import

Note: we've added the If-Match header because this action requires a matching ETag before being able to delete the task. The ETag is used to identify the latest version of the task object in Graph.

Next, update the connector

Test your action

If you did everything right, you can proceed directly to create a flow. You can test it by adding a button trigger and the Delete Task custom action.

Before you can add the action, you must first sign in. The action will then ask for the task id and the If-Match ETag

One way to get these, is to use the List tasks action from the Planner standard connector

Run the List Tasks and look in the output of the action and copy the ETag and the id. My ETag is JzEtVGFzayAgQEBAQEBAQEBAQEBAQEBARCc= and the id is n2958ulAPUmeaTcDq71irGUAF-2P

{
    "@odata.etag": "W/\"JzEtVGFzayAgQEBAQEBAQEBAQEBAQEBARCc=\"",
    "planId": "XkaLULAtb0SKMKjTA4Dxn2UADWj0",
    "bucketId": "RTZV7eMxjkKHH7f8GHitN2UACjMN",
    "title": "Another one",
    "orderHint": "8586048559571801294PN",
    "assigneePriority": "",
    "percentComplete": 0,
    "startDateTime": null,
    "createdDateTime": "2020-08-06T21:56:28.3755844Z",
    "dueDateTime": null,
    "hasDescription": false,
    "previewType": "automatic",
    "completedDateTime": null,
    "completedBy": null,
    "referenceCount": 0,
    "checklistItemCount": 0,
    "activeChecklistItemCount": 0,
    "conversationThreadId": null,
    "id": "n2958ulAPUmeaTcDq71irGUAF-2P",
    "createdBy": {
      "user": {
        "displayName": null,
        "id": "3a5c33ab-949c-445b-8032-efe18d02a234"
      }
    },
    "appliedCategories": {},
    "assignments": {},
    "_assignments": []
  },

Configure the Delete Task with the id and the ETag you have copied, but make sure you put the ETag between double quotes "

If you did everything right, the Delete Task action should work

If you're wondering how to delete all tasks that were completed, then please note that I have another article coming up in a few days explaining the whole process.

Write a Comment

Comment

  1. Alex, thank you so much for this write up. I was able to get this to work only by using an account with the custom connector that had Global Admin. What is the least privileged role for the delegated user that can be used for Delete?

    • I've not tested this, but you have to be a plan owner. In a situation where the plan/task was created by someone else and you don't own the plan, you won't be able to delete the task(s). Did you find different?