Get-TeamsMembership.ps1


<#PSScriptInfo
 
.VERSION 1.0
 
.GUID 5afc96b9-693c-430d-a0e6-773a20377212
 
.AUTHOR Paul Robichaux
 
COMPANYNAME Quadrotech Solutions
 
.COPYRIGHT (c) 2018 Quadrotech Solutions Inc.
 
.TAGS Teams
 
.LICENSEURI
http://creativecommons.org/licenses/by-nc/4.0/
 
 
.RELEASENOTES
07-July-2018: 1.0. Initial release.
 
 
 
#>


<#
 
.DESCRIPTION
This script will show which Teams objects the specified user is a member or owner of.
It can optionally clone membership from one user to another, so the target user has the same Teams memberships as the source user.
    
If you're not already connected to an Exchange Online PowerShell session, the script will attempt to connect you. It requires the Connect-ExOPSSession cmdlet, which means you need the Exchange Online Remote PowerShell module.
 
 
#>
 
<#
.Synopsis
Get-TeamsMembership
 
See and manage Microsoft Teams membership for the selected user.
 
Paul Robichaux
Quadrotech Solutions
paul.robichaux@quadro.tech
 
 
    THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
    RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
 
    Version 1.0, July 6th, 2018
     
.LINK
http://www.quadrotech-it.com
    
.Parameter $Identity
    Mandatory: User whose Teams membership you want to see. May be a display name or primary SMTP address.
    You may also be able to use the UPN if it matches the primary SMTP address.
.Parameter $Credential
    Optional PSCredential object to use when connecting to the service
.Parameter $TargetUser
    Optional: specify the UPN or primary SMTP of the user who you want to clone the source user's Teams membership or ownership to.
.Parameter $Clone
    Optional switch indicating that you want to clone membership from the source user to the target.
.Parameter $CloneOwner
    Optional switch indicating that you want to add the target user as an owner of any Team that the source user is a member of.
.Parameter $WhatIf
    Seriously, y'all know what this does.
.Example
    .\Get-TeamsMembership.ps1 -Identity paul.robichaux@quadrotech-it.com
.Example
    .\Get-TeamsMembership.ps1 -Identity paul.robichaux@quadrotech-it.com -TargetUser New.Employee@quadro.tech -Clone -WhatIf
#>


[CmdletBinding()]Param 
(
  [Parameter(Mandatory=$true, Position=1)][string]$Identity,
  [String]$targetUser,
  [Parameter(ValueFromPipeline=$false)][switch]$Clone,
  [Parameter(ValueFromPipeline=$false)][switch]$CloneOwner,
  [Parameter(ValueFromPipeline=$false)][switch]$WhatIf
)


# TODO: implement ownership changes
# TODO: -whatif for ownership changes
# TODO: more error handling
# TODO: switches for member only, owner only

# if we are cloning, verify that we have a target
if (($clone) -or ($cloneOwner)) {
    if (($targetUser -eq "") -or ($targetUser -eq $NULL)) {
        throw "You must specify a target user when using the -Clone or -CloneOwner switches."
    }
}

# See if we're already connected to ExO. If not, connect to Exchange Online.
# This is a little sloppy, as it requires the dedicated ExO PS module.
# TODO: add credential support instead of making the user plug one in
# TODO: use Michel de Rooij trick to locate and load module if necessary.
try
{
   Get-OrganizationConfig  -ErrorAction Stop > $null
}
catch 
{
    Write-Output "Connecting to Office 365..."
    Connect-ExOPSSession 
}

# The identity we get might be a display name or a primary SMTP. If it's a display name,
# get the primary SMTP because we'll need it later.
if ($identity.IndexOf("@") -lt 1) {
   $identity = (Get-Mailbox -id $identity).PrimarySMTPAddress
}

# Get the list of all the Teams objects
$teamlist = Get-UnifiedGroup | where {$_.welcomemessageenabled -eq $false}

# Set up the progress bar
$progDelta = ($teamlist.count) / 100
$checkCount = 0

# Iterate through all the Teams and check their membership and ownership.
# The call to Get-UnifiedGroup
foreach ($t in $teamlist) {
    Write-Progress -Activity "Checking Team membership" -status "checking $t" -percentComplete $checkCount
    $checkCount += $progDelta
    $teamOwner = Get-UnifiedGroupLinks -id $t.id -LinkType Owners

    if (($teamOwner.primarySMTPAddress -eq $identity) -or ($teamOwner.name -eq $identity)) {
        $obj = New-object -typename PSObject ` |
        Add-Member -memberType NoteProperty -name DisplayName -value $t.displayName -passthru | `
        Add-Member -memberType NoteProperty -name MembershipType -value "Owner" -passthru | `
        Add-Member -memberType NoteProperty -name TeamName -value $t.name -passthru | `
        Add-Member -memberType NoteProperty -name Description -value $t.notes -passthru 
        Write-Output $obj
        }
        
    if ($cloneOwner) {
            try {
                if ($whatif) {            
                    Add-UnifiedGroupLinks -id $t.name -LinkType Owner -links $targetUser -WhatIf -ErrorAction Stop
                } else {
                    Add-UnifiedGroupLinks -id $t.name -LinkType Owner -links $targetUser -ErrorAction Stop
                    }
                }
            catch {
                Write-Error "Couldn't add user $targetUser as owner of Team $t"
            }
        }

    $teamuser = Get-UnifiedGroupLinks -id $t.id -LinkType Members
    if (($teamuser.primarySMTPAddress -eq $identity) -or ($teamUser.name -eq $identity)) {
        if ($clone) {
            try {
                if ($whatif) {
                    Add-UnifiedGroupLinks -id $t.name -LinkType member -links $targetUser -whatif -ErrorAction Stop
                } else {
                    Add-UnifiedGroupLinks -id $t.name -LinkType member -links $targetUser -ErrorAction Stop
                }
                }
            catch {
                Write-Error "Couldn't add user $targetUser to Team $t"
            }
        }
        $obj = New-object -typename PSObject ` |
        Add-Member -memberType NoteProperty -name DisplayName -value $t.displayName -passthru | `
        Add-Member -memberType NoteProperty -name MembershipType -value "Member" -passthru | `
        Add-Member -memberType NoteProperty -name TeamName -value $t.name -passthru | `
        Add-Member -memberType NoteProperty -name Description -value $t.notes -passthru 
        Write-Output $obj
        }
}