Home Automate Teams Channels creation/edit using Powershell
Post
Cancel

Automate Teams Channels creation/edit using Powershell

…when a teacher would like to have a Team with their students and would like to have a channel for each of them however each of the channels should be locked such that the teacher and the respective student can access it. No student should view the channel of another student but the teacher should be able to view every student’s channel.

Synopsis

This script will loop through the Teams listed in Teams.csv and for each of the members of the team, it will create private channels with the display name as the name of the member. Microsoft has some limitations put on the channel display names so if the member name contains any of the characters # % & * { } / \ : < > ? + | ‘ then the script removes those character(s). Also, if the member name is more than 50 characters, it will be trimmed to 50 characters. The channel will be private, accessible only to the member and the teacher specified in the $teacherEmail variable.

Ensure that the team groupIds are correct on the CSV, if incorrect team names are given, there will be no error messages returned. It will be simply ignored.

Pre-requisites

  • Add a column named groupId with the group ids of the teams to Teams.csv saved in the same directory as the script.
  • Save the teacher email to the $teacherEmail variable. Ensure that they are a member/owner of the team already.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<#
.SYNOPSIS
Create/Edit private channels within multiple Teams on Microsoft Teams.
.DESCRIPTION
This script will loop through the teams listed in $csvPath and for each of the 'members' of the teams, it will create private channels with the display name as the name of the respective member. If the customer chooses to edit the private channels within the Team(s) then it will loop through the existing private channels within the Team(s) and add the teacher emails in the $teacherEmails array.
Microsoft has setup limitations on the channel display names - if the member name contains any of the characters # % & * { } / \ : < > ? + | ' then the script will remove those character(s). Also, if the member name is more than 50 characters, it will be trimmed to 50 characters. The channel will be private, accessible only to the member and the teachers specified in the $teacherEmails array.

1. Ensure that the team groupIds are correct on the CSV, if incorrect groupIds are given, there will be no error messages returned. It will be simply ignored.
2. Before running the script as .\teamsChannels.ps1: Add a column named groupId with the group ids of the teams to the csv. Save the teacher emails to the $teacherEmail array.
3. Teacher emails in the $teacherEmail array must be 'owner's of the team(s) already - this is not handled by the script as of now as the requirement did not demand it. If they are not 'owner', there will be a channel created with the teacher name: which is not a desired output.
4. Sometimes there are exceptions returned and the script would fail to create channels but there is no issue with re-running the script in those cases.
5. You might want to try the extensive GraphAPI version here: https://code.nevinpjohn.in/teamsGraph

#>
using namespace System.Management.Automation.Host

$groups= @()
$teacherEmails = @('[email protected]', '[email protected]')
$csvPath = "Teams.csv" #path to the csv that have the groupId

function GetTeamGroupIds{
  Import-Csv $csvPath | ForEach-Object{
    Write-Host -ForegroundColor Yellow "Getting the team details of " $_."groupId"
    try {
      $groups += Get-Team -GroupId $_."groupId"
      Write-Host -ForegroundColor Green $_."groupId" "fetched."
    }
    catch {
      Write-Host -ForegroundColor Red
      Write-Host -ForegroundColor Red $_
    }
  }
  if ($groups.count -gt 0) {
    $confirmation = Read-Host $groups.groupId.count"teams to process, Took note of exceptions, if any? (y/n)"
    if ($confirmation -eq 'y') {
      Clear-Host
      Write-Host -ForegroundColor Green "Number of Teams to process : "$groups.groupId.count
      Create-Choice
    }
  }else {
    Write-Host $groups.count
    Write-Host -ForegroundColor Yellow "--------------------------------"
    Write-Host -ForegroundColor Red "No Teams found."
    Write-Host -ForegroundColor Yellow "--------------------------------"
  }
}

function CreatePrivateChannels{
  Write-Host -ForegroundColor Yellow "--------------------------------"
  Write-Host -ForegroundColor Blue "Trying to create Channels."
  Write-Host -ForegroundColor Yellow "--------------------------------"
  foreach ($group in $groups){
    Write-Host -ForegroundColor Magenta "Creating Channels for the Team:-"$group.DisplayName
    try {
      ($channelsList = Get-TeamChannel -GroupId $group.groupId -MembershipType Private) > $null
      ($teamMembersForThisGroup = Get-TeamUser -GroupId $group.groupId -Role member) > $null
      foreach ($member in $teamMembersForThisGroup){
        $channelExists = $false #assuming the channel does not exist, caution - this is not fool proof as it may result in creating duplicate channels IF the existing channel name for the member was formatted other than the method below. I can't think of a better method so that's that.
        $channelName = $member.name -replace "[#%&*{}/\\:<>?+|']" #can't contain the characters # % & * { } / \ : < > ? + | ' as per MS guidelines.
        $channelName = $channelName.subString(0, [System.Math]::Min(50, $channelName.Length)) #Names must be 50 characters or less as per the MS guidelines.
        $channelName = $channelName.Trim() #Remove whitespaces from the beginning and end of the string
        if ($channelsList.DisplayName.count -gt 0){
          Foreach ($existingChannel in $channelsList) {
            if ($existingChannel.DisplayName -eq $channelName) {
              $channelExists = $True
              break
            }
          }
        }
        if ($channelExists){
          Write-Host -ForegroundColor Blue "The channel name" $channelName "exists in" $group.DisplayName
        } else {
          Write-Host -ForegroundColor Yellow "The channel name" $channelName "does not exist in" $group.DisplayName "hence creating..."
          (New-TeamChannel -GroupId $group.groupId -DisplayName $channelName -MembershipType Private -Owner $member.User) > $null
          Start-Sleep -Seconds 3
        }
        #As per MS docs: To turn an existing Member into an Owner, first Add-TeamChannelUser -User foo to add them to the members list, then Add-TeamChannelUser -User foo -Role Owner to add them to owner list hence the two commands.
        foreach($teacherEmail in $teacherEmails){
          try{
            (Add-TeamChannelUser -GroupId $group.groupId -DisplayName $channelName -User $teacherEmail) > $null
            Start-Sleep -Seconds 3
            (Add-TeamChannelUser -GroupId $group.groupId -DisplayName $channelName -User $teacherEmail -Role Owner) > $null
            Write-Host -ForegroundColor Green "Added" $teacherEmail "as owner of the Channel name : " $channelName
          }
          catch{
            Write-Host -ForegroundColor Red $_
          }
        }
      }
      Write-Host -ForegroundColor Yellow "--------------------------------"
    }
    catch {
      Write-Host -ForegroundColor Red "-----------------------------------"
      Write-Host -ForegroundColor Yellow "Team name : " $group.DisplayName
      Write-Host -ForegroundColor Yellow "Channel name : " $channelName
      Write-Host -ForegroundColor Yellow "Member name : " $member.name
      Write-Host -ForegroundColor Yellow "Member name : " $member.User
      Write-Host -ForegroundColor Red $_
      Write-Host -ForegroundColor Red "-----------------------------------"
    }
  }
  $groups.clear()
  Disconnect-MicrosoftTeams
  Write-Host -ForegroundColor Green "Disconnected from Teams PS Session."
}

function EditPrivateChannels{
  Write-Host -ForegroundColor Yellow "--------------------------------"
  Write-Host -ForegroundColor Blue "Trying to Edit the Channels."
  Write-Host -ForegroundColor Yellow "--------------------------------"
  foreach ($group in $groups){
    Write-Host -ForegroundColor Magenta "Editing Private Channels for the Team:-"$group.DisplayName
    try {
      ($channelsList = Get-TeamChannel -GroupId $group.groupId -MembershipType Private) > $null
      if ($channelsList.DisplayName.count -gt 0){
        foreach ($channel in $channelsList){
          foreach($teacherEmail in $teacherEmails){
            (Add-TeamChannelUser -GroupId $group.groupId -DisplayName $channel.DisplayName -User $teacherEmail) > $null
            Start-Sleep -Seconds 3
            (Add-TeamChannelUser -GroupId $group.groupId -DisplayName $channel.DisplayName -User $teacherEmail -Role Owner) > $null
            Write-Host -ForegroundColor Green "Added" $teacherEmail "as owner of the Channel name : " $channel.DisplayName
          }
        }
      }else{
        Write-Host -ForegroundColor Yellow "No private channels found in:-" $group.DisplayName
      }

      Write-Host -ForegroundColor Yellow "--------------------------------"
    }
    catch {
      Write-Host -ForegroundColor Red "-----------------------------------"
      Write-Host -ForegroundColor Yellow "Team name : " $group.DisplayName
      Write-Host -ForegroundColor Yellow "Channel name : " $channe.DisplayName
      Write-Host -ForegroundColor Red $_
      Write-Host -ForegroundColor Red "-----------------------------------"
    }
  }
  $groups.clear()
  Disconnect-MicrosoftTeams
  Write-Host -ForegroundColor Green "Disconnected from Teams PS Session."
}

function Create-Choice {
    $EditPrivateChannels= [ChoiceDescription]::new('&EditPrivateChannels', 'EditPrivateChannels')
    $CreatePrivateChannels = [ChoiceDescription]::new('&CreatePrivateChannels', 'CreatePrivateChannels')
    $options = [ChoiceDescription[]]($EditPrivateChannels, $CreatePrivateChannels)
    $custChoice = $host.ui.PromptForChoice('What do you want to do?', '', $options, 1)
    switch ($custChoice) {
        0 { EditPrivateChannels }
        1 { CreatePrivateChannels }
    }
}

try{
  $auth = Connect-MicrosoftTeams
  GetTeamGroupIds
}
catch {
  Write-Host -ForegroundColor Red $_
}

This post is licensed under CC BY 4.0 by the author.