Continuing on Graph API series: this time I show how to create a Planner board, add a bucket and task into it and attach it to a team as template.
The setup
- I am showing these snippets as example, they are not a full solutions
- I use PowerShell and Graph Explorer to post commands in
- Experiment, learn and use the knowledge to create your own solutions
Create a Planner and a bucket
Using Docs.Microsoft.Com examples it is actually quite easy to create a Planner and buckets into it. They key API is /planner/plans. I use variables $teamID and $teamName to create a planner to specific team. Plan title can of course be anything you wish.
# Create a Planner to team
$createPlanUri ="https://graph.microsoft.com/beta/planner/plans"
$createPlanJSON ='{
"owner": "' +$teamID +'",
"title": "' +$teamName +' Planner"
}
'
$graphResponse = Invoke-RestMethod -Method Post -Uri $createPlanUri -Headers @{"Authorization"="Bearer $delegatedaccessToken"} -Body $createPlanJSON -ContentType "application/json"
$planID = $graphResponse.id
Write-Host "Planner Plan ID: " $planID
After creation of a planner, we can add objects into it. Like a bucket.
## add some planner buckets & tasks
##
$bucketJSON ='
{
"name": "Backlog bucket",
"planId": "' +$planID + '",
"orderHint": " !"
}
'
$bucketURI = "https://graph.microsoft.com/beta/planner/buckets"
$graphResponse = Invoke-RestMethod -Method Post -Uri $BucketUri -Headers @{"Authorization"="Bearer $delegatedaccessToken"} -Body $BucketJSON -ContentType "application/json"
$backlockBucketID = $graphResponse.id
Adding tasks
When you know the plan and bucket IDs, it is easy to write tasks to them. Looking at the Docs reference you can go though orderHint (well, ordering). However – note that there is a priority property – you can set the task automatically important or urgent when you create a task! You can also assigns categories.
## Add a Task
$taskJSON ='
{
"title": "Sample task",
"planId": "' +$planID + '",
"bucketId" : "' + $backlockBucketID + '",
"orderHint": " !",
"priority" : 2,
"appliedCategories": {
"category1": true
}
}'
$taskURI = "https://graph.microsoft.com/beta/planner/tasks"
$graphResponse = Invoke-RestMethod -Method Post -Uri $TaskUri -Headers @{"Authorization"="Bearer $delegatedaccessToken"} -Body $TaskJSON -ContentType "application/json"
$taskID = $graphResponse.id
Adding a planner as a tab
Using Graph API it is easy to provision a template Planner (perhaps reading buckets and tasks from another template Team / Planner! – just note the ordering so you won’t create them in reverse).
Provisioning a template planner to a fresh team (or just adding a Planner to existing team) helps with specific team templates: project setup, sales process, marketing campaing, setting up an event and the list goes on.
How to setup the tab to a team? Read Docs.Microsoft.Com, check the example below or check my GitHub repository https://github.com/veskunopanen/Teams-Graph-API .
When adding a Planner tab you need to first configure the URL that is set to contentURL, removeURL and to websiteURL in a call. When you know a PlanID it is rather straight-forward.
You also need to ID of the team and the channel to which you are adding the tab.
## Add Planner Tab to a team
$generalTabsURI = "https://graph.microsoft.com/beta/teams/" + $teamID + "/channels/" + $ChannelID + "/tabs"
$planURL = 'https://tasks.office.com/'+ $tenantname +'.onmicrosoft.com/Home/PlannerFrame?page=7&planId='+ $planID
$plannerJSON =' {
"name": "'+ $teamname +' Backlog",
"displayName": "'+ $teamname +' Backlog",
"teamsAppId" : "com.microsoft.teamspace.tab.planner",
"configuration": {
"entityId": "'+ $planID +'",
"contentUrl": "' + $planURL+ '",
"removeUrl": "' + $planURL+ '",
"websiteUrl": "' + $planURL+ '"
}
}'
#Write-Host $plannerJSON
$graphResponse = Invoke-RestMethod -Method Post -Uri $generalTabsURI -Headers @{"Authorization"="Bearer $delegatedaccessToken"} -Body $plannerJSON -ContentType "application/json"
HI Julkaissut, Thank you for this post it was very helpful. I followed the directions mentioned by you and was able to add planner as a tab. However, the planner is totally empty. I do not see the buttons for adding a task etc. Is there anything else that needs to be done? Thank you in advance.
LikeLike
Interesting. Did you add buckets there first? Tasks are added to buckets. It shouldn’t be totally empty if you have created that Plan and followed all steps. Check also permissions.
Best,
Vesku
LikeLike
##############################################################################################
# Get Channel ID #
##############################################################################################
$uri = (“https://graph.microsoft.com/v1.0/teams/$TID/channels”)
$channel = (Invoke-RestMethod -Method Get -Uri $uri -Headers $token).Value
$channel
$CID = “19:1bb6d9f3e44e41bc888e57b5dee042b3@thread.tacv2”
$uri = (“https://graph.microsoft.com/beta/planner/plans”)
$createPlanJSON =@”
{
“owner”: “‘ +$TID +'”,
“title”: ” Planner ”
}
“@
$graphResponse = Invoke-RestMethod -Method Post -Uri $uri -Headers $token -Body $createPlanJSON -ContentType “application/json”
$graphResponse
OUTPUT
Invoke-RestMethod : {
“error”: {
“code”: “UnknownError”,
“message”: “\r\n\r\n\r\n\r\n401 – Unauthorized: Access is denied due to invalid
credentials.\r\n\r\n\r\n\r\n\r\n\r\nServer Error\r\n\r\n \r\n 401 – Unauthorized: Access is denied due to invalid
credentials.\r\n You do not have permission to view this directory or page using the credentials that you
supplied.\r\n \r\n\r\n\r\n\r\n”,
“innerError”: {
“date”: “2020-06-26T17:43:19”,
“request-id”: “0249a64f-8ce7-466d-bf2b-bd7f8da04f0f”
}
}
}
At line:1 char:18
+ … hResponse = Invoke-RestMethod -Method Post -Uri $uri -Headers $token …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
P
already given permission below
Microsoft Graph (49)
Channel.Create
Delegated
Create channels
Yes
Granted for 1
Channel.Create
Application
Create channels
Yes
Granted for 1
Channel.Delete.All
Delegated
Delete channels
Yes
Granted for 1
Channel.Delete.All
Application
Delete channels
Yes
Granted for 1
Channel.ReadBasic.All
Delegated
Read the names and descriptions of channels
–
Granted for 1
Channel.ReadBasic.All
Application
Read the names and descriptions of all channels
Yes
Granted for 1
ChannelMember.Read.All
Application
Read the members of all channels
Yes
Granted for 1
ChannelMember.ReadWrite.All
Application
Add and remove members from all channels
Yes
Granted for 1
ChannelMessage.Read.All
Application
Read all channel messages
Yes
Granted for 1
ChannelMessage.UpdatePolicyViolation.All
Application
Flag channel messages for violating policy
Yes
Granted for 1
ChannelSettings.Read.All
Application
Read the names, descriptions, and settings of all channels
Yes
Granted for 1
ChannelSettings.ReadWrite.All
Application
Read and write the names, descriptions, and settings of all channels
Yes
Granted for 1
Chat.ReadWrite.All
Application
Read and write all chat messages
Yes
Granted for 1
DelegatedPermissionGrant.ReadWrite.All
Delegated
Manage all delegated permission grants
Yes
Granted for 1
DelegatedPermissionGrant.ReadWrite.All
Application
Manage all delegated permission grants
Yes
Granted for 1
Group.Create
Application
Create groups
Yes
Granted for 1
Group.Read.All
Delegated
Read all groups
Yes
Granted for 1
Group.Read.All
Application
Read all groups
Yes
Granted for 1
Group.ReadWrite.All
Delegated
Read and write all groups
Yes
Granted for 1
Group.ReadWrite.All
Application
Read and write all groups
Yes
Granted for 1
GroupMember.Read.All
Delegated
Read group memberships
Yes
Granted for 1
GroupMember.Read.All
Application
Read all group memberships
Yes
Granted for 1
GroupMember.ReadWrite.All
Delegated
Read and write group memberships
Yes
Granted for 1
GroupMember.ReadWrite.All
Application
Read and write all group memberships
Yes
Granted for 1
Team.ReadBasic.All
Application
Get a list of all teams
Yes
Granted for 1
TeamMember.Read.All
Application
Read the members of all teams
Yes
Granted for 1
TeamMember.ReadWrite.All
Application
Add and remove members from all teams
Yes
Granted for 1
TeamsActivity.Read.All
Application
Read all users’ teamwork activity feed
Yes
Granted for 1
TeamsActivity.Send
Application
Send a teamwork activity to any user
Yes
Granted for 1
TeamsApp.Read.All
Application
Read all users’ installed Teams apps
Yes
Granted for 1
TeamsApp.ReadWrite.All
Application
Manage all users’ Teams apps
Yes
Granted for 1
TeamsAppInstallation.ReadForChat.All
Application
Read installed Teams apps for all chats
Yes
Granted for 1
TeamsAppInstallation.ReadForTeam.All
Application
Read installed Teams apps for all teams
Yes
Granted for 1
TeamsAppInstallation.ReadForUser.All
Application
Read installed Teams apps for all users
Yes
Granted for 1
TeamsAppInstallation.ReadWriteForChat.All
Application
Manage Teams apps for all chats
Yes
Granted for 1
TeamsAppInstallation.ReadWriteForTeam.All
Application
Manage Teams apps for all teams
Yes
Granted for 1
TeamsAppInstallation.ReadWriteForUser.All
Application
Manage Teams apps for all users
Yes
Granted for 1
TeamsAppInstallation.ReadWriteSelfForChat.All
Application
Allow the Teams app to manage itself for all chats
Yes
Granted for 1
TeamsAppInstallation.ReadWriteSelfForTeam.All
Application
Allow the Teams app to manage itself for all teams
Yes
Granted for 1
TeamsAppInstallation.ReadWriteSelfForUser.All
Application
Allow the app to manage itself for all users
Yes
Granted for 1
TeamSettings.Read.All
Application
Read all teams’ settings
Yes
Granted for 1
TeamSettings.ReadWrite.All
Application
Read and change all teams’ settings
Yes
Granted for 1
TeamsTab.Create
Application
Create tabs in Microsoft Teams.
Yes
Granted for 1
TeamsTab.Read.All
Application
Read tabs in Microsoft Teams.
Yes
Granted for 1
TeamsTab.ReadWrite.All
Application
Read and write tabs in Microsoft Teams.
Yes
Granted for 1
Teamwork.Migrate.All
Application
Create chat and channel messages with anyone’s identity and with any timestamp
Yes
Granted for 1
User.Read
Delegated
Sign in and read user profile
–
Granted for 1
User.ReadWrite.All
Delegated
Read and write all users’ full profiles
Yes
Granted for 1
User.ReadWrite.All
Application
Read and write all users’ full profiles
Yes
Granted for 1
LikeLike
You have to use a delegated authentication when you create a new plan. Applications can not create new plans.
https://docs.microsoft.com/en-us/graph/api/planner-post-plans?view=graph-rest-1.0&tabs=http
LikeLike
can you tell me how to connect delegated authentication using PowerShell
LikeLike
Unfortunately I have used delegated part only when doing demos.
I used Connect-PnPOnline for that part
https://docs.microsoft.com/en-us/powershell/module/sharepoint-pnp/connect-pnponline?view=sharepoint-ps
However, you should be able to configure your service account authentication to login without needing user action
https://docs.microsoft.com/en-us/graph/auth-v2-user
https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-authenticate-service-principal-powershell
https://docs.microsoft.com/en-us/powershell/azure/create-azure-service-principal-azureps?view=azps-4.3.0
https://docs.microsoft.com/en-us/graph/permissions-reference
You can also assign delegated permissions to application, but I haven’t digged into that yet.
Overall this the Lazy Administrator has a good text about Graph API & PowerShell
https://www.thelazyadministrator.com/2019/07/22/connect-and-navigate-the-microsoft-graph-api-with-powershell/
There seems also to be a way to user a service account username & password, while not recommended
https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
I hope you find a good robust solution. Please share the working one 🙂
LikeLike
Thanks for above links but again same error from different method.
Invoke-RestMethod : {
“error”: {
“code”: “UnknownError”,
“message”: “\r\n\r\n\r\n\r\n401 – Unauthorized: Access is denied due to invalid
credentials.\r\n\r\n\r\n\r\n\r\n\r\nServer Error\r\n\r\n \r\n 401 – Unauthorized: Access is denied due to invalid
credentials.\r\n You do not have permission to view this directory or page using the credentials that you
supplied.\r\n \r\n\r\n\r\n\r\n”,
“innerError”: {
“date”: “2020-06-29T12:25:39”,
“request-id”: “ede8c362-e302-4126-bbd9-1fb77abb1fe3”
}
}
}
Actually i want to create team channel , Planner and then add planner to team channel tab using Rest (Powershell)..My understanding is error is related to permission,but i give full permission.
LikeLike
It is saying you have invalid credentials and my guess it is that your authentication to get the token is not working. Or perhaps that user you are using isn’t a member/owner in that team?
Try testing the creation out first using Graph Explorer. Do you get it working there?
LikeLike
Yes,All working fine in Graph Explorer , but there is no option there for Create Planner Plan ?
LikeLike
$body = @”
{
“owner”: “$GID”,
“title”: “$TITLE”
}
“@
$uri = (“https://graph.microsoft.com/v1.0/planner/plans”)
$planner = Invoke-RestMethod -Method POST -Uri $uri -Headers $token -Body $body -ContentType
application/json
now issue is this is working in Graph Explorer ,but now working in Powershell.
LikeLike
https://docs.microsoft.com/en-us/graph/api/group-post-owners?view=graph-rest-1.0&tabs=http
Important: If you update the group owners and you created a team for the group, it can take up to 2 hours for the owners to be synchronized with Microsoft Teams. Also, if you want the owner to be able to make changes in a team – for example, by creating a Planner plan – the owner also needs to be added as a group/team member
This is the issue..
Now i have to add myself to group
LikeLiked by 1 person
I am glad you found the reason and shared it!
That one is so easy to overlook that it doesn’t ring a bell. Didn’t even occur to me that it could be the case here.
If you create a team using team APIs and adding your user as the owner there I think you don’t have to add that person separately to group as owner & members. However, if you use Group API to manage the adding of that person –> than that is needed.
LikeLike
This is fantastic! I will be implementing this into the team provisioning here. https://thatapiguy.tech/2020/03/27/provision-teams-using-power-apps-and-power-automate/comment-page-1/#comment-1711
My question is, is there a way to setup ”templates” per se, that can be called based upon a user’s selection in a powerapp?
For instance, user selects team name, owner, members in the powerapp and also the Planner template required.
The posted URL above handles the team but I’m trying to figure out a way to handle the planner creation and use templates to do it if that makes sense.
LikeLiked by 1 person
That part you need to do manually. Unfortunately there isn’t plan templates as such. You might want to create some template plans that you use as a reference and recreate / copy them to the new team.
LikeLike
Hi Vesa, would you consider doing a similar article about consumption of buckets/tasks etc.
i.e. given a team name and planner name, get information about tasks
LikeLike
I put that idea to my todo – no promises on schedule 🙂 Thank you!
LikeLike
Thanks! Working like charm, I’ve only dreamed of setting up Planner tabs since Microsoft says it’s not supported..
LikeLike
Hello, hou can I assign a created task to a user?
LikeLike
You can use Update Task to set assignments.
https://docs.microsoft.com/en-us/graph/api/plannertask-update?view=graph-rest-1.0&tabs=http&WT.mc_id=M365-MVP-5003326
LikeLike
How*
LikeLike