Teams Doesn’t Need Two PowerShell Modules (But Why Two Exist)

One for Teams, One for Skype for Business Online

One of the blessed PowerShell mysteries is the necessity to use two modules to manage Teams. There’s the Teams module and the oh-so-wonderful Skype for Business Online module. The two modules are very different.

The Teams PowerShell module is based on the Microsoft Graph. Its original implementation was flawed because the cmdlets available in the module mimicked the same ability to change settings as available to users in the Teams desktop and browser client. Over time, Microsoft gradually improved the module, notably to incorporate support for team management needed by the Teams Admin Center.

Generally Available PowerShell for Teams

All this work was presented by Microsoft as a preview. They eventually released a generally available version of the Teams module in April 2019. Unfortunately, the GA module suffers from some notable defects, the most obvious of which being its slowness when retrieving sets of teams. Filtering is another area ripe for improvement.

But the biggest improvement Microsoft could make is to dump the Skype for Business Online module. As far as I can see, the only reason this module lingers on is that it was easier for Microsoft to build it out with the policies needed by Teams.

Policy-Driven Advantages

Policies are good because they allow administrators to apply a very granular level of control over different aspects of Teams. It would have been great if Microsoft had created cmdlets to manage the policies used by Teams in the Teams module, preferably after making sure that the policy cmdlets worked in a consistent manner to the rest of the cmdlets in the module.

Why Policies Remain in Skype for Business Online

They didn’t. Probably because it’s easier and faster in software engineering terms to extend an existing framework to add some extra policies, we’re left with two incoherent modules. It’s also correct that we’re in the middle of the transition from Skype for Business Online to Teams, so a case can be argued that keeping the policy cmdlets in the Skype for Business Online module is sensible.

Of course, software engineers never have to manage actual tenants, so they don’t see just what a pain it can be to have functionality split across multiple modules. As far as the engineers are concerned, their code works. And to be fair, the cmdlets in the Skype for Business Online module do work. That is, if you keep a session active as the module likes to time out and then won’t reconnect. Apparently, there’s a cmdlet “coming” to fix the problem, but I see no trace of it as I write.

The Big Seven Policy Cmdlets for Teams

In any case, not much is going to change soon, which means that Teams administrators need to understand how to work with the policies that affect Teams. Running the Get-Command cmdlet reveals that there are 18 sets of policy cmdlets in the Skype for Business Online module. Each set has a Get- cmdlet (fetch policy settings), Set- cmdlet (update policy settings), New- (create new policy of the type) and Grant- cmdlet (assign a policy to a user). Some policy cmdlets in the module (like the *-CsTeamsNotificationAndFeedsPolicy set) are undocumented.

The Teams Admin Center does a good job of making it easy to create and manage policy settings and to assign policies to users (Figure 1).

Teams Policies for a User
Figure 1: Assigning Teams policies to a user in the Teams Admin Center (image credit: Tony Redmond)

However, when the time comes to assign a policy to multiple users, you’ll want to know how to do this with PowerShell. Table 1 outlines the seven policy cmdlets of most interest.

Cmdlet Set Purpose


Controls which apps Teams users can access. See Permissions policies under Teams apps in the Teams Admin Center.
*-CsTeamsAppSetupPolicy Controls the set of apps pinned to the Teams app bar. See Setup policies under Teams apps in the Teams Admin Center.
*- CsTeamsCallingPolicy Controls the calling policies available within a tenant. See Calling policies under Voice in the Teams Admin Center.
*- CsTeamsChannelsPolicy Controls the org-wide settings for channels (including private channels in the future). See Teams policies under Teams in the Teams Admin Center.
*- CsTeamsFeedbackPolicy Controls the display of feedback surveys and Give feedback option for Teams clients. This policy isn’t available in the Teams Admin Center.
*- CsTeamsMeetingPolicy Controls the type of meetings users can create and the features they can use in meetings. See Meeting policies under Meetings in the Teams Admin Center.
*- CsTeamsMessagingPolicy Controls the messaging features available to users. See Messaging policies in the Teams Admin Center.

Table 1: Essential Teams Policy Cmdlets

These are the most commonly used policy cmdlets. Other aspects of Teams, like Live Events, are controlled by other policy cmdlets (*-CsTeamsMeetingBroadcastPolicy).

Grant cmdlets are available to assign policies to users. For example, I don’t like the idea of Teams presenting end users with feedback surveys (where the data flows to Microsoft without any tenant oversight), and the easiest way to stop this happening is to create a new feedback policy and use the Grant-CsTeamsFeedbackPolicy cmdlet to assign the policy to users.

Looking Forward

PowerShell is messy within Office 365. Too many modules, too many inconsistencies across modules, too little cooperation between engineering groups. It would be nice if the Teams developers took the initiative to unify the Teams cmdlets into one module. Maybe it will happen when Skype for Business Online bites the bullet in 2021. Only two more years to wait.