Find Teams Meetings Attended by a Specific User

This commit is contained in:
AdminDroid 2024-05-22 14:51:59 +05:30
parent 2efbc63d4e
commit f966ce8f3c

View File

@ -0,0 +1,239 @@
<#
=============================================================================================
Name : Find the Teams Meetings Attended by a Specific User Using PowerShell
Version : 1.0
website : o365reports.com
-----------------
Script Highlights
-----------------
1. The script exports user specific Teams meeting report.
2. The script retrieves user specific Teams meeting data for 180 days, by default.
3. Allows you to obtain audit Teams meeting attended by specific user for a custom period.
4. The script can be executed with an MFA enabled account too.
5. It exports audit results to CSV file format in the working directory.
6. Automatically installs the Exchange Online module (if not installed already) upon your confirmation.
7. The script is scheduler friendly.
8. The script supports certificate-based authentication.
For detailed Script execution: https://o365reports.com/2024/05/22/find-the-teams-meetings-attended-by-a-specific-user-using-powershell/
============================================================================================
\#>
param (
[Parameter(Mandatory = $false)]
[string]$userUPN,
[Nullable[DateTime]]$StartDate,
[Nullable[DateTime]]$EndDate,
[string]$UserName,
[string]$Password,
[string]$ClientId,
[string]$CertificateThumbprint,
[string]$Organization
)
Function Connect_Module {
# Checking availability of Exchange Online module and installing module
$ExchangeModule = Get-Module ExchangeOnlineManagement -ListAvailable
if($ExchangeModule.count -eq 0)
{
Write-Host ExchangeOnline module is not available -ForegroundColor Yellow
$confirm = Read-Host Do you want to Install ExchangeOnline module? [Y] Yes [N] No
if($confirm -match "[Yy]")
{
Write-Host "Installing ExchangeOnline module ..."
Install-Module ExchangeOnlineManagement -Repository PSGallery -AllowClobber -Force -Scope CurrentUser
Import-Module ExchangeOnlineManagement
}
else
{
Write-Host "ExchangeOnline Module is required. To Install ExchangeOnline module use 'Install-Module ExchangeOnlineManagement' cmdlet."
Exit
}
}
#Connecting to Exchange Online
Write-Host "`nConnecting Exchange Online module ..." -ForegroundColor Yellow
if(($UserName -ne "") -and ($Password -ne "")) {
$SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force
$Credential = New-Object System.Management.Automation.PSCredential $UserName,$SecuredPassword
Connect-ExchangeOnline -Credential $Credential
}
elseif($Organization -ne "" -and $ClientId -ne "" -and $CertificateThumbprint -ne "") {
Connect-ExchangeOnline -AppId $ClientId -CertificateThumbprint $CertificateThumbprint -Organization $Organization -ShowBanner:$false
}
else {
Connect-ExchangeOnline
}
}
#Verify user UPN is present
if($userUPN -eq "") {
Write-Host User Principal Name is Required! -Foregroundcolor Yellow
$userUPN = Read-Host Enter User UPN
}
$MaxStartDate=((Get-Date).AddDays(-180)).Date
#Getting Teams meeting attendance report for past 180 days
if(($StartDate -eq $null) -and ($EndDate -eq $null)) {
$EndDate=(Get-Date) #.Date
$StartDate=$MaxStartDate
}
#Getting start date to generate Teams meetings attendance report
While($true) {
if ($StartDate -eq $null) {
$StartDate = Read-Host Enter start time for report generation '(Eg:MM/DD/YYYY)'
}
Try {
$Date=[DateTime]$StartDate
if($Date -ge $MaxStartDate) {
break
}
else {
Write-Host `nAudit can be retrieved only for past 180 days. Please select a date after $MaxStartDate -ForegroundColor Red
return
}
}
Catch {
Write-Host `nNot a valid date -ForegroundColor Red
}
}
#Getting end date for teams attendance report
While($true) {
if ($EndDate -eq $null) {
$EndDate = Read-Host Enter End time for report generation '(Eg: MM/DD/YYYY)'
}
Try {
$Date=[DateTime]$EndDate
if($EndDate -lt ($StartDate))
{
Write-Host End time should be later than start time -ForegroundColor Red
return
}
break
}
Catch {
Write-Host `nNot a valid date -ForegroundColor Red
}
}
#get file dir
$outputFilePath = $PSScriptRoot
$OutputCSV = "$outputFilePath\TeamsMeetingSpecificUserAttendanceReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
$IntervalTimeInMinutes = 1440 #$IntervalTimeInMinutes=Read-Host Enter interval time period '(in minutes)'
$CurrentStart = $StartDate
$CurrentEnd = $CurrentStart.AddMinutes($IntervalTimeInMinutes)
#Check whether CurrentEnd exceeds EndDate
if($CurrentEnd -gt $EndDate) {
$CurrentEnd = $EndDate
}
if($CurrentStart -eq $CurrentEnd) {
Write-Host Start and end time are same.Please enter different time range -ForegroundColor Red
Exit
}
Connect_Module
$CurrentResultCount = 0
$ResultCount = 0
Write-Host `nGenerating Teams meeting attendance report from $StartDate to $EndDate...
$ProcessedAuditCount = 0
$OutputEvents = 0
$ExportResult = ""
$ExportResults = @()
$RetriveOperation = "MeetingParticipantDetail"
while($true) {
#Getting Teams meeting participants report for the given time range
Search-UnifiedAuditLog -StartDate $CurrentStart -EndDate $CurrentEnd -Operations $RetriveOperation -SessionId s -SessionCommand ReturnLargeSet -ResultSize 5000 | ForEach-Object {
$ResultCount++
$ProcessedAuditCount++
Write-Progress -Activity "`n Retrieving Team meeting attended by user : $userUPN ..."`n" Processed audit record count: $ProcessedAuditCount"
$AuditData=$_.AuditData | ConvertFrom-Json
$MeetingID=$AuditData.MeetingDetailId
$CreatedBy=$_.UserIDs
$AttendeesInfo=($AuditData.Attendees)
$AttendeesType=$AttendeesInfo.RecipientType
$Attendees=$AttendeesInfo.DisplayName
$AttendeesUPN=$AttendeesInfo.UPN
$JoinTime=(Get-Date($AuditData.JoinTime)).ToLocalTime() #Get-Date($AuditData.JoinTime) Uncomment to view the Activity Time in UTC
$LeaveTime=(Get-Date($AuditData.LeaveTime)).ToLocalTime()
$Duration = $JoinTime - $LeaveTime
$DurationinSeconds = ($Duration).TotalSeconds
$TimeSpanDuration = [timespan]::fromseconds($DurationinSeconds)
$AttendedDuration = ("{0:hh\:mm\:ss}" -f $TimeSpanDuration)
if($AttendeesUPN -eq $userUPN) {
#Export result to csv
$OutputEvents++
$ExportResult=@{'Meeting id'=$MeetingID;'Created By'=$CreatedBy;'Attendee'=$Attendees;'Attendee UPN' = $AttendeesUPN;'Attendee Type'=$AttendeesType;'Joined Time'=$JoinTime;'Left Time'=$LeaveTime;'Duration' = $AttendedDuration}
$ExportResults= New-Object PSObject -Property $ExportResult
$ExportResults | Select-Object 'Meeting id','Created By','Attendee','Attendee UPN','Attendee Type','Joined Time','Left Time','Duration' | Export-Csv -Path $OutputCSV -NoTypeInformation -Append
}
}
$currentResultCount=$currentResultCount+$ResultCount
if($CurrentResultCount -ge 50000) {
Write-Host Retrieved max record for current range.Proceeding further may cause data loss or rerun the script with reduced time interval. -ForegroundColor Red
$Confirm=Read-Host `nAre you sure you want to continue? [Y] Yes [N] No
if($Confirm -match "[Y]") {
Write-Host Proceeding audit log collection with data loss
[DateTime]$CurrentStart=$CurrentEnd
[DateTime]$CurrentEnd=$CurrentStart.AddMinutes($IntervalTimeInMinutes)
$CurrentResultCount=0
if($CurrentEnd -gt $EndDate) {
$CurrentEnd=$EndDate
}
}
else {
Write-Host Please rerun the script with reduced time interval -ForegroundColor Red
Exit
}
}
if($ResultCount -lt 5000) {
if($CurrentEnd -eq $EndDate) {
break
}
$CurrentStart=$CurrentEnd
if($CurrentStart -gt (Get-Date)) {
break
}
$CurrentEnd=$CurrentStart.AddMinutes($IntervalTimeInMinutes)
$CurrentResultCount=0
if($CurrentEnd -gt $EndDate) {
$CurrentEnd=$EndDate
}
}
$ResultCount=0
}
#Open output file after execution
if($OutputEvents -eq 0) {
Write-Host No records found
}
else {
Write-Host `nThe Teams meeting attendance report contains $OutputEvents audit records -ForegroundColor Green
if((Test-Path -Path $OutputCSV) -eq "True") {
Write-Host `n "The output file available in: " -NoNewline -ForegroundColor Yellow; Write-Host "$OutputCSV"
Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green
Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline;
Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n`n
$Prompt = New-Object -ComObject wscript.shell
$UserInput = $Prompt.popup("Do you want to open output file?",0,"Open Output File",4)
If ($UserInput -eq 6) {
Invoke-Item "$OutputCSV"
}
}
}
#Disconnect Exchange Online session
Disconnect-ExchangeOnline -Confirm:$false -InformationAction Ignore -ErrorAction SilentlyContinue