For over two years, my original guide for deploying Logitech devices with Intune and Teams had been working reliably, however understanding why you’re doing what you’re doing rather than just “following documentation” is the key to success - this is also a very good lesson on what worked 2 years may not work the same way in the future - likewise the advice in this later post may be outdated in the future.
The Problem
A new Logitech Rally Bar installation presented a very specific and puzzling issue:
- ✅ Teams authentication worked perfectly - device signed in successfully
- ✅ Teams Admin Center showed "Healthy" status
- ✅ Inbound and outbound calls worked flawlessly
- ✅ Directory lookups functioned normally
- ✅ Meeting invites were auto-accepted and appeared in Exchange
- ❌ Calendar sync completely failed - no meetings displayed on the device
- ❌ Teams diagnostic logs wouldn't download from Teams Admin Center
The Logitech screen would show "sync could not be performed" or similar errors when attempting calendar synchronization. Yet if you checked the room mailbox directly, all the accepted meetings were clearly visible in with the Exchange Calendar and accepted notification were being sent to the inboxes?
Eliminate “noise” from the issue.
This symptom pattern ruled out the obvious culprits:
- Network connectivity was clearly working (Teams calls and directory access)
- Authentication was successful (device showed as healthy)
- Exchange connectivity was functional (invites were being processed)
- Licensing was correct (Teams Rooms Pro license assigned)
The issue was specifically isolated to Exchange Web Services (EWS) calendar synchronization and Teams telemetry services - but basic Teams functionality worked perfectly.
The Investigation
You need to investigate everything in this situations, even if it seems insignificant take a look, until you have ruled that issue out, everything is on the table - so to speak.
Step 1: Verify Azure AD Sign-in Logs
The first step was examining the authentication patterns in Azure AD. This is where many people make a critical mistake.
Important: Don't just check the standard sign-in logs. For Teams Room devices, you need to review the non-interactive sign-in logs because these service accounts don't perform user-style interactive authentication for day-to-day operations.
In the Azure AD sign-in logs, I found:
- Multiple successful non-interactive sign-ins
- Single-factor authentication sessions completing successfully
- Conditional Access status showing "Not Applied"
This confirmed that Conditional Access policies weren't blocking the device, and authentication was working as expected.
Lets just get a visual of that, here you can see the "interactive" sign in logs, there are not how the device works for the majority and will only show events linked to the interactive login to the Teams app, it is worth nothing that the "interrupted" entries are device registration process working as it should be:
The error will even tell you this that this is not an error - the bottom interrupted event this is the PRT (primary refresh token) acquisition:
These requests from from the Device Registration service as you can see here:
However we need to be looking an the non-interactive sign-in logs as that is what the device is actually using:, you will need to expend the aggregate to get the event as below:
The lets cover of "conditional access" as you can see from below all the policies are not applied that means they are not applied:
Step 2: The Password Investigation
During investigation, I discovered the room account password had been changed multiple times, leading me initially to suspect credential issues. However, this was misleading because:
- OAuth tokens can remain valid for weeks/months after password changes
- Teams Room devices use cached refresh tokens rather than password authentication for ongoing operations
- Successful Azure AD sign-ins don't prove the current password is correct - they just prove the cached tokens are still valid
Conclusion : Successful authentication logs don't necessarily mean credentials are current when OAuth is involved.
Step 3: The Always-On VPN Investigation
I then discovered a global Intune device restriction policy requiring zScaler Always-on VPN for all Android devices:
Policy Settings:
- System Security: Threat scan on apps = Require
- Connectivity: Always-on VPN (work profile-level) = Enable
- VPN Client: Custom
- Package ID: zscaler.com.zscaler
Initially, this seemed relevant excluding the fact that all the other Logitech devices were working fine, but as device restrictions should not be applied to Logitech devices, I added the relevant exclusion group to this policy to avoid adverse effects on Teams Room functionality.
However, on technical assessment the following would be true:
-
If devices can't install the VPN client, how could it block traffic? The policy would mark devices non-compliant, but couldn't actively block connections.
-
Why did directory lookups still work? If EWS was truly blocked, all Exchange connectivity should fail.
Conclusion: Just because applying an exclusion group coincided with the fix doesn't mean the policy was the root cause.
Step 4: Device Registration Changes
The actual solution came from observing behavioral changes in the sign-in process that revealed Microsoft had fundamentally altered how Teams Room devices register with Azure AD.
The New Registration Pattern
When signing into the problematic device, I noticed:
- First sign-in attempt → "Register this device" screen appears
- Azure AD device registration process initiates
- Device automatically signs out (this is normal!)
- Second sign-in attempt → Successful authentication
What Changed: Company Portal vs. Built-in Registration
Old Method (used in my original 2022 guide):
- Company Portal app handled device registration to Azure AD
- Separate enrollment flow through Intune Company Portal
- Predictable, well-documented process
New Method (current):
- Built-in Azure AD registration as part of Teams sign-in flow
- Integrated device enrollment without separate Company Portal app
- "Register your device" prompts replace Company Portal interface
Device Registration Process - Critical!
When authenticating a Teams Room device, you must complete the full device registration process:
- Initial sign-in → Device presents "Register this device" screen
- Azure AD device registration → Device registers its identity with your tenant
- Automatic sign-out → This is intentional and required
- Second sign-in → Complete the authentication with registered device identity
This two-step process is mandatory. The device registration establishes the device's identity in Azure AD, which is required for:
- Teams Room-specific authentication (different from basic Teams app access)
- Exchange Web Services access (calendar synchronization)
- Teams telemetry and diagnostic services (voice logs, device health)
- Compliance policy evaluation (device health validation)
Conclusion: You must allow the device to complete both sign-in attempts. Interrupting this process or assuming the first sign-out is an error will result in incomplete device registration.
Modern Authentication Evolution
Microsoft's rapid evolution of authentication and device management processes means that documentation written even 2-3 years ago may use completely different procedures. The shift from Company Portal-based registration to built-in Azure AD registration represents a fundamental change in how Teams Room devices authenticate and enroll.
If you encounter similar issues, follow this systematic approach:
1. Verify Basic Connectivity (Don't Skip This)
- ✅ Teams calls work
- ✅ Directory lookups function
- ✅ Teams Admin Center shows "Healthy"
- ✅ Meeting invites are auto-accepted in Exchange
2. Check Authentication Logs (The Right Ones)
- Review non-interactive sign-in logs in Azure AD
- Look for authentication patterns, not just success/failure
- Check Conditional Access evaluation results
- Verify single-factor authentication is completing
3. Identify Service-Specific Failures
- ❌ Calendar sync fails
- ❌ Teams diagnostic logs won't download
- ❌ Voice logs missing from Teams Admin Center
- ❌ Specific telemetry services not working
4. Test the Registration Process
- Sign out completely from the device
- Delete all user data (not just sign-out)
- Attempt fresh sign-in and observe:
- Does "Register this device" screen appear?
- Does device sign out automatically after first attempt?
- Does second sign-in succeed completely?
5. Compare Registration Methods
- Check if Company Portal app appears during enrollment (it should not anymore, this indicates out of date firmware/team application)
- Note if built-in Azure AD registration is used instead
- Verify device appears correctly in Azure AD with proper attributes
7. Check for Policy Interference
- Review global device restriction policies
- Look for device restriction or compliance policies that could interfere with the process
8. Extract Logs from All Sources
- Azure AD sign-in logs (interactive and non-interactive)
- Intune device compliance logs
- Teams Admin Center diagnostic data (if available)
- Logitech Sync Portal logs (if device is registered)
- CollabOS system logs (contact Logitech support if needed)
Behavioral Symptom: BYOD Mode Switching
During the investigation, I observed a crucial behavioral pattern that initially seemed like minor noise but actually provided the key to understanding the entire problem.
The problematic Rally Bar was intermittently switching between:
- Teams Room application (normal operational mode)
- "Please connect a device" screen (what Logitech calls the "BYOD default screen")
This switching behavior was inconsistent and easy to dismiss as a minor glitch, but it actually revealed the core issue.
What This Behavior Really Means
Simple : BYOD Mode = Authentication Failure Fallback
When Logitech devices display the "please connect a device" screen or the screen with the cable displayed, they're operating in BYOD (Bring Your Own Device) mode rather than Teams Room appliance mode. This is the device's fallback state when it cannot maintain proper Teams Room authentication.
The Authentication State Conflict
The switching pattern indicates:
- Teams app launches successfully → Basic OAuth authentication works
- Teams Room mode fails to stabilize → Device registration or compliance validation fails
- Device falls back to BYOD mode → Safe default state when Teams Room authentication fails
- Cycle repeats → Device continuously attempts to re-establish proper Teams Room mode
The Service Hierarchy Explained
This behavior perfectly explains why different services failed at different levels:
- Basic OAuth tokens → Sufficient to launch Teams app
- Incomplete device registration → Insufficient to maintain Teams Room mode
- EWS calendar access → Requires full device registration
- Teams telemetry services → Requires device compliance validation
- Diagnostic log access → Requires proper Teams Room registration state
The Missing Diagnostic Indicator
This switching behavior should be considered a primary diagnostic indicator for device registration issues, but you had to be in the room to notice this issue, remotely you cannot tell this is occuring.
"Device alternating between Teams app and BYOD screen = incomplete Azure AD device registration causing authentication state instability"
Why This Wasn't Initially Obvious
The switching pattern was likely:
- Intermittent rather than constant
- Brief - easy to miss during quick status checks
- Seemingly unrelated to calendar sync issues
- Dismissed as minor glitch rather than core symptom
Step 5 : Account Investigation
To rule out account configuration issues as the root cause, I created a comprehensive PowerShell script to compare the problematic account with a known working room account.
Script : RoomMailboxInvestigation.ps1
# Room Mailbox Investigation Script
# This script collects diagnostic information to identify conversion thumbprints
# and configuration differences between problematic and working room accounts
param(
[Parameter(Mandatory=$true)]
[string]$ProblematicAccount,
[Parameter(Mandatory=$true)]
[string]$WorkingAccount,
[Parameter(Mandatory=$false)]
[string]$OutputPath = "./
"
)
# Create output directory if it doesn't exist
if (!(Test-Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath -Force
}
# Generate timestamp for files
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = "$OutputPath\RoomMailbox_Investigation_$timestamp.txt"
# Function to write section headers
function Write-Section {
param([string]$Title)
$separator = "=" * 80
$output = @"
$separator
$Title
$separator
"@
Write-Host $output -ForegroundColor Yellow
Add-Content -Path $outputFile -Value $output
}
# Function to write subsection headers
function Write-Subsection {
param([string]$Title)
$output = @"
--- $Title ---
"@
Write-Host $output -ForegroundColor Cyan
Add-Content -Path $outputFile -Value $output
}
# Function to execute command and capture output
function Execute-Command {
param(
[string]$Command,
[string]$Description
)
Write-Subsection $Description
Write-Host "Executing: $Command" -ForegroundColor Gray
try {
$result = Invoke-Expression $Command
$output = $result | Out-String
Add-Content -Path $outputFile -Value "Command: $Command"
Add-Content -Path $outputFile -Value $output
Write-Host $output
}
catch {
$errorOutput = "ERROR: $($_.Exception.Message)"
Add-Content -Path $outputFile -Value $errorOutput
Write-Host $errorOutput -ForegroundColor Red
}
}
# Start investigation
Write-Host "Starting Room Mailbox Investigation..." -ForegroundColor Green
# Collect comprehensive diagnostic data
Write-Section "BASIC MAILBOX INFORMATION"
Execute-Command "Get-Mailbox -Identity '$ProblematicAccount' | Format-List Name,RecipientTypeDetails,IsResource,ResourceType,WhenCreated,WhenMailboxCreated,Database,MailboxPlan,AccountDisabled" "Problematic Account - Basic Info"
Execute-Command "Get-Mailbox -Identity '$WorkingAccount' | Format-List Name,RecipientTypeDetails,IsResource,ResourceType,WhenCreated,WhenMailboxCreated,Database,MailboxPlan,AccountDisabled" "Working Account - Basic Info"
Write-Section "CALENDAR PROCESSING SETTINGS"
Execute-Command "Get-CalendarProcessing -Identity '$ProblematicAccount' | Format-List AutomateProcessing,DeleteSubject,DeleteComments,AddOrganizerToSubject,RemovePrivateProperty,ProcessExternalMeetingMessages" "Problematic Account - Calendar Processing"
Execute-Command "Get-CalendarProcessing -Identity '$WorkingAccount' | Format-List AutomateProcessing,DeleteSubject,DeleteComments,AddOrganizerToSubject,RemovePrivateProperty,ProcessExternalMeetingMessages" "Working Account - Calendar Processing"
Write-Section "EWS CONFIGURATION"
Execute-Command "Get-CASMailbox -Identity '$ProblematicAccount' | Format-List EwsEnabled,EwsAllowOutlook,EwsAllowMacOutlook" "Problematic Account - EWS Settings"
Execute-Command "Get-CASMailbox -Identity '$WorkingAccount' | Format-List EwsEnabled,EwsAllowOutlook,EwsAllowMacOutlook" "Working Account - EWS Settings"
Write-Host "`nInvestigation completed! Results saved to: $outputFile" -ForegroundColor Green
Investigation Results: No Account Configuration Issues
Running this script revealed that both accounts were perfectly configured:
Identical Configuration:
RecipientTypeDetails: RoomMailbox
IsResource: True
AutomateProcessing: AutoAccept
DeleteSubject: False
DeleteComments: False
EwsEnabled: True
No Conversion Artifacts:
- Both accounts showed proper room mailbox creation patterns
- No evidence of user-to-room conversion
- Timing differences explained by different Entra Connect sync intervals
Conclusion : This confirmed that the issue was NOT account configuration but rather device-level authentication state corruption.
EWS State Investigation
Note : The degraded account was created by a different team, I did not create these particular accounts personally.
I did hear as an update that someone made the remark that “EWS was not enabled”, let’s just be clear about EWS on an Exchange Online mailbox, you do not need to specifically enable it on any individual mailbox as it takes the organizational setting and applies that by default, Let’s look into what happens if EWS was disabled at an organizational level…..
If EWS was disabled at the organizational level, here's what would break across your entire tenant:
What would not work
1. Teams Room Calendar Functionality:
- ❌ Calendar sync completely fails (no meetings display)
- ❌ Meeting join buttons don't appear
- ❌ Room booking confirmations fail
- ❌ Calendar processing stops working
- ❌ Free/busy information unavailable
2. Outlook Client Connectivity:
- ❌ Outlook desktop apps can't connect to Exchange Online
- ❌ Outlook for Mac stops working
- ❌ Cached Exchange Mode fails
- ❌ Send/receive errors in Outlook
- ❌ Address book lookups fail
3. Mobile Device Email:
- ❌ iOS Mail app stops syncing
- ❌ Android native email apps fail
- ❌ Third-party email clients break
4. Third-Party Applications:
- ❌ Any app using EWS APIs (calendar sync tools, backup solutions)
- ❌ Room booking systems that integrate via EWS
- ❌ Monitoring tools that check mailbox health
- ❌ Migration tools that use EWS
- ❌ Compliance/archiving solutions using EWS
5. Shared Mailbox Access:
- ❌ Shared mailbox connectivity via Outlook
- ❌ Delegate access to other mailboxes
- ❌ Calendar sharing between users
6. Unified Communications:
- ❌ Skype for Business calendar integration
- ❌ Teams calendar access for regular users
- ❌ Meeting scheduling add-ins
That does not mean everything would not work with EWS disabled, the following would continue on unaware because the EWS is not used:
- ✅ Outlook Web App (OWA) - uses different APIs
- ✅ Teams chat/calling - doesn't require EWS
- ✅ Exchange ActiveSync - separate protocol
- ✅ IMAP/POP3 - if enabled
- ✅ PowerShell/Graph API - different authentication
- ✅ Mobile Outlook app - uses different APIs
EWS being Disabled : Company wide impact!
- All Outlook clients in your organization stop working
- Every Teams Room device loses calendar functionality
- Help desk flooded with "Outlook won't connect" tickets
- All third-party integrations break simultaneously
What was the situation with this problem?
- ✅ Other Logitech devices worked fine
- ✅ Only ONE device had calendar issues
- ✅ No widespread Outlook failures reported
- ✅ Teams calling still worked
If EWS was disabled organization-wide, you would have had a complete email/calendar catastrophe affecting every user and device in your tenant, not just one Rally Bar!
This confirms that EWS was never disabled, it is also worth noting just because you see a blank value or an unset value does not mean it is disabled, instead that setting comes from organizational configuration.
I have prepared a script that will check for changes to EWS configuration in the unified audit log, however, just to be clear all the other Logitech rooms did not require EWS enabling because it was already enabled - the script below will report who changed the setting, but remember as I said earlier it’s enabled by default.
# Comprehensive EWS Account Investigation Script
# This script checks current EWS status and complete history for any account
param(
[Parameter(Mandatory=$false)]
[string]$AccountToCheck,
[Parameter(Mandatory=$false)]
[int]$DaysBack = 90
)
# Prompt for account if not provided
if (-not $AccountToCheck) {
$AccountToCheck = Read-Host "Enter the account to investigate (UPN or email)"
}
# Set output to script directory
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
if (-not $ScriptPath) { $ScriptPath = Get-Location }
# Generate timestamp for files
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$outputFile = Join-Path $ScriptPath "EWS_Investigation_$($AccountToCheck.Split('@')[0])_$timestamp.txt"
# Function to write section headers
function Write-Section {
param([string]$Title)
$separator = "=" * 80
$output = @"
$separator
$Title
$separator
"@
Write-Host $output -ForegroundColor Yellow
Add-Content -Path $outputFile -Value $output
}
# Function to write output to both console and file
function Write-Output {
param([string]$Message, [string]$Color = "White")
Write-Host $Message -ForegroundColor $Color
Add-Content -Path $outputFile -Value $Message
}
# Start investigation
Write-Section "EWS INVESTIGATION FOR: $AccountToCheck"
Write-Output "Investigation Date: $(Get-Date)"
Write-Output "Checking last $DaysBack days of activity"
Write-Output "Output file: $outputFile"
# Check if connected to Exchange Online
try {
$null = Get-OrganizationConfig -ErrorAction Stop
Write-Output "✅ Connected to Exchange Online" "Green"
}
catch {
Write-Output "❌ Not connected to Exchange Online. Run Connect-ExchangeOnline first" "Red"
exit
}
# SECTION 1: Current EWS Status
Write-Section "CURRENT EWS STATUS"
try {
$CASMailbox = Get-CASMailbox -Identity $AccountToCheck -ErrorAction Stop
Write-Output "Account: $($CASMailbox.DisplayName)"
Write-Output "UPN: $($CASMailbox.PrimarySmtpAddress)"
Write-Output ""
Write-Output "EWS Configuration:"
Write-Output " EwsEnabled: $($CASMailbox.EwsEnabled)" $(if($CASMailbox.EwsEnabled) {"Green"} else {"Red"})
Write-Output " EwsAllowOutlook: $($CASMailbox.EwsAllowOutlook)"
Write-Output " EwsAllowMacOutlook: $($CASMailbox.EwsAllowMacOutlook)"
Write-Output " EwsAllowEntourage: $($CASMailbox.EwsAllowEntourage)"
Write-Output " EwsApplicationAccessPolicy: $($CASMailbox.EwsApplicationAccessPolicy)"
# Check if there are any EWS-specific blocks
if ($CASMailbox.EwsBlockList) {
Write-Output " EwsBlockList: $($CASMailbox.EwsBlockList)" "Red"
}
if ($CASMailbox.EwsAllowList) {
Write-Output " EwsAllowList: $($CASMailbox.EwsAllowList)" "Green"
}
}
catch {
Write-Output "❌ Error retrieving current EWS status: $($_.Exception.Message)" "Red"
}
# SECTION 2: Organization-wide EWS Status
Write-Section "ORGANIZATION EWS STATUS"
try {
$OrgConfig = Get-OrganizationConfig
Write-Output "Organization EWS Settings:"
Write-Output " EwsEnabled: $($OrgConfig.EwsEnabled)" $(if($OrgConfig.EwsEnabled) {"Green"} else {"Red"})
Write-Output " EwsAllowOutlook: $($OrgConfig.EwsAllowOutlook)"
Write-Output " EwsAllowMacOutlook: $($OrgConfig.EwsAllowMacOutlook)"
Write-Output " EwsAllowEntourage: $($OrgConfig.EwsAllowEntourage)"
if ($OrgConfig.EwsBlockList) {
Write-Output " Organization EwsBlockList: $($OrgConfig.EwsBlockList)" "Red"
}
if ($OrgConfig.EwsAllowList) {
Write-Output " Organization EwsAllowList: $($OrgConfig.EwsAllowList)" "Green"
}
}
catch {
Write-Output "❌ Error retrieving organization EWS status: $($_.Exception.Message)" "Red"
}
# SECTION 3: EWS Change History - Set-CASMailbox Commands
Write-Section "EWS CHANGE HISTORY - SET-CASMAILBOX COMMANDS"
Write-Output "Searching for Set-CASMailbox commands affecting this account..."
try {
$CASChanges = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-$DaysBack) -EndDate (Get-Date) -Operations "Set-CASMailbox" |
Where-Object {$_.AuditData -like "*$($AccountToCheck)*" -and $_.AuditData -like "*EWS*"}
if ($CASChanges) {
Write-Output "EWS-related Set-CASMailbox commands found:" "Red"
foreach ($change in $CASChanges) {
$auditData = $change.AuditData | ConvertFrom-Json
Write-Output ""
Write-Output "Date: $($change.CreationDate)"
Write-Output "Admin: $($change.UserIds)"
Write-Output "Operation: $($change.Operations)"
Write-Output "Object: $($auditData.ObjectId)"
if ($auditData.Parameters) {
$ewsParams = $auditData.Parameters | Where-Object {$_.Name -like "*EWS*"}
if ($ewsParams) {
Write-Output "EWS Parameters: $($ewsParams | ConvertTo-Json -Compress)"
}
}
}
} else {
Write-Output "✅ No Set-CASMailbox EWS changes found for this account" "Green"
}
}
catch {
Write-Output "❌ Error searching Set-CASMailbox audit log: $($_.Exception.Message)" "Red"
}
# SECTION 4: EWS Change History - Organization Config Changes
Write-Section "EWS CHANGE HISTORY - ORGANIZATION CONFIG"
Write-Output "Searching for Set-OrganizationConfig commands affecting EWS..."
try {
$OrgChanges = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-$DaysBack) -EndDate (Get-Date) -Operations "Set-OrganizationConfig" |
Where-Object {$_.AuditData -like "*EWS*"}
if ($OrgChanges) {
Write-Output "Organization EWS changes found:" "Yellow"
foreach ($change in $OrgChanges) {
$auditData = $change.AuditData | ConvertFrom-Json
Write-Output ""
Write-Output "Date: $($change.CreationDate)"
Write-Output "Admin: $($change.UserIds)"
Write-Output "Operation: $($change.Operations)"
if ($auditData.Parameters) {
$ewsParams = $auditData.Parameters | Where-Object {$_.Name -like "*EWS*"}
if ($ewsParams) {
Write-Output "EWS Parameters: $($ewsParams | ConvertTo-Json -Compress)"
}
}
}
} else {
Write-Output "✅ No organization-wide EWS changes found" "Green"
}
}
catch {
Write-Output "❌ Error searching Set-OrganizationConfig audit log: $($_.Exception.Message)" "Red"
}
# SECTION 5: All Commands Affecting This Account
Write-Section "ALL COMMANDS AFFECTING THIS ACCOUNT"
Write-Output "Searching for any commands that modified this account..."
try {
$AllChanges = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-$DaysBack) -EndDate (Get-Date) -FreeText $AccountToCheck -ResultSize 5000 |
Where-Object {$_.AuditData -like "*$AccountToCheck*"}
if ($AllChanges) {
Write-Output "Commands affecting this account:" "Cyan"
$GroupedChanges = $AllChanges | Group-Object Operations
foreach ($group in $GroupedChanges) {
Write-Output ""
Write-Output "Operation: $($group.Name) ($($group.Count) times)"
$group.Group | Sort-Object CreationDate | Select-Object -First 5 | ForEach-Object {
Write-Output " $($_.CreationDate) - $($_.UserIds)"
if ($_.AuditData -like "*EWS*") {
Write-Output " ⚠️ EWS-related activity detected" "Yellow"
}
}
if ($group.Count -gt 5) {
Write-Output " ... and $($group.Count - 5) more entries"
}
}
} else {
Write-Output "No commands found affecting this account" "Green"
}
}
catch {
Write-Output "❌ Error searching for account changes: $($_.Exception.Message)" "Red"
}
# SECTION 6: Unified Audit Log Search
Write-Section "UNIFIED AUDIT LOG - EWS ACTIVITIES"
Write-Output "Searching unified audit log for EWS-related activities..."
try {
$UnifiedAudit = Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-$DaysBack) -EndDate (Get-Date) -Operations "Set-CASMailbox","Set-OrganizationConfig" |
Where-Object {$_.AuditData -like "*$AccountToCheck*" -or $_.AuditData -like "*EWS*"}
if ($UnifiedAudit) {
Write-Output "Unified audit entries found:" "Yellow"
foreach ($entry in $UnifiedAudit) {
$auditData = $entry.AuditData | ConvertFrom-Json
Write-Output ""
Write-Output "Date: $($entry.CreationDate)"
Write-Output "User: $($entry.UserIds)"
Write-Output "Operation: $($entry.Operations)"
if ($auditData.Parameters) {
Write-Output "Parameters: $($auditData.Parameters | Out-String)"
}
}
} else {
Write-Output "✅ No relevant unified audit entries found" "Green"
}
}
catch {
Write-Output "❌ Error searching unified audit log: $($_.Exception.Message)" "Red"
}
# SECTION 7: Account Creation History
Write-Section "ACCOUNT CREATION AND MAILBOX HISTORY"
try {
$Mailbox = Get-Mailbox -Identity $AccountToCheck
$User = Get-User -Identity $AccountToCheck
Write-Output "Account Timeline:"
Write-Output " User Created: $($User.WhenCreated)"
Write-Output " Mailbox Created: $($Mailbox.WhenMailboxCreated)"
Write-Output " Account Type: $($Mailbox.RecipientTypeDetails)"
Write-Output " Last Modified: $($User.WhenChanged)"
$AccountAge = (Get-Date) - $User.WhenCreated
Write-Output " Account Age: $($AccountAge.Days) days"
# Check if account was created recently vs when issues started
if ($AccountAge.Days -lt $DaysBack) {
Write-Output " ⚠️ Account was created within investigation period" "Yellow"
}
}
catch {
Write-Output "❌ Error retrieving account creation info: $($_.Exception.Message)" "Red"
}
# SECTION 8: Summary and Recommendations
Write-Section "SUMMARY AND RECOMMENDATIONS"
Write-Output "Investigation Summary:"
# Current status summary
if ($CASMailbox.EwsEnabled -and $OrgConfig.EwsEnabled) {
Write-Output "✅ EWS is currently ENABLED at both account and organization level" "Green"
} elseif (-not $CASMailbox.EwsEnabled) {
Write-Output "❌ EWS is currently DISABLED at the account level" "Red"
} elseif (-not $OrgConfig.EwsEnabled) {
Write-Output "❌ EWS is currently DISABLED at the organization level" "Red"
}
# Change history summary
$TotalEWSChanges = @($CASChanges).Count + @($OrgChanges).Count
if ($TotalEWSChanges -eq 0) {
Write-Output "✅ NO EWS configuration changes found in the last $DaysBack days" "Green"
Write-Output " The claim that 'EWS was disabled and re-enabled' appears to be incorrect" "Yellow"
} else {
Write-Output "⚠️ $TotalEWSChanges EWS configuration changes found - review above for details" "Red"
}
Write-Output ""
Write-Output "Next Steps:"
if ($TotalEWSChanges -eq 0) {
Write-Output "• EWS configuration has not been changed - look for other root causes"
Write-Output "• Consider device-level authentication issues or policy conflicts"
Write-Output "• Review Teams Room device registration and authentication state"
} else {
Write-Output "• Review the EWS changes found above"
Write-Output "• Contact the administrators who made changes for more details"
Write-Output "• Correlate timing of changes with when issues were reported"
}
Write-Output ""
Write-Output "Investigation completed: $(Get-Date)" "Green"
Write-Output "Full results saved to: $outputFile" "Cyan"
Root Cause: Device-Level Authentication State Corruption
Since the account configuration was perfect, the problem lay in how the device itself was managing authentication state.
Understanding Modern Authentication Architecture
Teams Room devices don't just have "one login" - they maintain multiple authentication contexts simultaneously:
- OAuth Token Layer (Teams app authentication)
- Azure AD Device Registration (device identity in tenant)
- Certificate-based Authentication (device certificates)
- Cached Device Profile (CollabOS device configuration)
- Service-Specific Tokens (EWS, Graph API, Teams telemetry)
Why Simple Sign-Out/Sign-In Doesn't Fix Everything
What Sign-Out/Sign-In Actually Does:
- ✅ Clears OAuth tokens for Teams app
- ✅ Refreshes user credentials
- ❌ Preserves Azure AD device registration
- ❌ Retains device certificates
- ❌ Keeps cached device profile
- ❌ Maintains service-specific authentication state
What Gets Left Behind:
/data/data/com.microsoft.teams/
├── shared_prefs/ # Device registration state
├── databases/ # Cached authentication tokens
├── cache/ # Service endpoints and certificates
└── files/ # Device profile and configuration
Why User Data Reset/Deletion Was Required
User data deletion removes everything:
- All cached authentication tokens
- Device registration certificates
- Service-specific authentication state
- Cached policy configurations
- Device profile information
After data deletion, the device goes through complete re-authentication:
- Fresh Azure AD device registration (with exclusion policy in place)
- Clean OAuth token acquisition (no corrupted cache)
- Proper service token generation (EWS, telemetry, etc.)
- Complete device profile setup (Teams Room mode configuration)
Why did a new account "Fix" It?
Simply put with a new account you would not be able to sign out of the teams application and sign back in, instead you would need to reset all the user data and monitor the process yourself, it is also worth noting that the person that created the account should be doing this authentication into the teams application, do not get somebody else to do that.
- No corrupted cache to inherit
- Clean device registration process
- Policy exclusion already in place (no enrollment conflicts)
- Complete service token acquisition (all services authenticated properly)
- I personally watched the whole login process and confirmed it had worked correctly
Conclusion
The most frustrating technical problems are often the ones where everything you know is correct, but no longer relevant. In a rapidly evolving ecosystem like Microsoft 365, yesterday's expertise can become tomorrow's blind spot.
In this particular scenario, another team created and set up the account to which I had no visibility of what was done so I had to reverse engineer what had been done, unfortunately, meeting rooms, get a lot of attention and we did not have a time to do a full technical deep dive, therefore, to resolve this particular incident, I created a new account and set it up myself - this then enabled EWS to function correctly with the calendar.
Remember: when your battle-tested procedures suddenly stop working, the problem might not be your environment - it might be that the entire game has changed while you weren't looking - ensure you are responsible and accountable for actions taken when setting up publicly visible meeting rooms.