Compare Microsoft Teams User List against a CSV file using PowerShell

I was looking for a why to bulk add a list of users into a Microsoft Teams Group however before I did that I wanted to compare the list of users in the team group with a list of users that I pulled from another system.¬† With this goal in mind I pulled together the following script.¬† It will load the list of users from a csv file, a list of users assigned to a team group, and them compare those two lists and output the result with an indication on a per user basis on if they are “In the List to Import”, “In the Team Site”, or “In Both Lists”

Example: Compare against the file “users.csv” and show the users that are in the file ONLY (and not already a member of the team site)

Compare-TeamUsers -GroupName "My Team Group Name" -FileName users.csv | ? { $_.State -eq "ImportListOnly" }

Here is the script

param(
    [string] $GroupName = $null,
    [string] $GroupId = $null,
    [string] $FileName = "users.csv"  # File needs at least 1 column called User per line with user's email address
)

# We need at least one of these to continue
if ($null -eq $GroupName -and $null -eq $GroupId) {
    Write-Warning "Please specify either a GroupName or GroupId."
    exit
}

# Lets validate that the CSV file exists
if (-Not (Test-Path $FileName)) {
    Write-Warning "File '$FileName' was not found. Please check and try again... "
    exit
}

# Do we have the Microsoft Teams PowerShell Module installed?
if (Get-Module -ListAvailable -Name MicrosoftTeams) {
    Write-Information "Microsoft Teams Module already Installed"
} 
else {
    try {
        Write-Information "Installing Microsoft Teams Module"
        Install-Module -Name MicrosoftTeams -AcceptLicense -AllowClobber -Confirm:$False -Force                
    }
    catch [Exception] {
        $_.message 
        exit
    }
}

# Are we connected and logged in?
if (-Not (Get-TeamsApp -ErrorAction SilentlyContinue -ErrorVariable errGetTeamsApp -OutVariable teamsApp)) {
    Write-Information "Connecting to Teams"
    Connect-MicrosoftTeams
} else {
    Write-Information "Already Connected to Teams"
}

# Lets get the group/team to work with
$team = $null
if (($null -ne $GroupName -and $GroupName.Length -gt 0) -and ($null -eq $GroupId -or $GroupId.Length -eq 0)) {
    Write-Information "Looking for Team: $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
    }
} 

# Did we find a valid group id
if ($null -ne $GroupId -and $GroupId.Length -gt 0) {
    Write-Information "Verifying Team Exists"
    $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
    }
} else {
    Write-Warning "Failed to find team. Please check GroupId '$GroupId' or GroupName '$GroupName' arguments and try again."
    exit
}

# Lets load the users from the file
$usersToImport = Import-Csv $FileName

# Lets load the users from the team
$usersInTeam = Get-TeamUser -GroupId $team.GroupId

# Lets compare the two lists
Write-Information "Comparing Users into '$($team.DisplayName)' ($team.GroupId)"

$userList = @()

foreach ($ui in $usersToImport) {
    $found = $false
    foreach ($ut in $usersInTeam) {
        if ($ut.User -eq $ui.User) {
            $ue = "" | select-object User, Name, Role, State; $ue.User = $ui.User; $ue.Name = $ut.Name; $ue.Role = $ut.Role; $ue.State = "Both"; $userList += $ue

            $found = $true
            break
        }
    }

    if (-Not $found) {
        $ue = "" | select-object User, Name, Role, State; $ue.User = $ui.User; $ue.Role = "member"; $ue.State = "ImportListOnly"; $userList += $ue
    }
}

foreach ($ut in $usersInTeam) {
    $found = $false
    foreach ($ui in $usersToImport) {
        if ($ut.User -eq $ui.User) {
            $found = $true
            break
        }
    }

    if (-Not $found) {
        $ue = "" | select-object User, Name, Role, State; $ue.User = $ut.User; $ue.Name = $ut.Name; $ue.Role = $ut.Role; $ue.State = "TeamsOnly"; $userList += $ue    
    }
}    

# List output the results -- note this object is "queryable" based on the the attributes: User, Name, Role, State
$userList