Share and Enjoy !

Introduction to Provisioning New Microsoft Teams

Microsoft Teams is becoming a primary tool for collaboration in many organizations.  As the need increases for more Teams to be created, the need for more standardization and automation in the creation of these Teams is beneficial.  The combination of PowerShell and PnP Provisioning templates provides a lot of potential when it comes to creating and/or customizing Microsoft Teams and the underlying M365 groups and SharePoint sites that get created to support the Team.

In a recent blog, I highlighted the “Request a Team” application provided by Microsoft.  This is an application that users in an organization can use to request the creation of a new Team and can monitor the progress of the request.  In addition, the group responsible for creating new Teams can use the application to approve or reject the new Teams requests. 

“Request a Team” Customizations

While the “Request a Team” application is useful “as is”, ThreeWill provided some customizations to this application to make it more robust.  Most of the customizations made to the application beyond changes to the User Interface (PowerApp) were changes introduced to call an Azure Runbook when the requested Team was more robust than a simple Teams template.  The Runbook, in turn, invoked a PnP Provisioning template to accomplish some of the desired work.

At a high level, the Azure Runbook accomplished the following tasks:

  1. Create new Team
  2. Add custom sections to the OneNote NoteBook
  3. Associate the related SharePoint site to a Hubsite
  4. Create custom lists in the underlying SharePoint site that supports the Team
  5. Create tabs in the General Channel of the new Team to display the custom lists and OneNote Notebook

Items 1,2 and 3 were accomplished through PnP Powershell cmdlets.  Items 4 and 5 were accomplished through the PnP Provisioning template.

Below are some additional details with code examples to demonstrate:

Examples

Within the Azure Runbook, a PnP cmdlet is called to create an M365 group with the -CreateTeam option selected to create an associated Microsoft Team:

$newGroup = New-PnPMicrosoft365Group -DisplayName $global:teamRequestDisplayName `
            -Description $global:TeamDescription `
            -MailNickname $global:teamRequestMailboxAlias `
            -Owners $owners `
            -Force `
            -CreateTeam `
            -IsPrivate:([bool]::Parse($isPrivate))

After the M365 Group and associated Microsoft Team and SharePoint site are created, Graph PowerShell cmdlets (Microsoft.Graph module) are used to create pre-defined sections in the OneNote Notebook:

function AddProjectNoteBookSections($newGroup, $noteBook) {
    # create new notebook section
    $sections = @("Project Summary","Team Meetings","Training","Testing")
    $existingSections = Get-MgGroupOnenoteNotebookSection -GroupId $newGroup.Id -NotebookId $noteBook.Id
    foreach ($section in $sections) {
        if($existingSections -and $existingSections.DisplayName -contains $section) {
            Write-Output "'$($section)' Section Already Exists"
        }
        else {
$newSection = New-MgGroupOnenoteNotebookSection -GroupId $newGroup.Id -NotebookId $noteBook.Id `
-DisplayName $section
        }
    }
}

In this scenario, we are only creating sections based upon a hard-coded list of sections.  One potential enhancement identified was reading an existing OneNote Notebook template and creating sections and even sample pages based upon the template.  Graph cmdlets currently exist to support this.

Next, the SharePoint site related to the Team is added to a hubsite

Add-PnPHubSiteAssociation -Site $newSiteUrl  -HubSite "<hubsite url>"

Next, the PnP Provisioning template is invoked.  The following line of code invokes the PnP Provisioning template from the Azure Runbook:

Invoke-PnPTenantTemplate -Template  $global:pnpProvisioningTemplate `
        -Parameters @{"TeamTitle"="$($global:teamRequestDisplayName)"; `
"TeamAlias"="$($global:teamRequestMailboxAlias)";"Owner1"="$($owners[0])"; `
	"Owner2"="$($owners[1])";"NoteBookId"="$($noteBookId)"; `
	"SharePointUrl"="$($global:rootUrl)/sites/$($global:teamRequestMailboxAlias)"; `
	"GroupId"="$($newGroup.Id)";"SourceDoc"="$($sourceDoc)"}

PnP Provisioning templates can be quite large.  Since the SharePoint functionality has been around for a while, the provisioning of the custom SharePoint lists won’t be included in the example template, but the newer Teams configuration will be shown that accomplishes the following:

  • Hide wiki tab
  • Display the custom list, “Project Issues”, in a tab in the General Channel
  • Display the OneNote Notebook in a tab in the General Channel

Schema Configuration

The full PnP Provisioning template schema can be found at https://github.com/pnp/PnP-Provisioning-Schema to see all the capabilities including the provisioning of custom SharePoint lists.  Below is the schema configuration to accomplish the bullet items described above.  I’ve truncated some of the urls for readability.

<pnp:Teams>
     <pnp:Team GroupId="{sequencesitegroupid:TEAM.SITE.01}"
         DisplayName="{parameter:TeamTitle}"
         Description="{parameter:TeamTitle}"
         Visibility="Private" 
         Archived="false" 
         MailNickname="{parameter:TeamAlias}">
<pnp:Channels>
	     <pnp:Channel DisplayName="General"
	         Description="General"
	         IsFavoriteByDefault="true">
	               <pnp:Tabs>
		<!-- Remove Wiki tab -->
		<pnp:Tab DisplayName="Wiki" 
			TeamsAppId="com.microsoft.teamspace.tab.wiki" 
		Remove="true" />
		<!-- Create Tab for custom List -->
		<pnp:Tab DisplayName="Project Issues" Remove="false"
			TeamsAppId="26bc2873-6023-480c-a11b-76b66605ce8c">
		  	<pnp:Configuration EntityId="" 
         ContentUrl="{parameter:SharePointUrl}/_layouts/15/teamslogon.aspx?..." `
			         RemoveUrl="" WebsiteUrl="" />
		</pnp:Tab>
		<!-- Create tab for OneNote -->
		 <pnp:Tab DisplayName="Notebook" TeamsAppId="0d820ecd-def2-4297-adad-78056cde7c78" Remove="false">
		         <pnp:Configuration EntityId="" ContentUrl="https://www.onenote.com/teams/...
			RemoveUrl="https://www.onenote.com/teams/TabRemove?notebookSource=Pick&amp;..." 
			WebsiteUrl="https://www.onenote.com/teams/TabRedirect?redirectUrl={parameter..." />
		 </pnp:Tab>
	            </pnp:Tabs>
	     </pnp:Channel>
</pnp:Channels>
     </pnp:Team>
</pnp:Teams>

Conclusion

The above explanation and code has discussed and demonstrated some basic Teams configurations as well as configurations to the underlying SharePoint site.  The possibilities of what can be accomplished through PowerShell and the PnP Provisioning template is incredible.  Take advantage of the predictability and consistency that can be achieved by automating the provisioning and configuration of your new Teams.  And, if you want help from ThreeWill, please reach out to us.

Contact ThreeWill to help guide you in automated provisioning of your Teams sites!

Share and Enjoy !