Get Online Presence Status of Microsoft Teams Users using PowerShell

Microsoft Teams provides a collaborative workspace environment within Microsoft 365/Office 365 services. This is a central hub for personal (one-to-one chat) and group chat conversations, making audio and video calls, and file sharing.

We can check a user’s online presence status in Teams client (on the desktop, the web, iOS, and Android). This will help us to ensure whether the user is online (Available) or offline (Away). In this post, we will explore how to find a user’s online status using Microsoft Graph API with PowerShell. 

Summary

Get Graph API Access Token

Microsoft Graph supports the Get presence API to check your own presence status and we can use the same API to get online presence status for another user. This operation requires OAuth Access Token with the Delegated permission “Presence.Read.All“.

We can use the MSAL.PS library to acquire access tokens with Delegated permissions. Run the following command in PowerShell to install this module. You can close and re-open the PowerShell once you installed the module.

Install-Module -Name MSAL.PS

Run the following commands to get Access Token on behalf of a user.

#Provide your Office 365 Tenant Domain Name or Tenant Id
$TenantId = "contoso.onmicrosoft.com"
#$TenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
     
#Used the Microsoft Graph PowerShell app id. You can create and use your own Azure AD App id if needed.
$AppClientId="14d82eec-204b-4c2f-b7e8-296a70dab67e"  

$MsalParams = @{
    ClientId = $AppClientId
    TenantId = $TenantId    
    Scopes   = "https://graph.microsoft.com/Presence.Read.All"    
}

$MsalResponse = Get-MsalToken @MsalParams
$AccessToken  = $MsalResponse.AccessToken

Get the presence status of a single user

The below commands retrieve the availability status of the given Microsoft Teams user. The successful API call returns the user’s availability status (ex: Available, Busy, Away) and activity state (ex: Available, InACall, InAConferenceCall, Away).

Note: As of now, the API only works with the user’s ObjectId (User Object GUID) and it will not work with the user’s UserPrincipalName (UPN). You will get the availability status as “PresenceUnknown” when you provide an unknown or invalid User Id.

#Provide your access token. 
#$AccessToken="eyJ0eXAiOiJ......" 
 
#Form request headers with the acquired $AccessToken
$headers = @{'Content-Type'="application\json";'Authorization'="Bearer $AccessToken"}

#Provide the required user's ObjectId to check the presence status
$UserId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 
#This request gets the online presence status of the given user
$ApiUrl = "https://graph.microsoft.com/v1.0/users/$UserId/presence"

#Get the presence status
$Response = Invoke-RestMethod -Method GET -Uri $ApiUrl -ContentType "application\json" -Headers $headers
$Response | FL

Export Teams Online Presence Status for Bulk Users

We can use the getPresencesByUserId API to get the presence status for multiple users in a single API call. This API supports a maximum of 650 user IDs per API request. Sometimes, we may need to check the online presence status of multiple users. In this case, we can keep the user IDs (Object GUID) in a CSV file. Consider the CSV file “TeamUsers.csv” (Download sample CSV) which holds the user identity values in each row with the column headers UserName and UserId.  

The below script reads the bulk users from the CSV file and checks the online status for all the users, finally exports the presence status report to a CSV file.

#Provide your access token. 
#$AccessToken="eyJ0eXAiOiJ......" 
 
#Form request headers with the acquired $AccessToken
$headers = @{'Content-Type'="application\json";'Authorization'="Bearer $AccessToken"}

$ReportData = @() #Result array

#Read Teams users from the CSV file
$TeamsUsers = Import-CSV "C:\Temp\TeamsUsers.csv"
$i = 0;
$UserIdsToCheck = @()
$TotalUsers = $TeamsUsers.Count

#Enumerate users and check the Teams online status 
Foreach($TeamUser in $TeamsUsers)
{

$UserName = $TeamUser.'UserName'
$UserId = $TeamUser.'UserId'

#Add user id to the input array
$UserIdsToCheck += $UserId

$i++;
Write-Progress -activity "Processing $UserName" -status "$i out of $TotalUsers completed"

#Check online status for 100 users in a single batch call
if($UserIdsToCheck.Count -eq 100 -OR $i -eq $TotalUsers)
{
$PostContent= $UserIdsToCheck | ConvertTo-Json 
$RequestBody =  '{ "ids" : '+$PostContent+' }'

#Clear array to add next batch of users
$UserIdsToCheck =@() 

$ApiUrl = "https://graph.microsoft.com/v1.0/communications/getPresencesByUserId"

#Get the presence status for multilpe users
$Response = Invoke-RestMethod -Headers $headers -Uri $ApiUrl -Method Post -Body $RequestBody -ContentType "application/json"

if($Response.value)
{
$PresenceObjects = $Response.value

#Enumerate the presence status objects one by one
ForEach($PresenceInfo in $PresenceObjects)
{
#Get user name from CSV detail
$CSVUserInfo = $TeamsUsers | Where-Object { $_.'UserId' -eq $PresenceInfo.id}

#Add user status info into the result array
$ReportData += New-Object PSObject -property $([ordered]@{ 
UserName = $CSVUserInfo.'UserName'
UserId = $PresenceInfo.id
Availability = $PresenceInfo.availability
Activity = $PresenceInfo.activity
})

} 
}
}
}

#Export Teams Users Presence Status Report to CSV file
$ReportData | Export-CSV "C:\Temp\TeamsUsersPresenceReport.CSV" -NoTypeInformation -Encoding UTF8

#Display the result in PS console
#$ReportData | Select UserName,Availability,Activity
Advertisement

Leave a Comment