Ever found your self looking for a way to add a group of users to a team site and one or more channels in bulk? I was in that situation the other day and decided to see if there was an easy way to take care of it using PowerShell. The following script is what I came up with and is uses a yaml file as input to make it easy to use (would be a simple change to move over to json or csv if needed)
Here is an example of the input file
team: # Only name or id is needed. Note if there are multiple teams that start with the same name use the id
id:
name: Team Site A
users:
- email: user_a_email@company.com
channels:
- name: Channel A
- name: Channel B
enabled: false # Option field to enable/disable adding a user to a channel
- email: user_b_email@company.com
channels:
- name: Channel A
- name: Channel C
enabled: false # Option field to enable/disable adding a user to a channel
And here is the PowerShell script that does all the magic. Note: It supports the common parameters of WhatIf, Verbose, Information, and Debug to help with testing and troubleshooting.
[CmdletBinding(SupportsShouldProcess)]
param(
[string] $GroupName = $null,
[string] $GroupId = $null,
[string] $FileName = "users.yml"
)
if (-Not (Test-Path $FileName)) {
Write-Error "File '$FileName' was not found. Please check and try again... "
exit
}
if (Get-Module -ListAvailable -Name MicrosoftTeams) {
Write-Verbose "Microsoft Teams Module already Installed"
} else {
try {
Write-Verbose "Installing Microsoft Teams Module"
Install-Module -Name MicrosoftTeams -AcceptLicense -AllowClobber -Confirm:$False -Force
}
catch [Exception] {
$_.message
exit
}
}
if (Get-Module -ListAvailable -Name powershell-yaml) {
Write-Verbose "ConvetFrom-Yaml already installed"
} else {
try {
Write-Verbose "Installing ConvertFrom-Yml command"
Install-Module -Name powershell-yaml
}
catch {
$_.message
exit
}
}
Get-TeamsApp -ErrorAction SilentlyContinue -ErrorVariable errGetTeamsApp -OutVariable teamsApp | Out-Null
if ($errGetTeamsApp.Count -gt 0) {
Write-Verbose "Connecting to Teams"
Connect-MicrosoftTeams -WhatIf:$false
} else {
Write-Verbose "Already Connected to Teams"
}
$importData = (Get-Content -Path $FileName) | ConvertFrom-Yaml
if ($null -ne $importData.team) {
if ($null -ne $importData.team.name) { $GroupName = $importData.team.name }
if ($null -ne $importData.team.id) { $GroupId = $importData.team.id }
}
if ($null -eq $GroupName -and $null -eq $GroupId) {
Write-Warning "Please specify either a GroupName or GroupId."
exit
}
$team = $null
if (-Not [string]::IsNullOrEmpty($GroupName) -and [string]::IsNullOrEmpty($GroupId)) {
Write-Verbose "Looking for Team By Name: '$GroupName'"
$team = Get-Team -DisplayName $GroupName -ErrorAction SilentlyContinue
if ($team.GetType().IsArray) {
Write-Warning "Multiple Groups Returned with that name. Please specify a specific Group by using the GroupId parameter."
$team | Format-Table GroupId, DisplayName
exit
} elseif ($null -eq $team) {
Write-Warning "Unable to locate team '$GroupName'. Please verify and try again."
exit
} else {
$GroupId = $team.GroupId
}
}
if (-Not [string]::IsNullOrEmpty($GroupId) -and $null -eq $team) {
Write-Verbose "Looking for Team By ID: '$GroupId'"
$team = Get-Team -GroupId $GroupId -ErrorAction SilentlyContinue
if ($null -eq $team) {
Write-Warning "Unable to locate team based on Group Id '$GroupId'. Please verify and try again"
exit
}
}
if ([string]::IsNullOrEmpty($GroupId) -and [string]::IsNullOrEmpty($GroupName)) {
Write-Warning "Failed to find team. Please check GroupId '$GroupId' or GroupName '$GroupName' arguments and try again."
exit
}
Write-Information "Retrieving current list of users in team '$($team.DisplayName)"
$teamExistUsers = Get-TeamUser -GroupId $($team.GroupId)
Write-Host "Importing Users into '$($team.DisplayName)' [ID: $($team.GroupId)]"
Write-Host "----------------------------------------------------------------------------"
$users = $importData.users
foreach ($u in $users) {
if ([string]::IsNullOrEmpty($u.role)) { $u.role = "member" }
$userExists = $teamExistUsers | Where-Object { $_.User -eq $u.email }
if ($null -ne $userExists) {
Write-Host "User '$($u.email)' is already a member of team '$($team.DisplayName)'"
} else {
if ($PSCmdlet.ShouldProcess("Add-TeamUser", "Adding User '$($u.email)' to team '$($team.DisplayName)' as a '$($u.role)'")) {
Write-Host "Adding User '$($u.email)' to team '$($team.DisplayName)' as a '$($u.role)'"
Add-TeamUser -GroupId $($team.GroupId) -user $($u.email) -role $($u.role.ToLower()) -ErrorVariable errAddTeamuser | Out-Null
if ($errAddTeamUser.Count -gt 0) {
Write-Warning "`tFailed to add user to team..."
}
Write-Verbose "Sleeping for 30 seconds to allow changes to propogate..."
Start-Sleep -Seconds 30
}
}
foreach ($c in $u.channels) {
if ($null -ne $c.enabled -and $c.enabled -eq $false) {
Write-Host "`tAdding user to channel $($c.name) has been disabled. Skipping...."
Write-Debug ($c | Out-String)
continue
}
$teamChannel = Get-TeamChannel -GroupId $($team.GroupId) | Where-Object { $_.DisplayName -eq "$($c.name)" }
if ($null -ne $teamChannel) {
$userExistsChannel = Get-TeamChannelUser -GroupId $($team.GroupId) -DisplayName $($c.name) | Where-Object { $_.User -eq $u.email }
if ($null -ne $userExistsChannel) {
Write-Host "User '$($u.email)' is already a member of channel '$($teamChannel.DisplayName)"
} else {
if ($PSCmdlet.ShouldProcess("Add-TeamChannelUser", "Adding User '$($u.email)' to teams channel '$($teamChannel.DisplayName)' as a '$($u.role)'")) {
Write-Host "`tAdding User '$($u.email)' to teams channel '$($teamChannel.DisplayName)' as a '$($u.role)'"
Add-TeamChannelUser -GroupId $($team.GroupId) -DisplayName $($teamChannel.DisplayName) -user $($u.email) -ErrorAction SilentlyContinue -ErrorVariable errAddUserTeamsChannel | Out-Null
if ($errAddUserTeamsChannel.Count -gt 0) {
Write-Warning "Failed to add user to teams channel: $($c.name). Please verify the channel exists"
}
}
}
} else {
Write-Warning "`tFailed to find channel '$($c.name)'...."
}
}
}
Write-Host "----------------------------------------------------------------------------"
write-Host "Done..."