Skip to the main content.

ScriptRunner Blog

Graph PowerShell and Microsoft Teams – Part 3 of our series

Table of contents

Post Featured Image

Damian shares his knowledge about Microsoft Graph. His third article goes into detail about teams and introduces the Microsoft.Graph.Teams module. Learn how and when to use the sub-module.  

 

Further exploration

In the first two articles in this series, we explored Graph PowerShell and its wide array of sub-modules and cmdlets and then we covered the uses of Graph PowerShell and Exchange Online. Proceeding forward, we now explore Microsoft Teams and Graph PowerShell and in doing so, we find a different setup. The biggest is that we have a dedicated sub-module called Microsoft.Graph.Teams which has hundreds of different cmdlets. We also find commonalities where 'Teams' cmdlets exist outside of this code sub-module:

  • Graph.Compliance
  • Graph.Reports
  • Graph.Security
  • Graph.Teams
  • Graph.Users.Actions
  • Graph.Users.Functions
  • MicrosoftGraph

We can run a quick bit of PowerShell to find any cmdlet with Team in it and get a count by sub-module:


$uniqueTeamsCmdletSources = Get-Command *team* | Where-Object Source -Like *graph* | Sort-Object Source -Unique
$uniqueTeamsCmdletSources.Source |
ForEach-Object {
Write-Host $_ -ForegroundColor Green -NoNewline
Write-Host ' - ' -NoNewline
Write-Host "$((Get-Command *team* -Module $_).Count)"
}

Yielding this:

01_cmdlet count

Cmdlet count per sub-module

Now the Microsoft.Graph.Teams sub-module does have more cmdlets, which do not have the noun 'Team' in them and indeed it has 654 total cmdlets. This leaves 121 cmdlets without that noun. Confirmation:


(Get-Command -Module Microsoft.Graph.Teams | Where-Object Name -NotLike *team*).Count

 

Microsoft Teams PowerShell tasks

As we did with Exchange Online, here we will quickly cover some of the common tasks that could be accomplished with the dedicated Microsoft Teams PowerShell Module.

  • Auto attendant
  • Meeting configuration
  • Dial plan
  • Dial-in conference
  • Team user settings
  • Teams shifts
  • Guest configuration
  • Granting access
  • Channel policies
  • Call policies
  • Emergency policies
  • Meeting policies
  • Shifts configuration
  • and much more

 

 Scoping permissions

Although this was covered in the first and second articles in this series, it bears repeating that when using Graph PowerShell, we need to scope permissions properly to use the Teams cmdlets.


$AllCmdlets = @()
Foreach ($Cmdlet in $GraphTeamsCmdlets) {
Try {
$Line = Find-MgGraphCommand $Cmdlet.Name -ERRORACTION STOP |
Select Command,Method,URI,Permissions
} Catch {
}
$AllCmdlets += $Line
}
$AllCmdlets |
Select Command,Permisions

Yielding this:

02_permissions needed

Truncated list of permissions needed

A long list of permissions is needed to run the myriad of cmdlets in the Teams sub-module of Graph. You can download the full output of this file from here.

We can also pull a summary of all delegated Teams permissions using a simple one-liner:


Find-MgGraphPermission teams -PermissionType Delegated

03_list of permissions teams graph

List of permissions for Teams cmdlets in Graph

 

Breaking down the differences

Well, all these cmdlets are well and good until an Administrator needs to perform a task and has to decide what module to perform a task in. So how should an administrator approach this module? One way is to look at the cmdlets in bunches, perhaps by verbs or nouns. If one wants to perform a particular task, like manage Team reactions, then a noun search would be better. Below we can example these groups by nouns to get an idea what is present in Microsoft Teams vs. Microsoft.Graph.Teams.

 

Example differences

When comparing the types of cmdlets, versus what is present in each module, we see cat differences in the types/number of cmdlets:

04_comparing groups of cmdlets

Comparison of available cmdlets

You can see a breakdown of some cmdlet groups for comparison. The examples above are done by keyword – 'clear', team reactions and dial.

Going forward, those new to Microsoft.Graph.Teams should get a full list of cmdlets and breakdown what is familiar to them in terms of the cmdlets nouns. By doing so they might be able to discern cmdlets to use for their management tasks. Once identified, then review the help and examples for each cmdlet to begin building one-liners and scripts using these newly discovered cmdlets.

 

Practical uses of Teams

Discussing cmdlets and how they are groups can be interesting for those exploring what can be manage in Microsoft Teams with Graph PowerShell, but being able to translate into useable code is by far the most valuable activity. In the below section we will walk through some example scenarios where Graph PowerShell is of use to Administrators.

 

Team membership

Combining cmdlets like these three: Get-MgTeam, Get-MgUser, and Get-MgUserJoinedTeam, we can build a script that verifies Microsoft Team memberships. Why would we want to do this? Some sample scenarios would be a tenant-to-tenant migration where we need to validate Team memberships were populated by an external process. Perhaps to validate that at members of a group are members of their respective Teams.

 

Single user


Get-MgUserJoinedTeam -UserId damian@powershellgeek.com

 

Multiple users


Get-MgUser | ForEach-Object {
Write-Host "$($_.DisplayName)" -ForegroundColor Green
$Groups = Get-MgUserJoined
Team -UserId $_.Id
If ($Groups.Count -eq 0 ) {
Write-host 'No Groups' -ForegroundColor Yellow
} Else {
$Groups
}
}

 

Members of a Team


Get-MgTeamMember -TeamId cfdba387-1319-4f6b-a883-8700046f07e7

05_list of members in a team

List of members in a Team (default view)

 


$Members | Format-List

06_additional properties

Additional properties

Notice that each member of the Team has a property called 'additional properties' and inside of this, we see the 'userId' key/value pair.

Now that we have a list of members, we can pull that user's Id which could then in turn be used in a lookup of the full user account:


$Members.AdditionalProperties.userId

Notice that 'userId' is actually case-sensitive and is something that may be worth remembering for future properties of Graph objects. We can now loop this into finding all user properties for group members:


$Members.AdditionalProperties.userId | ForEach-Object { Get-MgUser -UserId $_ }

07_list of users

List of users, their Ids, mail address and UserPrincipalNames (UPN) 

 

Members of all groups


Get-MgTeam | ForEach-Object {
Write-Host "$($_.DisplayName)" -ForegroundColor Green
$Members = Get-MgTeamMember -TeamId $_.id
$Members.AdditionalProperties.userId |
ForEach-Object {
Get-MgUser -UserId $_
}  
}

 

Channel management

Another area where the cmdlets differ between the modules is Channel management where the Microsoft Teams module has 14 cmdlets with the noun 'channel' in them whereas the Microsoft.Graph.Teams PowerShell module has 283 cmdlets:

08_sample of cmdlets

A small sampling of Teams cmdlets, focused on the noun 'channel'

Among these cmdlets, we will see many similarities:

 

Example – Managing members in Teams

Teams


Add-TeamChannelUser, Get-TeamChannelUser and Remove-TeamChannelUser

 

Graph


Add-MgTeamChannelMember, Add-MgTeamPrimaryChannelMember, Add-MgTeamworkDeletedTeamChannelMember, Get-MgGroupTeamChannelMember, Get-MgGroupTeamChannelMemberCount, Get-MgGroupTeamPrimaryChannelMember, Get-MgGroupTeamPrimaryChannelMembe rCount, Get-MgTeamChannelMember, Get-MgTeamChannelMemberCount, Get-MgTeamPrimaryChannelMember, Get-MgTeamPrimaryChannelMemberCount Get-MgTeamworkDeletedTeamChannelMember, Get-MgTeamworkDeletedTeamChannelMemberCount, New-MgGroupTeamChannelMember, New-MgGroupTeamPrimaryChannelMember, New-MgTeamChannelMember, New-MgTeamPrimaryChannelMember, New-MgTeamworkDeletedTeamChannelMember, Remove-MgGroupTeamChannelMember, Remove-MgGroupTeamPrimaryChannelMember, Remove-MgTeamChannelMember, Remove-MgTeamPrimaryChannelMember, Remove-MgTeamworkDeletedTeamChannelMember, Update-MgGroupTeamChannelMember, Update-MgGroupTeamPrimaryChannelMember, Update-MgTeamChannelMember, Update-MgTeamPrimaryChannelMember and Update-MgTeamworkDeletedTeamChannelMember

What we see is that the Graph PowerShell cmdlets are more numerous, and more laser focused on certain aspects of user memberships in a Team Channel and also the fact that users are called members in the cmdlets whereas the same nomenclature in Teams refers to users as 'users' not members.

 

Pull Team channel memberships

First, we need an Id of the Team where we are getting the Channel memberships of:


Get-MgTeam

Copy the Id of the Team and then get a list of channels:


Get-MgTeamChannel -TeamId cfdba387-1319-4f6b-a883-8700046f07e7

Copy the Id of the channel and now pull members of that channel:


Get-MgTeamChannelMember -ChannelId 19:1b01cc16e436489dbf22462dfce1443d@thread.skype -TeamId cfdba387-1319-4f6b-a883-8700046f07e7

What if we want a list of all members, of all Team / channels?


$Teams = Get-MgTeam | Select DisplayName,Id
Foreach ($Team in $Teams) {
$Channels = Get-MgTeamChannel -TeamId $Team.Id
Foreach ($Channel in $Channels) {
$AllMembers = $Null
$AllMembers = @()
$JoinedMembers = $Null
$JoinedMembers = @()
$Members = Get-MgTeamChannelMember -ChannelId $Channel.Id -TeamId $Team.Id
Write-Host "$($Team.DisplayName)" -ForegroundColor Green -NoNewline
Write-Host " / $($Channel.DisplayName) / " -ForegroundColor Yellow -NoNewLine
$MemberCount = $Members.Count
If ($MemberCount -gt 2) {
Foreach ($Member in $Members) {
$AllMembers += $Member.AdditionalProperties.email
}
$JoinedMembers = $AllMembers -join ','
$JoinedMembers
} Else {
Write-Host "$($Member.AdditionalProperties.email)"
}
}
}

Running this code will provide these results:

09_consent to permissions

Consent to permissions

Note that you will need to consent to the these permissions to make it work: Team.ReadBasic.All,ChannelMember.Read.All.

 

Creating new Teams

In this example we have a consulting firm that wants to create a new team each time a client is on-boarded and needs assistance. We can use PowerShell to create the Team, create channels and add members to each as needed for the project work to occur.

First, we have a CSV input file to be used for configuration of the new teams:


Name, Description, AllowAddRemoveApps, AllowCreatePrivateChannels, AllowCreateUpdateChannels, AllowDeleteChannels, AllowCreateUpdateRemoveConnectors, AllowCreateUpdateRemoveTabs, Guest-AllowCreateUpdateChannels, Guest-AllowDeleteChannels
"Project Falcon","Falcon, llc - client team",$False,$True,$True,$False,$True,$False,$False,$False
"Big Box, Inc.","Big Box, Inc. - Banking Industry",$False,$True,$True,$True,$True,$False,$False,$False

Using the PowerShell code block below, we can create the new Teams:


Foreach ($Team in $Teams) {
$params = @{
"template@odata.bind" = "https://graph.microsoft.com/v1.0/teamsTemplates('educationClass')"
DisplayName = $Team.Name
Description = $Team.Description
Visibility = $Team.visibility
MemberSettings = @{
AllowAddRemoveApps = $Team.allowAddRemoveApps
AllowCreatePrivateChannels = $Team.AllowCreatePrivateChannels
AllowCreateUpdateChannels = $Team.allowCreateUpdateChannels
AllowCreateUpdateRemoveConnectors = $Team.allowCreateUpdateRemoveConnectors
AllowCreateUpdateRemoveTabs = $Team.allowCreateUpdateRemoveTabs
AllowDeleteChannels = $Team.allowDeleteChannels
}
GuestSettings = @{
AllowCreateUpdateChannels = $Team.AllowCreateUpdateChannels
AllowDeleteChannels = $Team.AllowDeleteChannels
}
}

Try {
New-MgTeam -BodyParameter $params -ErrorAction STOP
} Catch {
Write-Host 'Failed to create team: ' -ForegroundColor Red -NoNewline
Write-Host "Error message - $_.Exception.Message" -ForegroundColor Yellow
}
}

After the code is run, no feedback is provided, so we will need to run Get-MgTeam to validate the creation:

10_new teams

New Teams are present in the red rectangle

Then we need some sort of input CSV for channels:


Team,ChannelName,Members,Description,membershipType
"HR Department",InternalProject-Vision,,"Effort to upgrade ERM app.",standard
"HR Department",InternalProject-Money,,"Effort to improve salaries.",private

Using this CSV, we can run the below block of PowerShell code:


Foreach ($Channel in $TeamsChannels) {
$teamId = (Get-MgTeam | Where-Object DisplayName -eq $Channel.Team).Id
$params = @{
"@odata.type" = "#Microsoft.Graph.channel"
MembershipType = $Channel.MembershipType
DisplayName = $Channel.ChannelName
Description = $Channel.Description
}
Try {
New-MgTeamChannel -TeamId $teamId -BodyParameter $params -ErrorAction STOP
} Catch {
Write-Host 'Failed to create channel in Team: ' -ForegroundColor Red -NoNewline
Write-Host "Error message - $_.Exception.Message" -ForegroundColor Yellow
}
}

Which yields these results from the sample CSV:

11_new channels

We see our two new channels that were added to the HR Team

 

Conclusion – Final thoughts

Microsoft Teams is as complex a product as Exchange Online to manage. There are hundreds of settings and nuances to be aware of and secure to make the most of Teams. In the Microsoft.Graph.Teams module we are able to provide some real management and processing of settings, teams, channels and users with PowerShell. There are some operations that are not possible, for example, there is no Grant set of cmdlets, so those operations will need to be performed in the Microsoft Teams PowerShell module. Now, like everything in Teams, it will take some time to get the permissions correct and some extra work will be needed to create BodyParameter settings to appropriately make changes. The hint here is to use help and practice some examples. In the end, this sub-module is quite useful and more so than the Exchange cmdlets in Graph – worth the time of Microsoft Teams administrators to learn.

 

 

Good2know

Microsoft Teams Cheat Sheet

Simplify and automate your Microsoft Teams management with our 8-page PowerShell cheat sheet for Microsoft Teams. This handy guide provides you with quick-reference cmdlets and code snippets to manage users, channels, policies and more with ease. Ideal for both beginners and seasoned administrators.

Teams-Cheat-Sheet2024

Your ultimate PowerShell Cheat Sheet

Unleash the full potential of PowerShell with our handy poster. Whether you're a beginner or a seasoned pro, this cheat sheet is designed to be your go-to resource for the most important and commonly used cmdlets.

The poster is available for download and in paper form.

PowerShellPoster2024

Get your PowerShell goodies here!

 

And do you know our webinars?

Transform your Microsoft Teams management with PowerShell

Managing Teams can be pretty time consuming. Have you ever wondered how you could optimize and reduce the arising workload?

The PowerShell module for Microsoft Teams is your key: it allows you to standardize and automate many repetitive tasks.

SR-Teams-Webinar-Blog-EN
For example:

  • Pushing messages to Teams channels
  • Finding teams with no owners
  • Bulk creation/deletion/archiving of teams
  • Adding/removing channels/users in all/selected teams
  • Managing security settings in all/selected teams
  • Creating reports of your current Teams infrastructure

This webinar is aimed at administrators, IT and DevOps professionals, PowerShell developers and IT managers.

 

Sign up for the next Teams webinar!

 

 

Related links

Related posts

12 min read

Licensing with Microsoft Graph PowerShell

The Microsoft Graph SDK PowerShell module is replacing two other modules. Learn more about connecting to Graph, finding...

12 min read

Are you ready for Destination Graph? – Azure AD and MSOnline module are deprecated by March 2024

With MS Online and Azure AD module deprecation, it's time to map previous tasks to new methods. We hope the following...

11 min read

Graph PowerShell SDK – Part 1 of our Graph series

Users will encounter one or two hurdles when they start using Graph. Damian Scoles wrote three articles provides help...

About the author: