Entra / Microsoft 365 · Teams
Find Teams member-added events for monitored users
Detect when users matching a display name pattern are added to Teams membership and email a report of the events.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-ExchangeOnlineConnect-MgGraph -Scopes Mail.Send.Shared, Directory.Read.All
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
param([int] $LookbackDays = 7,[string] $StartDate = (Get-Date).AddDays(-$LookbackDays),[string] $EndDate = (Get-Date).AddDays(1))Function Add-MessageRecipients {# Function to build an addressee list to send email[cmdletbinding()]Param([array]$ListOfAddresses )ForEach ($SMTPAddress in $ListOfAddresses) {@{emailAddress = @{address = $SMTPAddress}}}}# Check if we can run an Exchange Online cmdlet. If we can, go on, else connect to Exchange OnlineIf ($Null -eq (Get-ConnectionInformation)) {Connect-ExchangeOnline}# Connect to the Graph# Scopes: Mail.Send.Shared required to send email from a shared mailbox# Directory.Read.All required to read user information from Entra IDConnect-MgGraph -Scopes Mail.Send.Shared, Directory.Read.All# Find users who have the string "Project" in their display name. This query excludes guest accounts and only finds accounts# with at least one assigned license.Write-Host "Finding user details to check"[array]$Users = Get-MgUser -Search "displayName:Project" -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel EventualIf (!($Users)) {Throw "No users found"}Write-Host ("Checking audit records for {0} users" -f $Users.count)# Build hash table of users that we want to check$UserLookup = @{}ForEach ($User in $Users) {$UserLookup.Add($User.UserPrincipalName, $User.DisplayName)}[array]$Records = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -Formatted -ResultSize 5000 `-RecordType MicrosoftTeams -Operations MemberAdded -SessionCommand ReturnLargeSetIf (!($Records)) {Throw "No records found"} Else {$Records = $Records | Sort-Object Identity -Unique}$Report = [System.Collections.Generic.List[Object]]::new()ForEach ($Rec in $Records) {$Role = $Null$AuditData = $Rec.AuditData | ConvertFrom-Json# Check the members noted as added to a groupForEach ($Member in $AuditData.Members) {If ($UserLookup[$Member.Upn]) {# Write-Host ("User {0} added to team {1}" -f $Member.DisplayName, $AuditData.TeamName)Switch ($Member.Role) {"1" { $Role = "Member" }"2" { $Role = "Owner"}"3" { $Role = "Guest" }}$ReportLine = [PSCustomObject]@{Date = $AuditData.CreationTimeUser = $Member.UpnName = $Member.DisplayNameTeam = $AuditData.TeamNameRole = $RoleAddedBy = $AuditData.UserId}$Report.Add($ReportLine)}}}# Uncomment if you want to see the output# $Report | Out-GridView$EmailRecipient = "Lotte.Vetler@Office365itpros.com"Write-Host ("Sending results with {0} monitored events to {1}" -f $Report.count, $EmailRecipient )# Send a message from the shared mailbox$MsgFrom = "Customer.Services@Office365itpros.com"# Add your recipient address here$ToRecipientList = @( $EmailRecipient )[array]$MsgToRecipients = Add-MessageRecipients -ListOfAddresses $ToRecipientList$MsgSubject = "Monitored User Additions to Team membership"$HtmlHead = "<h2>Monitored User Additions to Teams</h2><p>The following additions to Teams membership occurred for monitored user accounts.</p>"$HtmlBody = $Report | ConvertTo-Html -Fragment$HtmlMsg = "</body></html><p>" + $HtmlHead + $Htmlbody + "<p>"# Construct the message body$MsgBody = @{Content = "$($HtmlMsg)"ContentType = 'html'}$Message = @{subject = $MsgSubject}$Message += @{toRecipients = $MsgToRecipients}$Message += @{body = $MsgBody}$Params = @{'message' = $Message}$Params += @{'saveToSentItems' = $True}$Params += @{'isDeliveryReceiptRequested' = $True}# And send the message using the parameters that we've filled inSend-MgUserMail -UserId $MsgFrom -BodyParameter $ParamsWrite-Host "All done!"
Parameters
ParameterDefaultNotes
-LookbackDays7Number of days back to search Teams MemberAdded audit records.-StartDate(Get-Date).AddDays(-7)Start of the audit log search window.-EndDate(Get-Date).AddDays(1)End of the audit log search window.Attribution
Author
Office365itpros