Skip to content

Instantly share code, notes, and snippets.

@mozziemozz
Last active April 8, 2023 06:55
Show Gist options
  • Save mozziemozz/c3057fba9da212578601e0b12b0a95bf to your computer and use it in GitHub Desktop.
Save mozziemozz/c3057fba9da212578601e0b12b0a95bf to your computer and use it in GitHub Desktop.
$teamsRegion = Read-Host "Enter your Teams region. E.g. 'emea'"
function Get-UserToken {
param (
)
# Tenant name or id
$tenantName = Read-Host "Enter your primary M365 domain or *.onmicrosoft.com name."
Add-Type -AssemblyName System.Web
$WebResource = "https://teams.microsoft.com/"
$redirectUrl = "https://teams.microsoft.com/go"
$client_id = "5e3ce6c0-2b1f-4285-8d4b-75ee78787346"
$scope = "48ac35b8-9aa8-4d74-927d-1f4a14a0b239%2F.default%20openid%20profile"
$nonce = [guid]::NewGuid().GUID
$url = "https://login.microsoftonline.com/$tenantName/oauth2/authorize?response_type=token&scope=$scope&redirect_uri=" +
[System.Web.HttpUtility]::UrlEncode($redirectUrl) +
"&client_id=$client_id" +
"&prompt=login" + "&nonce=$nonce" + "&resource=" + [System.Web.HttpUtility]::UrlEncode($WebResource) + "&state=12345" #here
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object -TypeName System.Windows.Forms.Form -Property @{ Width = 440; Height = 640 }
$web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property @{ Width = 420; Height = 600; Url = ($url) }
$DocComp = {
$Global:uri = $web.Url.AbsoluteUri
if ($Global:Uri -match "error=[^&]*|access_token=[^&]*") { $form.Close() }
}
$web.ScriptErrorsSuppressed = $true
$web.Add_DocumentCompleted($DocComp)
$form.Controls.Add($web)
$form.Text = "AAD User Login"
$form.Add_Shown({ $form.Activate() })
$form.ShowDialog() | Out-Null
$Script:Token = [Web.HttpUtility]::ParseQueryString(($web.Url -replace '^.*?(access_token.+)$','$1'))['access_token']
$AADBearerToken = ('Bearer {0}' -f $Script:Token)
$Headers = @{
Authorization = $AADBearerToken
}
}
function Get-Buddies {
param (
)
$URL = "https://teams.microsoft.com/api/mt/$teamsRegion/beta/contacts/buddylist/"
$ListID = ((Invoke-RestMethod -Uri $URL -Method GET -Headers $Headers -ContentType "application/json").value | Where-Object{$_.displayname -like "OtherContacts"}).id
$URL = "https://teams.microsoft.com/api/mt/$teamsRegion/beta/contacts/buddylist/$ListID"
$buddies = Invoke-RestMethod -Uri $URL -Method GET -Headers $Headers -ContentType "application/json"
}
$outlook= NEW-OBJECT -ComObject Outlook.Application
$contacts = $Outlook.session.GetDefaultFolder(10).items
$allTeamsContactDetails = @()
foreach ($contact in $Contacts) {
$contactNumbers = $contact.psobject.Properties | Where-Object {$_.Name -match "TelephoneNumber" -and $_.Value -notlike ""}
foreach ($number in $contactNumbers) {
$contactDetails = NEW-OBJECT -TypeName psobject
$contactDetails | Add-Member -MemberType NoteProperty -Name "FullName" -Value "$($contact.FirstName) $($contact.LastName)"
$contactDetails | Add-Member -MemberType NoteProperty -Name "CompanyName" -Value $contact.CompanyName
$contactDetails | Add-Member -MemberType NoteProperty -Name "JobTitle" -Value $contact.JobTitle
if ($contactDetails.CompanyName) {
$contactDetails.CompanyName = $contactDetails.CompanyName.Replace("(","").Replace(")","")
}
if ($contactDetails.JobTitle) {
$contactDetails.JobTitle = $contactDetails.JobTitle.Replace("(","").Replace(")","")
}
if (!$contactDetails.FullName) {
$contactDetails.FullName = $contactDetails.CompanyName
}
$contactDetails.FullName = $contactDetails.FullName.Replace("(","").Replace(")","").Trim()
$phoneNumber = $number.Value.Replace(" ","").Replace("-","").Replace("(0)","")
$contactDetails | Add-Member -MemberType NoteProperty -Name "PhoneNumber" -Value $phoneNumber
$numberType = $number.Name.Replace("TelephoneNumber","")
$contactDetails.FullName = "$($contactDetails.FullName) [$numberType]"
$allTeamsContactDetails += $contactDetails
}
}
. Get-UserToken
. Get-Buddies
$existingBuddies = $buddies.value.buddies
$addBuddiesURL = "https://teams.microsoft.com/api/mt/$teamsRegion/beta/contacts/buddylist/$ListID/managebuddies?migrationRequested=true&federatedContactsSupported=true"
foreach ($contact in $allTeamsContactDetails) {
$contact
Start-Sleep 1
if ($existingBuddies.mri.Replace("4:","") -notcontains $contact.PhoneNumber -or $existingBuddies.displayName -notcontains $contact.FullName) {
Write-Host "No Teams contact found for $($contact.FullName) or $($contact.PhoneNumber)" -ForegroundColor Green
$payload = @"
{"add":[{"mri":"4:$($Contact.PhoneNumber)","displayName":"$($Contact.FullName)","phone":"$($Contact.PhoneNumber)","companyName":"$($Contact.CompanyName)","jobTitle":"$($Contact.JobTitle)"}]}
"@
Invoke-RestMethod -Uri $addBuddiesURL -Body $payload -Method Post -Headers $Headers -ContentType "application/json; charset=utf-8"
}
else {
Write-Host "Teams contact for $($contact.FullName) or $($contact.PhoneNumber) already exists" -ForegroundColor Yellow
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment