cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous

How to provision team with Flow?

Teams are rapidly replacing traditional SharePoint workspaces. If and when this happens, we need a tool for end-users to order different teams for different purposes. 

Fortunately, Microsoft Graph has plenty of useful APIs for managing Teams. In this blog post we build simple Teams provisioning solution using:

  • PowerApps
  • SharePoint
  • Flow
  • Microsoft Graph

In our solution:

  • The user can subscribe to either a project team or "regular" team (= we have two Teams template)
  • The user will be also the owner of the new team 
  • The user may nominate other team owners and members when placing the request
  • If the user requests a private team, she/he must justify why this team has to be private (our example organization wants all communication to be transparent)
  • Private teams will be manually approved/rejected before they are created. Public teams are automatically created

And all of this without writing a single line of code!

 

Step 1 - Creating templates

We create two new teams (Template_Team and Template_Project) which will act as templates. Let's make the following changes to them.

  • Add typical channels
  • Delete Wiki site link for each channel (I just don't like them)

 

teams teamplates.png

 

When we clone an existing team, we can pick (in REST API call) which part of the source team will be copied to the new team. Choices are

  • members
  • tabs 
  • apps 
  • settings
  • channels 

Template owners are always copied to a new team. Don't be worried, they can be automatically removed during the process.

 

Step 2 - SharePoint list for the requests

We need a place where to store all team requests. SharePoint list is an excellent choice for that. Let's create a one with the following columns.

  • Title (name of the team)
  • Template id 
  • Template name
  • Description
  • isPrivate 
  • Comments for privacy (why this team should be private)
  • Owners 
  • Members 
  • Status 

 

teams requests list.png

 

We need also another list having information about used team templates (name and id). 

 

teams teamplates list.png

 

Wait a minute, where i can find those team id's?

 

You can always use Microsoft's excellent Graph ExplorerSign in with your account and execute joined teamsquery. From the response, you find all the teams you have been joined (also those two templates we just created).

From there you can find also that team id we are looking for.

 

get teams id.png

 

Step 3 - Order form (PowerApps)

How end users start the provisioning process? With PowerApps of course!

Just create an empty PowerApps and add the form on it. Attach the form to the SharePoint list we just created. After quick restructuring, our PowerApps looks like this.

 

teams order powerapps.png

 

I skip the details (this is not a PowerApps community) but after a few minutes of cleaning and building some logic to the form fields PowerApps looks like this.

 

teams order powerapps ready.png

 

If you are not familiar with PowerApps, don't stop here. You can skip PowerApps part and start with manually entering requests on the SharePoint list.

Let's make a few requests with PowerApps.

 

teams orders.png

 

Seems to be working. Now we can start the hard part of this exercise.

 

Step 4 - Register Azure AD Application 

We will use Microsft Graph API in our Flow for creating and updating teams. For that, we have to somehow authenticate our REST API calls. This can be easily done by using Azure AD Application.

First, we need to create a new Application in Azure AD (Azure Active Directory -> App registrations -> New application registration ).

 

azure ad step 1.png

 

After that we have to require permissions for the Application (Settings -> Required permissions -> Add - > Microsoft Graph).

Just pick the right ones from the list

  • Group.ReadWrite.All
  • Directory.ReadWrite.All
  • User.ReadWrite.All

Names are of course different from those used in the Microsoft documentation (above). No worries, they still can be found there.

 

Screenshot 2018-11-21 at 18.34.46.png

 

Finally, the Administrator must approve the requested rights. Usually, you can't do this by yourself but we you have to ask an administrator to grant permissions. 

This time I can perform self-acceptance.

 

azure ad step 3.png

 

Then we create a secret. The key of the secret and application id are the pair we use in authenticating.

 

azure ad step 4.png

 

We need also Tenant id. It can be found, for example, in Azure Ad properties (directory id).

 

azure ad step 5.png

 

Azure AD part is ready. We can move on to build the actual workflow.

 

Step 5 - Use Flow to create a team

The new team is created with Flow starting every time when a new item is created on our request list. 

At the beginning of the workflow, we initialized variables for storing necessary stuff to use Microsoft Graph API

  • Tenant Id
  • Client Id
  • Secret

And one extra variable to store the privacy setting of the team. The default value for it is "Public". 

 

flow.png

 

Approval of the request (private team)

If the user has requested a private team, we start an approval process. 

  • Update the request status to "waiting for approval"
  • Start the approval workflow
  • If the request is rejected
    • Send an email about rejection to the requester 
    • Update the request status to "fail"
    • Stop workflow (with Terminate operation)
  • Update the team visibility to the private

 

flow-21.png

 

The process above is skipped entirely if the requested team will be public.

 

Creating a team

Next, we create the requested team. In fact, we create a copy of the matching team template.

This is done in a very simple HTTP call. In the body, there is all needed information in place.

 

Screenshot 2018-11-21 at 18.48.42

 

However, the team will be not created immediately. This will cause a little bit more effort because we are not finished yet. The aim is to add more owners and members to the team.

After the REST API call, we add Parse JSON function. It makes easier to handle all the information the REST API call returns.

Among the returned fields we found locationIt is URL address from where we can ask whether a team is ready and what GUID it has.

Nex we just wait for 5 minutes before we continue. Actually, we should build a loop for polling team creation status. Maybe next time.

 

flow4.png

 

Now the team has been created. Next, we get (with Microsoft Graph and Parse JSON) GUID for the created team.

 

Screenshot 2018-11-21 at 18.56.31.png

 

Adding owners

At last, we can finalize the team we have created.

We add requester as an owner for the team. For that, we need the id of requester user account. This is done with Microsoft Graph API (of course). After that, we can add the user to the owners group.

 

Screenshot 2018-11-21 at 18.59.27.png

 

In the same way, we add other owners (requester listed in the request form).  

 

Screenshot 2018-11-21 at 19.01.45.png

 

Adding members

This starts to be a little bit boring. Members (requester listed in the form) are added exactly the same way than owners.

The only small difference is in the URL we use. Word "owners" is replaced with "members".

 

https://graph.microsoft.com/v1.0/groups/{teamguid}/members/$ref

 

Screenshot 2018-11-21 at 19.05.21.png

 

Removal of the (template) original owner

The new team has the same owners than the team where it has been cloned from. We want to remove those ones.

Hardly comes as a surprise that this is done by REST API call to the Microsoft Graph.

 

Screenshot 2018-11-21 at 19.25.48.png

 

Summary

Our solution can be used as a base for the provisioning solution.  It can create different teams according to what the user has requested. It also can add owners and members of the created team. 

Clone function is pretty handy. It makes easier to understand what templates actually looks like. An alternative way is to build the whole team from the scratch (add channels, change settings, add apps etc) in the Flow.

Comments

This is a great idea and implementation. I'm sharing it with my team and looking forward to trying it out with some of my customers.

I really wish some more details about a few steps were provide. 

 

For example - How are you parsing the JSON? I see the first few lines but that does not give me all the steps to grab the GUID from the returned JSON.

 

After researching this a bit it looks like you ran the scripts one to generate the returned JSON then pasted that into the "Use Sample Payload to generate schema" which then allows you to parse the JSON that is returned more easily.

Anonymous

Yes Berny, just like you wrote.

 

Parse JSON is super handy. First just run action that outputs JSON. Copy the output and give it to Parse JSON as an example (Use Sample Payload to generate schema). This works very well. If the JSON is very complicated, then you might like/have to write a schema by yourself.

 

After Parse JSON action you have all the output in arrays and/or variables. You can use them easily in your Flow,

Anonymous

Hey Timo,

 

Great article and I will be using it is a base for the solution I am developing.  One request though.  Would you be OK with exporting the flow and sharing?  It would definitely speed up my development time if I got an actual flow example to import and work with.

Anonymous
Anonymous

@Anonymous - Thanks for sharing.  It will be a great help.  Happy New Year!

Hello @Anonymous,

 

I create MS Team using Custom Connector and flow, Authentication with MS Teams connector on Azure AD would require the global admin password to be fed in each time you log in, can you please tell me what i do that they do not ask again and again for global admin password.

 

Thanks

Thanks for nice post. It helps me a lot.

How can we parse response header of HTTP call?

It does not return JSON format, so I can not get TeamId from header.

 

 

 

2019-03-07_173845.png

 

Anonymous

Hi!

 

I can pars output of the clone operation (in header) with using PARSE JSON action. Tricky part might be to get example output that you can use with PARSE JSON action.

 

I have used schema:

{
    "properties": {
        "headers": {
            "properties": {
                "Cache-Control": {
                    "type": "string"
                },
                "Content-Length": {
                    "type": "string"
                },
                "Content-Type": {
                    "type": "string"
                },
                "Date": {
                    "type": "string"
                },
                "Duration": {
                    "type": "string"
                },
                "Location": {
                    "type": "string"
                },
                "Strict-Transport-Security": {
                    "type": "string"
                },
                "Transfer-Encoding": {
                    "type": "string"
                },
                "client-request-id": {
                    "type": "string"
                },
                "request-id": {
                    "type": "string"
                },
                "x-ms-ags-diagnostic": {
                    "type": "string"
                }
            },
            "type": "object"
        },
        "statusCode": {
            "type": "integer"
        }
    },
    "type": "object"
}

After the clone you get that "location" from where you can ask if the team is allready cloned or not. When asking status, you get id as a part of response.

 

 

 

Anonymous

Hi Timo,

 

Thank you for the great article. 

 

We have managed to get Teams, channels and its settings to clone. however the tabs and apps are not showing for us (We are trying to use MS Planner in a tab). Did you manage to get yours to show and if you did, do you advise any sort of work around we could try?

 

We have tried changing permissions from app to delegate, tried using the planner api using the HTTP flow, however no luck.

 

Any help would be much appreciate.

 

Regards,

Ricky

Anonymous

Hi!

 

Actually I didn't manage to clone tabs ( I used Application level permission in my excercise). But I have told that it works when using Delegated permissions.

 

Please try

- Directory.ReadWrite.All (application)

- Group.ReadWrite.All (application)

- Group.ReadWrite.All (delegated)

- Site.Read.All (Application

- User.Read (Delegated)

- User.Read.All (Delegated)

- User.ReadWrite.All (delegated)

 

Some of those are not needed for this case, but you can drop them out one by one after you managed to create those tabs and apps.

 

And try also beta endpoint aso.

Hi

 

This acrticle is very good and just what i needed.

I tried eveyrthing now but im stuck at the Clone Team part.

 

I get the following error message.

BadRequest.

 

Outputs

{
"error": {
"code": "BadRequest",
"message": "Failed to execute MsGraph backend request CreateGroupS2SRequest. Request Url: https://graph.microsoft.com/beta/groups, Request Method: POST, Response Status Code: BadRequest, Response Headers:
 
2019-03-21 14_52_40-Run History _ Microsoft Flow.png
 

@JimmyWork have you tried calling that graph method with the Graph explorer? it is a Beta endpoint and may still have issues.

@DLGross 

 

Does not work from Graph Explorer.

 

"code": "BadRequest",
"message": "Failed to execute MS Graph backend request CreateGroupRequest. The server failed to respond correctly. Response Code: BadRequest, Reason: Reason: Bad Request, Correlation headers: request-id

 

If i only type in tabs in partsToClone i get this message.

{
"error": {
"code": "InvalidRequest",
"message": "Tabs cannot be cloned without cloning Apps as well.",
"innerError": {

 

When i then add to clone Apps it will generate the error message

Anonymous

Hi @JimmyWork !

 

 Just to be sure. Are you using beta or prod (V1.0) endpoints on your rest api calls?

 

So are the URLs you are using like

https://graph.microsoft.com/beta/...

or

https://graph.microsoft.com/V1.0/...

 

 

 

@Anonymous 

 

Im actually using the flow you posted to download. 

 

And i have tried typing it in graph explorer both beta and v1. 0

 

It seems that when i add apps in the cloning part of the body it will produce the error and i cannot clone without adding the apps so i really dont know why its not working. Not even in graph explorer. Can it be something with my team template? 

 

I created a new Team and took the id of this. 

 

Im really thankfull for all the help here. 

 

@Anonymous 

 

I solved it, for this to work now i have to remove "classification": ""

If you remove this the Team gets created, so i cannot have "classification": "" in the body

 

@Anonymous 

 

I hope it's okey that i ask so much 🙂

 

I downloaded your flow and edited to best of knowledge.

At the apply to each new owner and same for member part i dont have access to the sharepoint columns as an option. So my Owners column is not available for me to pick.

 

I dont know why its not picking it up really. Any input would be appricitaed

 

2019-03-22 13_23_21-Edit your flow _ Microsoft Flow.png

Anonymous

@JimmyWork 

 

Nice that you solved the cloning issue! I am sorry if there were some beta endpoints used in my downloadable version of Flow. Beta is always beta and I had all kind of issues with beta endpoint.  I had also issues with service level permissions. Delegated permissions worked at the time blog post was written much better.

 

But about the owners...

 

Does the owners column allow multivalues in your SharePoint list?

 

Näyttökuva 2019-3-23 kello 18.55.03.png

 

 

@Anonymous

 

First i would like to say thanks again. This flow is just amazing.

And thank you for answering me. 

 

Im pretty sure i have not set allow multiple selections in the column so this is the first thing i will do on monday. I dont have access to the account until then. 

 

Thank you for all the help and i post an update on monday. Have a great weekend

@Anonymous 

 

It was the columns i needed to change according to your info.

Thank you so much.

@Anonymous 

 

Hi Timo

Im having one small issue, i downloaded your flow.

The last part, "Apply to each new owner"

If i create the Item i will be made into an Owner, if i then in the list as Owners also add myself it will conflict with the "Apply to each new owner" because im already added, this is logic. But in my situation this will happen alot from users and i wonder what i need to add to check if owner or members is already added skip and move forward in flow.

Anonymous

Hi @JimmyWork !

 

As allways, there are different ways to handle this. Just pick one.

 

For eaxmple:

- When adding owner in "Apply to each new owner" check if the current owner to add is same than requester. If it is, just skip it.

- Allow Flow to continue in case when Add new owner action fails (not cool)

 

 

 

 

 

 

@Anonymous 

 

Could you re-share the link to the exported Flow please? It's currently expired.

 

Thanks in advance!

Hi @Anonymous 

 

Thanks so much for the article. My company and I are trying to incorporate it for a client's environment and create a new Team whenever a custom entity record is created within a common data service app.

 

Right now I'm stuck on the parse JSON part. I'm not too experienced with Flow nor JSON so I'm wondering where to even start in regards to what I'm entering into that part.

Any advice?

 

Thanks.

Anonymous

Here is link for downloading the example Flow. Keep in mind example is done over 6 months ago. Some parts of it can be done better nowadays. 

 

But I hope it give little help. 

 

https://digitalillustrated-my.sharepoint.com/:f:/p/timo_pertila/Es9vAn41v4pCvjbV2oKCuw8Bsjkov1DNHmwg...

Hi @Anonymous 

 

Could you share youre flow again?

 

Kind regards,

 

Litrick

Great article!  If you wouldn't mind sharing the flow download again that would be most excellent!  

Hi,

 

would it be possible to reshare your flow?

 

Thanks

Knut

Anonymous

Sure! Sorry for late answer 😞

 

And please note that this example is allmost a year old. Think might be changed after that.  

 

https://digitalillustrated-my.sharepoint.com/:f:/p/timo_pertila/Es9vAn41v4pCvjbV2oKCuw8Bsjkov1DNHmwg...

 

 

@Anonymous

 

Thanks

I m getting the following error , Please help. 

 

{
"error": {
"code": "BadRequest",
"message": "Failed to execute settings store request: https://settings.teams.skype.com/au/v1.0/settings/teams/teams/19:31730bf0108c4aa5a5c77cefda95ad8d@th..., StatusCode: 400, ReasonPhrase: Schema validation errors, X-MSEdge-Ref: Ref A: 0E544410CCAE429292F3D3A0A7D5EFD0 Ref B: SG2EDGE1121 Ref C: 2019-09-16T07:34:00Z",
"innerError": {
"request-id": "9b9a30bf-2e42-489a-8238-79ce01f0830b",
"date": "2019-09-16T07:34:00"
}
}
}

@Anonymous 

Is it possible to reshare flow? The provided link is expired.

 

Is it possible to send an Adaptive Card to Microsoft team channel and Requester if request approved or reject instead of Email Notification?

 

Let's assume, I am not a member of the template team and want to clone using delegated permission with TemplateTeamId. Does it possible?

I have tried with the above scenario and getting access denied.

 

Failed to CloneTeams. StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  request-id: 7d37ee56-8aa3-44fd-83e6-d5e85fb88fab
  client-request-id: 7d37ee56-8aa3-44fd-83e6-d5e85fb88fab
  x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"Central US","Slice":"SliceC","Ring":"4","ScaleUnit":"000","RoleInstance":"AGSFE_IN_11"}}
  Strict-Transport-Security: max-age=31536000
  Cache-Control: private
  Date: Fri, 25 Oct 2019 07:48:09 GMT
  Content-Length: 255
  Content-Type: application/json
}

 

Provide your feedback on this how can I achieve the team clone functionality for the above scenario so I can get all apps, tabs, channels, etc. 

 

Unfortunately, under the October 2019 Power Automate licensing this solution now requires licenses because it uses the now Premium 'HTTP' action...

 

The same goes for solutions that use an Azure Automation runbook to run the 'new-team' powershell command in the cloud.

 

It seems that there is no way to automate teams creation with included Office 365 Flow licenses anymore.

 

Dumb question here, but I'm an Owner or Member of a lot of MS Teams. When I run the joinedTeams query, how can I see all of the responses, not just the preview. My template isn't showing up here.Response PreviewResponse Preview

Please disregard my last comment. I realized I was using test data. Ugh - so sorry!

Timo,

 

I'm trying to follow along but I keep getting a Resource Not Found error. Any thoughts? I posted on Tech Community as well.

 

https://techcommunity.microsoft.com/t5/Teams-Developer/Microsoft-Teams-Graph-API-Error/m-p/1061052

Anonymous

Hi @GStover 

 

Seems that you are calling URL https://graph.microsoft.com/teams/a30b9536-631b-4fe9-ad1c-836c00f17dc7/clone 

 

You should include API version in url. Like

https://graph.microsoft.com/v1.0/teams/a30b9536-631b-4fe9-ad1c-836c00f17dc7/clone  

Is there any chance you could share the flow again?

Sorry to bother you once again. When the flow trys to process the Owners, I am getting ActionFailed. An Action failed. No dependent actions succeeded. Any thoughts?

 

 

Image1.JPG

Anonymous

@GStover 

Hi!

 

Please click "Next failed" inside "Apply to each new owner" loop and look which of the actions actually fails and why. It might help you.

 

it might be

- there is no such a user (get owner id fails)

- adding owner fails (user allready is owner)

- something else

 

Hi @Anonymous ,

 

is it possible to export the PowerApps App?

I'm not familiar with PowerApps, so that would be helpful for me 🙂

 

Thank you very much


Josef

Hi @Anonymous,

 

i also will use your FLOW Template.

 

I uploaded the Template and configured it, but i get following Error:

1.PNG2.PNG

 

Maybe you have got an tipp for me why i got an Forbidden Error. I'm a Global Admin and have privileges to all Sharepoint Sites 🙂

 

Thank you for helping me!

 

 

 

 

THIS PROBLEM IS SOLVED 🙂 I forget in Azure Active Directory to approve the API with Admistrator Rights 🙂

Anonymous

Hi @Anonymous 

 

Thanks for posting this awesome article. I was trying to implement this in my tenant and got an error at Parse Request guid action. Below is the schema I used. Screenshot of the error message is beneath Schema. Please  help. 

 

{
"type": "object",
"properties": {
"businessPhones": {
"type": "array"
},
"displayName": {
"type": "string"
},
"givenName": {
"type": "string"
},
"jobTitle": {
"type": "string"
},
"mail": {
"type": "string"
},
"mobilePhone": {},
"officeLocation": {},
"preferredLanguage": {},
"surname": {
"type": "string"
},
"userPrincipalName": {
"type": "string"
},
"id": {
"type": "string"
},
"@odata.context": {
"type": "string"
}
}
}
ParseErr.png

 

 

 
 

@Anonymous 

 

which type did you use in your Sharepoint List?

@Anonymous Hi,

 

Thanks for this great article. Is it possible to export and share the link the Flow you used in this case study again?

 

I really need this.

This is awesome! @Anonymous Is there any chance you could share the flow again? 

Hi, Sorry I know you were asked a million times already!

Could you please share your flow again?

 

Tks!! 

 

About the Author
  • Experienced Consultant with a demonstrated history of working in the information technology and services industry. Skilled in Office 365, Azure, SharePoint Online, PowerShell, Nintex, K2, SharePoint Designer workflow automation, PowerApps, Microsoft Flow, PowerShell, Active Directory, Operating Systems, Networking, and JavaScript. Strong consulting professional with a Bachelor of Engineering (B.E.) focused in Information Technology from Mumbai University.
  • I am a Microsoft Business Applications MVP and a Senior Manager at EY. I am a technology enthusiast and problem solver. I work/speak/blog/Vlog on Microsoft technology, including Office 365, Power Apps, Power Automate, SharePoint, and Teams Etc. I am helping global clients on Power Platform adoption and empowering them with Power Platform possibilities, capabilities, and easiness. I am a leader of the Houston Power Platform User Group and Power Automate community superuser. I love traveling , exploring new places, and meeting people from different cultures.
  • Read more about me and my achievements at: https://ganeshsanapblogs.wordpress.com/about MCT | SharePoint, Microsoft 365 and Power Platform Consultant | Contributor on SharePoint StackExchange, MSFT Techcommunity
  • Encodian Owner / Founder - Ex Microsoft Consulting Services - Architect / Developer - 20 years in SharePoint - PowerPlatform Fan
  • Founder of SKILLFUL SARDINE, a company focused on productivity and the Power Platform. You can find me on LinkedIn: https://linkedin.com/in/manueltgomes and twitter http://twitter.com/manueltgomes. I also write at https://www.manueltgomes.com, so if you want some Power Automate, SharePoint or Power Apps content I'm your guy 🙂
  • I am the Owner/Principal Architect at Don't Pa..Panic Consulting. I've been working in the information technology industry for over 30 years, and have played key roles in several enterprise SharePoint architectural design review, Intranet deployment, application development, and migration projects. I've been a Microsoft Most Valuable Professional (MVP) 15 consecutive years and am also a Microsoft Certified SharePoint Masters (MCSM) since 2013.
  • Big fan of Power Platform technologies and implemented many solutions.
  • Passionate #Programmer #SharePoint #SPFx #M365 #Power Platform| Microsoft MVP | SharePoint StackOverflow, Github, PnP contributor
  • Web site – https://kamdaryash.wordpress.com Youtube channel - https://www.youtube.com/channel/UCM149rFkLNgerSvgDVeYTZQ/