Entra / Microsoft 365 · Teams
Send Teams chat with many mentions
Demonstrates sending a Teams chat via Microsoft Graph with multiple @mentions, emojis, and inline images.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes Chat.ReadWrite, User.Read.All -NoWelcome
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
Connect-MgGraph -Scopes Chat.ReadWrite, User.Read.All -NoWelcome# Get details of the signed in user$SendingUser = (Get-MgContext).Account$SendingUserId = (Get-MgUser -UserId $SendingUser).IdWrite-Host ("Chats will be sent by {0}" -f $SendingUser)[array]$Modules = Get-Module | Select-Object -ExpandProperty NameIf ("ExchangeOnlineManagement -notin $Modules") {Connect-ExchangeOnline -SkipLoadingCmdletHelp}$GroupName = "Emergency Contacts"# Download the icon we want to use if it's not already available - use your own image if you want$WebImage = "https://i0.wp.com/office365itpros.com/wp-content/uploads/2024/04/Warning.jpg"# Download target is in user download folder$ContentFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\Warning.jpg"If (!(Get-Item -Path $ContentFile -ErrorAction SilentlyContinue)) {Invoke-WebRequest $WebImage -OutFile $ContentFile}# Target group to receive chat messages$TargetGroupforChats = "Information Quality and Accuracy"$Team = Get-MgTeam -Filter "displayName eq '$TargetGroupforChats'"If ($Team) {[array]$TeamMembers = (Get-MgGroupMember -GroupId $Team.Id).IdWrite-Host ("Found {0} members in the {1} team" -f $TeamMembers.Count, $GroupName)} Else {Write-Host ("Can't find the target team ({0}) to send chats" -f $GroupName)Break}# Find the group to use for contact information$Group = Get-MgGroup -Filter "displayName eq '$GroupName'"If (!($Group)) {Write-Host ("Can't find the {0} group with emergency contact information" -f $GroupName)Break}# Group owner is the primary contact$PrimaryContact = Get-MgGroupOwner -GroupId $Group.Id$PrimaryContactDetails = $PrimaryContact | Select-Object -ExpandProperty AdditionalProperties# Get the identifiers for the other contacts[array]$Contacts = Get-MgGroupMember -GroupId $Group.Id# Define the content of the chat message, starting with the imline image$Content = '<img height="200" src="../hostedContents/1/$value" width="200" style="vertical-align:bottom; width:200px; height:200px">'$Content = $Content + '<p><b>Warning!</b></p>'$Content = $Content + '<p><b>Immediate Action Required</b><p>Please contact the situation coordinator '# Create the mention for the primary contact$MentionedUserDetails = @{}$MentionedUserDetails.add("userIdentityType", "aadUser")$MentionedUserDetails.add("Id", $PrimaryContact.id)# Define a hashtable to point to the hash table holding the user details$MentionedUser = @{}$MentionedUser.add("user", $MentionedUserDetails)$MentionPrimaryContact = @{}$MentionPrimaryContact.add("Id","0")$MentionPrimaryContact.add("Mentiontext",$PrimaryContactDetails.displayName)$MentionPrimaryContact.add("Mentioned", $MentionedUser)[array]$MentionIds = $MentionPrimaryContact# add the contact mention to the message text$PrimaryContactMention = ('<at id="0">{0}</at> for more information. Contact details are available in the profile card.<p>' -f $PrimaryContactDetails.displayName)$Content = $Content + $PrimaryContactMention$Content = $Content + "<p><p><u>Location-specific contacts are:</u></p>"# Loop through the users in the $Contacts array to add them to the message[int]$i = 0ForEach ($Contact in $Contacts) {$i++$ContactName = $Contact.additionalProperties.displayName$ContactLocation = $Contact.additionalProperties.officeLocation$MentionedUserDetails = @{}$MentionedUserDetails.add("userIdentityType", "aadUser")$MentionedUserDetails.add("Id", $Contact.Id)$MentionedUser = @{}$MentionedUser.add("user", $MentionedUserDetails)$MentionContact = @{}$MentionContact.add("Id",$i)$MentionContact.add("Mentiontext",$ContactName)$MentionContact.add("Mentioned", $MentionedUser)$MentionIds += $MentionContact$ContactLine = ('<p><at id="{0}">{1}</at> ({2})</p>' -f $i, $ContactName, $ContactLocation)$Content = $Content + $ContactLine}$Content = $Content + "<p>-------------------------------------------------------------------<p></p>"$Content = $Content + '<p><emoji alt="😎"></emoji>'# Create a hash table to hold the image content that's used with the HostedContents parameter. Hosted content# is stored by Teams in its store and includes images and code snippets. File attachments are in OneDrive# or SharePoint Online$ContentDataDetails = @{}$ContentDataDetails.Add("@microsoft.graph.temporaryId", "1")$ContentDataDetails.Add("contentBytes", [System.IO.File]::ReadAllBytes("$ContentFile"))$ContentDataDetails.Add("contentType", "image/jpeg")[array]$ContentData = $ContentDataDetails$Body = @{}$Body.add("content", $Content)$Body.add("contentType", 'html')# Loop through the set of team members and send a chat to each[int]$ChatMessagesSent = 0ForEach ($TeamUser in $TeamMembers) {# No need to chat with the sender, so ignore them if they're in the team membershipIf ($TeamUser -eq $SendingUserId) {Write-Host "Skipping sending chat to self"Continue}$User = Get-MgUser -UserId $TeamUser -Property id, displayName, userprincipalName, userType# Can't handle MTO accounts - communicate should be with their real accountIf ($User.UserPrincipalName -like "*#EXT*" -and $User.userType -eq "Member") {Write-Host ("Skipping MTO account {0}" -f $User.DisplayName)Continue}[array]$MemberstoAdd = $SendingUserId, $TeamUser[array]$Members = $nullForEach ($Member in $MemberstoAdd){$MemberId = ("https://graph.microsoft.com/v1.0/users('{0}')" -f $Member)$MemberDetails = @{}[array]$MemberRole = "owner"If ($User.userType -eq "Guest") {[array]$MemberRole = "guest"}$MemberDetails.Add("roles", $MemberRole.trim())$MemberDetails.Add("@odata.type", "#microsoft.graph.aadUserConversationMember")$MemberDetails.Add("user@odata.bind", $MemberId.trim())$Members += $MemberDetails}# Add the members to the chat body$OneOnOneChatBody = @{}$OneOnOneChatBody.Add("chattype", "oneOnOne")$OneOnOneChatBody.Add("members", $Members)# Set up the chat - if one already exists between these two participants, Teams returns the id for that chat$NewChat = New-MgChat -BodyParameter $OneOnOneChatBodyIf ($NewChat) {Write-Host ("Chat {0} available" -f $NewChat.id)} Else {Write-Host "Failed to create chat"}# Send the message to the chatWrite-Host ("Sending chat to {0}" -f $User.DisplayName)$ChatMessage = New-MgChatMessage -ChatId $NewChat.Id -Body $Body -Mentions $MentionIds `-HostedContents $ContentData -Importance UrgentIf ($ChatMessage) {Write-Host ("Chat sent to {0}" -f $User.DisplayName) -ForegroundColor Yellow$ChatMessagesSent++} Else {Write-Host ("Failed to send chat message to {0}" -f $User.DisplayName) -ForegroundColor Red}}Write-Host ("All done. {0} chat messages sent" -f $ChatMessagesSent)
Attribution
Author
Office365itpros