A Teams PowerShell Primer

Teams PowerShell

A Flawed Approach to Automation

In November, Microsoft released the first beta version of a PowerShell module for Teams. I did not like the module too much because I consider it critically flawed. The module is user-centric rather than administrator centric, so it is difficult to automate tasks. For instance, you cannot write a script to process every team in the tenant unless you use an account that is a member of every team.

The original module was very buggy. Microsoft updated it in December to version 0.9.1. The module is more stable but some parameters and expected features still do not work, which is what you expect from beta releases. Documentation for the cmdlets is available online.

[Update October 20: The latest version is now 0.9.5]

Connecting to Teams

Before you can use the Teams PowerShell module, you must download the module from the PowerShell gallery and install it on your PC (see the instructions in the link above). You can then run the Connect-MicrosoftTeams cmdlet to connect to the Teams service and start using the cmdlets.

Because a team always has an underlying Office 365 group, you can use the cmdlets that work against Office 365 groups with Teams, so you probably want to connect PowerShell to Exchange Online too. And then throw in a connection to Azure Active Directory for good measure.

The examples shown in the rest of this article are based on and tested against version 0.9.1 of the Teams PowerShell module.

Manipulating Teams Membership

The Get-Team cmdlet returns a list of the teams to which the logged-in user belongs. The cmdlet only returns three properties, the most important being the GroupId, which we use with most of the other cmdlets. This is the identifier that the group is known by in Azure Active Directory.

PS] C:\> Get-Team

GroupId                              DisplayName               Description           
-------                              -----------               -----------           
8836e3ca-6531-402a-ac5f-b71c83d6affa Mail Filter Patent        Discussing the Mail Filter patent
84fe8ec1-d85f-4564-a786-1f7bedd9862c Engineering Testers       People who do testing for engineering
72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 Office 365 Chat           What’s happening in Office 365

Update: From 0.9.5 onward, Get-Team can return teams for the tenant.

For example, to list the membership of a team, we use the Get-TeamUser cmdlet. This example outputs the display name (Name), role, and Azure Active Directory account (User) for each member. Guest users are clearly marked.

[PS] C:\> Get-TeamUser -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 | format-Table Name, Role, User

Name                                   Role   User   
----                                   ----   ----       
Tony Redmond                           owner  [email protected]
Jeff Guillet                           member [email protected]
Administrator                          member [email protected]    
Vasil Michev (MVP)                     guest  [email protected]#EXT#@Office365itpros.onmicrosof...

You can use the Get-TeamUser cmdlet to return the membership of any team if you know the group identifier, which you can find out from Azure Active Directory. For example:

[PS] C:\> Get-TeamUser -GroupId (Get-AzureADGroup -SearchString "A random group").ObjectId

Alternatively, use the Get-UnifiedGroup cmdlet to retrieve the GroupId:

[PS] C:\> Get-TeamUser -GroupId (Get-UnifiedGroup -Identity Hydra).ExternalDirectoryObjectId

Get-TeamUser returns the group membership for any kind of Azure Active Directory group as the cmdlet does not check that the target group is an Office 365 group. This proves that Get-TeamUser is simply another way to call the Get-AzureADGroupMember cmdlet.

The Add-TeamUser cmdlet adds a new member to a team, while the Remove-TeamUser cmdlet does the opposite. You cannot run these cmdlets against a team unless you are a team owner or a tenant administrator.

[PS] C:\> Add-TeamUser -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 -User "[email protected]" -Role Member
[PS] C:\> Remove-TeamUser -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 -User "[email protected]"

If you are a tenant administrator, you can add a member to any Office 365 group (and team) by fetching the group identifier with the Get-UnifiedGroup cmdlet and using it with Add-TeamUser to find the correct group. This works even if an Office 365 group is not team-enabled. For example.

[PS] C:\> Add-TeamUser -GroupId (Get-UnifiedGroup -Identity "Stock Market Club").ExternalDirectoryObjectId -User [email protected] -Role Member

Creating New Teams

You can create a new team in two ways: either create a brand-new team from scratch or team-enable an existing Office 365 group. If you add a new team from scratch, you also probably want to add some users.

The New-Team cmdlet applies in both cases. Here is an example of creating a new team from scratch. In this case, we create a new team and set its access type to Private and apply one of the classifications defined for the tenant. The AddCreatorAsMember parameter is False, meaning that the account used to run New-Team is not automatically added as a team owner.

[PS] C:\> New-Team -DisplayName "Microsoft Ignite Conference 2018" -Alias Ignite18 -Description "Planning for the company’s participation in the Microsoft Ignite 2018 conference" -AccessType Private -Classification Confidential -AddCreatorAsMember $False

We can now fetch the GroupId for the newly created Office 365 group and use that to add some team members:

[PS] C:\> $GroupId = (Get-UnifiedGroup -Identity Ignite18).ExternalDirectoryObjectId
[PS] C:\> Add-TeamUser -GroupId $GroupId -User [email protected] -Role Member
[PS] C:\> Add-TeamUser -GroupId $GroupId -User [email protected] -Role Owner

Once the team membership is populated, you can then proceed to amend group settings and create some channels.

To create a new team based on an existing Office 365 group, run New-Team and pass the identifier for the Office 365 group in the -Group parameter. [This function does not work in version 0.9.1]

Playing with Team Settings

A set of cmdlets is available to manipulate the various settings that control how members interact with a team. First, the Get-TeamMemberSettings cmdlet reveals what members can do to the structure of the team (add channels, etc.):

[PS] C:\> Get-TeamMemberSettings -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4

AllowCreateUpdateChannels         : True
AllowDeleteChannels               : True
AllowAddRemoveApps                : True
AllowCreateUpdateRemoveTabs       : True
AllowCreateUpdateRemoveConnectors : True

Use the Get-TeamMessagingSettings cmdlet to see the settings that control whether users can edit or remove messages and use team and channel mentions in conversations:

[PS] C:\> Get-TeamMessagingSettings -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4

AllowUserEditMessages    : False
AllowUserDeleteMessages  : False
AllowOwnerDeleteMessages : False
AllowTeamMentions        : True
AllowChannelMentions     : True

To see what guest users can do in a team, use the Get-TeamGuestSettings cmdlet:

[PS] C:\> Get-TeamGuestSettings -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4

AllowCreateUpdateChannels AllowDeleteChannels
------------------------- -------------------
                    False               False

To see the “fun stuff” settings for a team, use the Get-TeamFunSettings cmdlet:

[PS] C:\> Get-TeamFunSettings -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4

AllowGiphy GiphyContentRating AllowStickersAndMemes AllowCustomMemes
---------- ------------------ --------------------- ----------------
      True           moderate                  True            False

As you can see, the cmdlets that deal with team settings mimic what’s available through the client user interface (Figure 1).

TeamsSettings
Figure 1: Teams settings in the client (image credit: Tony Redmond)

If you are a team owner or tenant administrator, you can update the settings using the Set-TeamMemberSettings, Set-TeamMessagingSettings, Set-TeamGuestSettings, and Set-TeamFunSettings cmdlets: for example:

[PS] C:\> Set-TeamMessagingSettings -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 -AllowTeamMentions $False

At least, that’s what’s supposed to work. I experienced many errors with the Set- cmdlets.

Dealing with Channels

To return the channels in a team, use the Get-TeamChannel cmdlet:

[PS] C:\> Get-TeamChannel -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4

Id                                   DisplayName             Description                
--                                   -----------             -----------           
534ebe88-8236-4e68-acd4-6935b126fdca General                 What’s happening in Office 365
f1dc5034-b5d5-4d01-b97b-14f2d37dfc31 The EHLO blog           Posts from the EHLO blog 
d286c712-6d6a-406f-84fb-74981e9276c2 MVP Tweets              Tweets from MVPs        
e8d93767-9017-4050-9782-6fd0eda4073c News from Petri.com     News from Petri.com   
c265e899-6905-4824-9c8a-95d86b0df585 Group Email             Email sent to the group

To change a channel setting, you need to give the group identifier and the current channel name to the Set-TeamChannel cmdlet. You cannot update the settings of the General channel.

[PS] C:\> Set-TeamChannel -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 -CurrentDisplayName "News from Petri.com" -NewDisplayName "Petri.com News" -Description "RSS feed from Petri.com"

The New-TeamChannel cmdlet adds a channel to a team. For instance:

[PS] C:\> New-TeamChannel -GroupId 72ee570e-3dd8-41d2-bc84-7c9eb8024dd4 -DisplayName "Bug Tracking" -Description "A place to track bugs as we discover them in our favorite product"

The Remove-TeamChannel cmdlet is available to remove a channel from a team.

A Surprising Use for Get-TeamChannel

Administrators often ask for a way to know what groups are enabled for Teams or the other Office 365 resources available to groups. The Get-UnifiedGroup cmdlet returns the basic properties of groups, including the number of members, the URL for SharePoint resources, and if connectors are enabled, but it doesn’t tell you if the group is team-enabled or uses Planner. You can figure out whether an Office 365 group has an associated team by comparing lists of teams and groups, but that is an impossible task in most tenants.

However, it is possible to come up with innovative workarounds to the problem. One example from David Whitney (Microsoft) uses the Get-TeamChannel cmdlet to test whether any channels exist for a group on the basis that if a channel is available, the group is team-enabled. If the test generates a page not found (404) error, the assumption is that the group is not team-enabled. It is an imperfect and flawed solution, but it shows what is possible.

I amended the code (see the link) to generate a HTML report (Figure 2), which might be interesting to you.

Teams Groups Report
Figure 2: Reporting Office 365 Groups that are team-enabled (image credit: Tony Redmond)

After 1.0

I suspect that Microsoft will not change the overall shape of the Teams PowerShell module soon. The first task is to deliver a V1.0 release; attention then turns to what might be done to improve that release. I hope that Microsoft changes focus away from mimicking what can be done in the Teams client to understanding what administrators need to automate the maintenance of Teams.

Follow Tony on Twitter @12Knocksinna.

Want to know more about how to manage Office 365? Find what you need to know in “Office 365 for IT Pros”, the most comprehensive eBook covering all aspects of Office 365. Available in PDF and EPUB formats (suitable for iBooks) or for Amazon Kindle.