A Teams PowerShell Primer
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]
Passwords Haven’t Disappeared Yet
123456. Qwerty. Iloveyou. No, these are not exercises for people who are brand new to typing. Shockingly, they are among the most common passwords that end users choose in 2021. Research has found that the average business user must manually type out, or copy/paste, the credentials to 154 websites per month. We repeatedly got one question that surprised us: “Why would I ever trust a third party with control of my network?
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).
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.
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.