How to create a team with PnP PowerShell

Sometimes I like a nice challenge. I came across a Tweet from Joanne Klein with a question about Microsoft Teams provisioning. This article describes how to create a team with PnP PowerShell and the Microsoft Graph.

Update 24/03: I have created a new blog which uses the Create Team method.

The question from Joanne

On the 23rd of january I spotted this Tweet and the first response from Drew Madelung pointed me in the right direction for a solution.

My first attempt to create a solution

The following script is the end result of my attempt to recreate the solution suggested by Drew Madelung. I choose to use Microsoft Graph and PnP PowerShell.

Feel free to use it (of course at your own risk ;)).

Breakdown of the solution

Basicly the script has three parts. First of all you need to connect with the Microsoft Graph and get an access token. I am using the latest PnP PowerShell module for this, so make sure you download this module before running the script.

After that you can use a POST request to create an Office 365 Group via the Microsoft Graph. This is the first step in the creation of a Team.

In the second step I am using the Group ID of the reponse to use a PUT request to create a Microsoft Team.

You may also like...

9 Responses

  1. Paul H says:

    Hi Dennis, great post but unfortunately i’m getting stuck with an “Access token is empty” error when i run the script. the token isn’t empty if i view the variable. Any ideas? Thanks PH

  2. Dennis says:

    @Paul H, have you tried just connecting and getting the access token? Does that actually work?

    So try to run only these two lines:
    Connect-PnPOnline -Scopes “Group.ReadWrite.All”
    $accesstoken = Get-PnPAccessToken

    Btw, which version of PnP PowerShell module are you using?

  3. John says:

    Hi Dennis.
    I ran into the same problem. The issue is that I want to use this in an automated script (called the Scheduler hourly). Therefore I prepared the credentials and passed them via -Credentials to Connect-PnpOnline. But these credentials do no longer take effect when using Connect-PnPOnline with the paramater “-Scopes”. Using “-Scopes” make the web dialog login box popping up.

    Trying it the other way round and just leave out “-Scopes” you will not get the $accesstoken using Get-PnpAccessToken. The action just does not work. If you have done a login via the web login box before, your “old” $accesstoken remains the same and you can continue working (for at least the current session).

    Any idea how to get a valid “$accesstoken” without user interaction?
    Thx in advance and greetings to the Netherlaths via UK 😉

  4. Dennis says:

    Hi John,

    I haven’t tested it myself, but maybe it is an option to register an application in Azure Active Directory, assign the correct Graph API permissions to it and use the -AppID & AppSecret parameters of the Connect-PnPOnline cmdlet instead?

  5. John says:

    Hi Dennis.
    Yes, I tried it that way. Logging in automatically seems to work. I also get an $accesstoken then. But for some reason then creating a Team Fails with http error 400: Invalid request.
    I think I set al necessary Rights such as “Group.ReadWriteAll”, but when saving the Application Settings the browser sends back some sort of an ID string and my browser (I tried all 3 different ones) offers to open the app store in order to find the appropiate app which I obviously do not have…
    Will continue to try it out. Thx.

  6. John says:

    Some additional Information: When switching over to use -AppId and -AppSecret and also AADDomain of Course I no longer use -Scopes and -Url
    My assumption is that I am just doing the Right steps but without having sufficient Rights. Group.ReadWriteAll seems not to be set, but I do not know how to find out.

  7. John says:

    *** SOLUTION ***
    Hi Dennis.
    In your update post you mentioned: That’s the beauty of Office 365, everything improves so fast! Time to write a part two of my blog post…..

    To be honest, quick changes like that sometime make things unrelyable. The fetaure to set Access Rights like Group.ReadWrite.All and Users.ReadWrite.All has changed completely. Obviously not all Rights set there correspond to the -Scopes Parameter of the very same Connect-PnPOnline cmdlet. And threfore also the owner of a Group / Team is set differently. While the creator of the Group / Team is the owner by Default you have to add this to the JSON data when using the App Consent (Service). Then everything works as expected. Here is a Sample for a working JSON:

    $body = @’
    “template@odata.bind”: “‘standard’)”,
    “displayName”: “Dodenhof”,
    “description”: “Dodenhof bei Posthausen”,
    “owners@odata.bind”: [

    So this part is important to add:
    “owners@odata.bind”: [


  1. March 24, 2019

    […] Create Team. With this method you are able to create teams with just one request. So compared to my previous post this is easier when you want to create a team from […]

  2. March 29, 2021

    […] Create Team. With this method you are able to create teams with just one request. So compared to my previous post this is easier when you want to create a team from […]

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.