PowerShell Script to add users to Microsoft Team Sites and Channels in bulk

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..."