Generate-IntuneAnomaliesReport.ps1


<#PSScriptInfo
 
.VERSION 0.4
 
.GUID 4673bbfb-20cc-40e9-8ae9-c859099791fa
 
.AUTHOR Roy Klooster
 
.COMPANYNAME
 
.COPYRIGHT (c) 2025 Roy Klooster - RK Solutions. All rights reserved.
 
.TAGS
    RKSolutions
    Microsoft365
    MicrosoftIntune
    MicrosoftEntraID
    MicrosoftGraph
    DeviceManagement
    Compliance
    Autopilot
    BitLocker
    Reporting
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
        0.1 - Initial version of the script providing comprehensive Intune anomalies reporting functionality.
              Features include: Application failure analysis, multiple user detection on single-user devices,
              encryption status monitoring, Autopilot hash validation, inactive device tracking,
              compliance policy violation details, OS edition overview, and disabled user detection.
              Supports multiple authentication methods and email functionality with interactive HTML reports.
        0.2 - Filtered out the "Managed by MDE". Otherwise you get inconsistant information
        0.3 - Fixed the counting in the non compliant devices tile.
        0.4 - Fixed the $results return in get-alldevicedata function
 
 
.PRIVATEDATA
 
#>


<#
 
.DESCRIPTION
This PowerShell script connects to Microsoft Graph API and generates a comprehensive interactive HTML report that identifies various anomalies and potential issues in your Microsoft Intune environment. The script performs deep analysis of managed Windows devices and provides actionable insights for IT administrators to maintain optimal device management and security.
 
Key Features:
- Application Failure Analysis: Identifies applications with high failure rates that may indicate packaging or deployment issues
- Multi-User Device Detection: Locates user-driven devices with multiple logged-on users that should be re-enrolled as shared devices
- Encryption Status Monitoring: Reports devices without BitLocker encryption, highlighting significant security risks
- Autopilot Hash Validation: Identifies non-company owned devices missing hardware hash registration in Autopilot
- Inactive Device Tracking: Lists devices that haven't contacted Intune in 90+ days for cleanup consideration
- Compliance Policy Violations: Provides detailed breakdown of non-compliant devices with specific violation reasons
- OS Edition Overview: Displays operating system editions across the environment for license optimization opportunities
- Disabled User Detection: Identifies devices assigned to disabled Microsoft Entra ID user accounts
 
The generated HTML report features:
- Interactive dashboard with advanced filtering capabilities for each anomaly category
- Dark/light theme support with automatic system preference detection
- Export functionality (Excel, CSV, PDF, Print) for all data tables
- Responsive design that works across all modern web browsers
- Real-time search and pagination for large datasets
- Visual statistics cards showing anomaly counts at a glance
 
Authentication Methods Supported:
- Interactive browser-based authentication for interactive sessions
- Service principal authentication using client secret for automated scenarios
- Certificate-based authentication for enhanced security in production environments
- Managed identity authentication for Azure-hosted automation (Azure Automation, Functions, etc.)
- Access token authentication for custom authentication workflows
 
The script includes email functionality to automatically distribute reports to stakeholders with detailed HTML content and the interactive report as an attachment. All data collection is optimized for performance with efficient Graph API calls and proper error handling.
 
#>
 


Param(  
    [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
    [Parameter(Mandatory = $false, ParameterSetName = "ClientSecret")]
    [Parameter(Mandatory = $false, ParameterSetName = "Certificate")]
    [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
    [Parameter(Mandatory = $false, ParameterSetName = "AccessToken")]
    [string[]]$RequiredScopes = @("User.Read", "DeviceManagementManagedDevices.Read.All","DeviceManagementConfiguration.Read.All","DeviceManagementServiceConfig.Read.All", "DeviceManagementApps.Read.All","User.Read.All", "Directory.Read.All", "Mail.Send" ),

    [Parameter(Mandatory = $true, ParameterSetName = "ClientSecret")]
    [Parameter(Mandatory = $true, ParameterSetName = "Certificate")]
    [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
    [Parameter(Mandatory = $true, ParameterSetName = "AccessToken")]
    [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
    [string]$TenantId,
    
    [Parameter(Mandatory = $true, ParameterSetName = "ClientSecret")]
    [Parameter(Mandatory = $true, ParameterSetName = "Certificate")]
    [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
    [string]$ClientId,
    
    [Parameter(Mandatory = $true, ParameterSetName = "ClientSecret")]
    [string]$ClientSecret,
    
    [Parameter(Mandatory = $true, ParameterSetName = "Certificate")]
    [string]$CertificateThumbprint,

    [Parameter(Mandatory = $true, ParameterSetName = "Identity")]
    [switch]$Identity,

    [Parameter(Mandatory = $true, ParameterSetName = "AccessToken")]
    [string]$AccessToken,

    [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
    [Parameter(Mandatory = $false, ParameterSetName = "ClientSecret")]
    [Parameter(Mandatory = $false, ParameterSetName = "Certificate")]
    [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
    [Parameter(Mandatory = $false, ParameterSetName = "AccessToken")]
    [switch]$SendEmail,
    
    [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
    [Parameter(Mandatory = $false, ParameterSetName = "ClientSecret")]
    [Parameter(Mandatory = $false, ParameterSetName = "Certificate")]
    [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
    [Parameter(Mandatory = $false, ParameterSetName = "AccessToken")]
    [string[]]$Recipient,

    [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
    [Parameter(Mandatory = $false, ParameterSetName = "ClientSecret")]
    [Parameter(Mandatory = $false, ParameterSetName = "Certificate")]
    [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
    [Parameter(Mandatory = $false, ParameterSetName = "AccessToken")]
    [string]$From
)

function New-IntuneAnomaliesHTMLReport {
    param(
        [Parameter(Mandatory = $true)]
        [string]$TenantName,
        
        [Parameter(Mandatory = $false)]
        [array]$Report_ApplicationFailureReport,
        [Parameter(Mandatory = $false)]
        [array]$Report_DevicesWithMultipleUsers,
        [Parameter(Mandatory = $false)]
        [array]$Report_NotEncryptedDevices,
        [Parameter(Mandatory = $false)]
        [array]$Report_DevicesWithoutAutopilotHash,
        [Parameter(Mandatory = $false)]
        [array]$Report_InactiveDevices,
        [Parameter(Mandatory = $false)]
        [array]$Report_OperationSystemEdtionOverview,
        [Parameter(Mandatory = $false)]
        [array]$Report_NoncompliantDevices,
        [Parameter(Mandatory = $false)]
        [array]$Report_DisabledPrimaryUsers,
        [Parameter(Mandatory = $false)]
        [string]$ExportPath = "$env:PUBLIC\Documents\$TenantName-IntuneAnomaliesReport.html"
    )

    # Calculate counts for dashboard statistics
    $Report_ApplicationFailureReport_Count = $Report_ApplicationFailureReport | Measure-Object | Select-Object -ExpandProperty Count
    $Report_DevicesWithMultipleUsers_Count = $Report_DevicesWithMultipleUsers | Measure-Object | Select-Object -ExpandProperty Count
    $Report_NotEncryptedDevices_Count = $Report_NotEncryptedDevices | Measure-Object | Select-Object -ExpandProperty Count
    $Report_DevicesWithoutAutopilotHash_Count = $Report_DevicesWithoutAutopilotHash | Measure-Object | Select-Object -ExpandProperty Count
    $Report_InactiveDevices_Count = $Report_InactiveDevices | Measure-Object | Select-Object -ExpandProperty Count
    $Report_NoncompliantDevices_Count = $NoncompliantDevicesRaw | Measure-Object | Select-Object -ExpandProperty Count
    $Report_OperationSystemEdtionOverview_Count = $Report_OperationSystemEdtionOverview | Measure-Object | Select-Object -ExpandProperty Count
    $Report_DisabledPrimaryUsers_Count = $Report_DisabledPrimaryUsers | Measure-Object | Select-Object -ExpandProperty Count
    
    # Get the current date and time for the report header
    $CurrentDate = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss")

    # Create HTML Template with DataTables
    $htmlTemplate = @'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$TenantName Intune Anomalies Report</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.1/css/buttons.bootstrap5.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.1/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.1/js/buttons.bootstrap5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.1/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.1/js/buttons.print.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.4.1/js/buttons.colVis.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<style>
:root {
    --primary-color: #0078d4;
    --secondary-color: #2b88d8;
    --permanent-color: #d83b01;
    --eligible-color: #107c10;
    --group-color: #5c2d91;
    --disabled-color: #d9534f;
    --enabled-color: #5cb85c;
    --service-principal-color: #0078d4;
    --na-color: #6c757d;
    --bg-color: #f8f9fa;
    --card-bg: #ffffff;
    --text-color: #333333;
    --table-header-bg: #f5f5f5;
    --table-header-color: #333333;
    --table-stripe-bg: rgba(0,0,0,0.02);
    --table-hover-bg: rgba(0,0,0,0.04);
    --table-border-color: #dee2e6;
    --filter-tag-bg: #e9ecef;
    --filter-tag-color: #495057;
    --filter-bg: white;
    --btn-outline-color: #6c757d;
    --border-color: #dee2e6;
    --toggle-bg: #ccc;
    --button-bg: #f8f9fa;
    --button-color: #333;
    --button-border: #ddd;
    --button-hover-bg: #e9ecef;
    --footer-text: white;
    --input-bg: #fff;
    --input-color: #333;
    --input-border: #ced4da;
    --input-focus-border: #86b7fe;
    --input-focus-shadow: rgba(13, 110, 253, 0.25);
    --datatable-even-row-bg: #fff;
    --datatable-odd-row-bg: #f9f9f9;
    --tab-active-bg: #0078d4;
    --tab-active-color: #fff;
}
  
[data-theme="dark"] {
    --primary-color: #0078d4;
    --secondary-color: #2b88d8;
    --permanent-color: #d83b01;
    --eligible-color: #107c10;
    --group-color: #5c2d91;
    --disabled-color: #6c757d;
    --enabled-color: #0078d4;
    --service-principal-color: #0078d4;
    --bg-color: #121212;
    --card-bg: #1e1e1e;
    --text-color: #e0e0e0;
    --table-header-bg: #333333;
    --table-header-color: #e0e0e0;
    --table-stripe-bg: rgba(255,255,255,0.03);
    --table-hover-bg: rgba(255,255,255,0.05);
    --table-border-color: #444444;
    --filter-bg: #252525;
    --btn-outline-color: #adb5bd;
    --border-color: #444444;
    --toggle-bg: #555555;
    --button-bg: #2a2a2a;
    --button-color: #e0e0e0;
    --button-border: #444;
    --button-hover-bg: #3a3a3a;
    --footer-text: white;
    --input-bg: #2a2a2a;
    --input-color: #e0e0e0;
    --input-border: #444444;
    --input-focus-border: #0078d4;
    --input-focus-shadow: rgba(0, 120, 212, 0.25);
    --datatable-even-row-bg: #1e1e1e;
    --datatable-odd-row-bg: #252525;
    --tab-active-bg: #0078d4;
    --tab-active-color: #fff;
}
  
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    margin: 0;
    padding: 0;
    background-color: var(--bg-color);
    color: var(--text-color);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    transition: background-color 0.3s ease, color 0.3s ease;
}
  
.container-fluid {
    max-width: 1600px;
    padding: 20px;
    flex: 1;
}
  
.dashboard-header {
    padding: 20px 0;
    margin-bottom: 30px;
    border-bottom: 1px solid rgba(128,128,128,0.2);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
  
.dashboard-title {
    display: flex;
    align-items: center;
    gap: 15px;
}
  
.dashboard-title h1 {
    margin: 0;
    font-size: 1.8rem;
    font-weight: 600;
    color: var(--primary-color);
}
  
.logo {
    height: 45px;
    width: 45px;
}
  
.report-date {
    font-size: 0.9rem;
    color: var(--text-color);
    opacity: 0.8;
}
  
.card {
    border: none;
    border-radius: 10px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.05);
    margin-bottom: 25px;
    transition: transform 0.2s, box-shadow 0.2s, background-color 0.3s ease;
    overflow: hidden;
    background-color: var(--card-bg);
}
  
.card:hover {
    transform: translateY(-5px);
    box-shadow: 0 8px 16px rgba(0,0,0,0.1);
}
  
.card-header {
    background-color: var(--primary-color);
    color: white;
    font-weight: 600;
    padding: 15px 20px;
    border-bottom: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}
  
.card-header i {
    font-size: 1.2rem;
}
  
.card-body {
    padding: 20px;
}
  
.stats-card {
    height: 100%;
    text-align: center;
    padding: 8px 12px;
    border-radius: 6px;
    color: white;
    position: relative;
    overflow: hidden;
    min-height: 70px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    transition: all 0.3s;
}
  
.stats-card::before {
    content: '';
    position: absolute;
    top: -8px;
    right: -8px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background-color: rgba(255,255,255,0.1);
    z-index: 0;
}
  
.stats-card i {
    font-size: 1.2rem;
    margin-bottom: 4px;
    position: relative;
    z-index: 1;
}
  
.stats-card h3 {
    font-size: 0.65rem;
    font-weight: 500;
    margin-bottom: 4px;
    position: relative;
    z-index: 1;
    line-height: 1.0;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
}
  
.stats-card .number {
    font-size: 1.2rem;
    font-weight: 700;
    position: relative;
    z-index: 1;
}
  
.permanent-bg {
    background: linear-gradient(135deg, var(--permanent-color), #f25c05);
}
  
.eligible-bg {
    background: linear-gradient(135deg, var(--eligible-color), #2a9d2a);
}
  
.group-bg {
    background: linear-gradient(135deg, var(--group-color), #7b4db2);
}
  
.disabled-bg {
    background: linear-gradient(135deg, var(--disabled-color), #6c757d);
}
  
.enabled-bg {
    background: linear-gradient(135deg, var(--enabled-color), #0078d4);
}
  
.service-principal-bg {
    background: linear-gradient(135deg, var(--service-principal-color), #2b88d8);
}
  
table.dataTable {
    border-collapse: collapse !important;
    width: 100% !important;
    color: var(--text-color) !important;
    border-color: var(--table-border-color) !important;
}
  
.table {
    color: var(--text-color) !important;
    border-color: var(--table-border-color) !important;
}
  
.table-striped>tbody>tr:nth-of-type(odd) {
    background-color: var(--datatable-odd-row-bg) !important;
}
  
.table-striped>tbody>tr:nth-of-type(even) {
    background-color: var(--datatable-even-row-bg) !important;
}
  
.table thead th {
    background-color: var(--table-header-bg) !important;
    color: var(--table-header-color) !important;
    font-weight: 600;
    border-top: none;
    padding: 12px;
    border-color: var(--table-border-color) !important;
}
  
.table tbody td {
    padding: 12px;
    vertical-align: middle;
    border-color: var(--table-border-color) !important;
    color: var(--text-color) !important;
}
  
.table.table-bordered {
    border-color: var(--table-border-color) !important;
}
  
.table-bordered td, .table-bordered th {
    border-color: var(--table-border-color) !important;
}
  
.table-hover tbody tr:hover {
    background-color: var(--table-hover-bg) !important;
}
  
.badge {
    padding: 6px 10px;
    font-weight: 500;
    border-radius: 6px;
}
  
.badge-permanent {
    background-color: var(--permanent-color);
    color: white;
}
  
.badge-eligible {
    background-color: var(--eligible-color);
    color: white;
}
  
.badge-active {
    background-color: var(--service-principal-color);
    color: white;
}
  
.badge-group {
    background-color: var(--group-color);
    color: white;
}
  
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_processing,
.dataTables_wrapper .dataTables_paginate {
    color: var(--text-color) !important;
}
  
.dataTables_wrapper .dataTables_paginate .paginate_button {
    padding: 0.3em 0.8em;
    border-radius: 4px;
    margin: 0 3px;
    color: var(--text-color) !important;
    border: 1px solid var(--border-color) !important;
    background-color: var(--button-bg) !important;
}
  
.dataTables_wrapper .dataTables_paginate .paginate_button.current {
    background: var(--primary-color) !important;
    border-color: var(--primary-color) !important;
    color: white !important;
}
  
.dataTables_wrapper .dataTables_paginate .paginate_button:hover {
    background: var(--button-hover-bg) !important;
    border-color: var(--border-color) !important;
    color: var(--text-color) !important;
}
  
.dataTables_wrapper .dataTables_length select,
.dataTables_wrapper .dataTables_filter input {
    border: 1px solid var(--input-border);
    background-color: var(--input-bg);
    color: var(--input-color);
    border-radius: 4px;
    padding: 5px 10px;
}
  
.dataTables_wrapper .dataTables_filter input:focus {
    border-color: var(--input-focus-border);
    box-shadow: 0 0 0 0.25rem var(--input-focus-shadow);
}
  
.dataTables_info {
    padding-top: 10px;
    color: var(--text-color);
}
  
footer {
    background-color: var(--primary-color);
    color: var(--footer-text);
    text-align: center;
    padding: 15px 0;
    margin-top: auto;
}
  
footer p {
    margin: 0;
    font-weight: 500;
}
  
.toggle-switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 30px;
}
  
.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}
  
.toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--toggle-bg);
    transition: .4s;
    border-radius: 34px;
}
  
.toggle-slider:before {
    position: absolute;
    content: "";
    height: 22px;
    width: 22px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    transition: .4s;
    border-radius: 50%;
}
  
input:checked + .toggle-slider {
    background-color: var(--primary-color);
}
  
input:checked + .toggle-slider:before {
    transform: translateX(30px);
}
  
.show-all-container {
    display: flex;
    align-items: center;
    gap: 12px;
    background-color: transparent;
    padding: 0;
    border: none;
    margin-left: 15px;
}
  
.show-all-text {
    font-weight: 500;
    margin: 0;
    color: white;
    font-size: 0.85rem;
}
  
.theme-toggle {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 10px;
    background-color: var(--card-bg);
    padding: 8px 12px;
    border-radius: 30px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    transition: background-color 0.3s ease;
}
  
.theme-toggle-switch {
    position: relative;
    display: inline-block;
    width: 50px;
    height: 26px;
}
  
.theme-toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
}
  
.theme-toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--toggle-bg);
    transition: .4s;
    border-radius: 34px;
}
  
.theme-toggle-slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 4px;
    bottom: 4px;
    background-color: white;
    transition: .4s;
    border-radius: 50%;
}
  
input:checked + .theme-toggle-slider {
    background-color: var(--primary-color);
}
  
input:checked + .theme-toggle-slider:before {
    transform: translateX(24px);
}
  
.theme-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    color: var(--text-color);
}
  
.form-select, .form-control {
    background-color: var(--input-bg) !important;
    color: var(--input-color) !important;
    border-color: var(--input-border) !important;
}
  
.form-select:focus, .form-control:focus {
    border-color: var(--input-focus-border) !important;
    box-shadow: 0 0 0 0.25rem var(--input-focus-shadow) !important;
}
  
.form-label {
    color: var(--text-color);
}
  
.filter-container {
    background-color: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px;
}
  
.filter-row {
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    align-items: end;
}
  
.filter-group {
    flex: 1;
    min-width: 200px;
}
  
.filter-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: 500;
    color: var(--text-color);
}
  
.filter-buttons {
    display: flex;
    gap: 10px;
    align-items: end;
}
  
.btn-filter {
    padding: 8px 16px;
    border: none;
    border-radius: 4px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}
  
.btn-primary {
    background-color: var(--primary-color);
    color: white;
}
  
.btn-primary:hover {
    background-color: var(--secondary-color);
}
  
.btn-secondary {
    background-color: var(--button-bg);
    color: var(--button-color);
    border: 1px solid var(--button-border);
}
  
.btn-secondary:hover {
    background-color: var(--button-hover-bg);
}
  
.btn-outline-secondary {
    color: var(--text-color);
    border-color: var(--border-color);
    background-color: transparent;
}
  
.btn-outline-secondary:hover {
    background-color: var(--filter-tag-bg);
    color: var(--text-color);
}
  
.form-select option {
    background-color: var(--input-bg);
    color: var(--input-color);
}
  
table.dataTable.stripe tbody tr.odd,
table.dataTable.display tbody tr.odd {
    background-color: var(--datatable-odd-row-bg) !important;
}
  
table.dataTable.stripe tbody tr.even,
table.dataTable.display tbody tr.even {
    background-color: var(--datatable-even-row-bg) !important;
}
  
table.dataTable.hover tbody tr:hover,
table.dataTable.display tbody tr:hover {
    background-color: var(--table-hover-bg) !important;
}
  
table.dataTable.border-bottom,
table.dataTable.border-top,
table.dataTable thead th,
table.dataTable tfoot th,
table.dataTable thead td,
table.dataTable tfoot td {
    border-color: var(--table-border-color) !important;
}
  
.table-striped>tbody>tr:nth-of-type(odd)>* {
    --bs-table-accent-bg: var(--datatable-odd-row-bg) !important;
    color: var(--text-color) !important;
}
  
.table>:not(caption)>*>* {
    background-color: var(--card-bg) !important;
    color: var(--text-color) !important;
}
  
.table-striped>tbody>tr {
    background-color: var(--datatable-even-row-bg) !important;
}
  
.table tbody tr td {
    background-color: transparent !important;
}
  
.table-striped>tbody>tr:nth-of-type(odd) {
    --bs-table-accent-bg: var(--datatable-odd-row-bg) !important;
}
  
.report-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
}
  
.report-tab {
    padding: 10px 20px;
    border-radius: 5px;
    background-color: var(--button-bg);
    color: var(--button-color);
    border: 1px solid var(--button-border);
    cursor: pointer;
    font-weight: 600;
    transition: all 0.2s;
}
  
.report-tab:hover {
    background-color: var(--button-hover-bg);
}
  
.report-tab.active {
    background-color: var(--tab-active-bg);
    color: var(--tab-active-color);
    border-color: var(--tab-active-bg);
}
  
.report-panel {
    display: none;
}
  
.report-panel.active {
    display: block;
}
</style>
</head>
<body>
    <div class="theme-toggle">
        <div class="theme-icon">
            <i class="fas fa-sun"></i>
        </div>
        <label class="theme-toggle-switch">
            <input type="checkbox" id="themeToggle">
            <span class="theme-toggle-slider"></span>
        </label>
        <div class="theme-icon">
            <i class="fas fa-moon"></i>
        </div>
    </div>
      
    <div class="container-fluid">
        <div class="dashboard-header">
            <div class="dashboard-title">
                <svg class="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
                    <path fill="#ff5722" d="M6 6H22V22H6z" transform="rotate(-180 14 14)"/>
                    <path fill="#4caf50" d="M26 6H42V22H26z" transform="rotate(-180 34 14)"/>
                    <path fill="#ffc107" d="M6 26H22V42H6z" transform="rotate(-180 14 34)"/>
                    <path fill="#03a9f4" d="M26 26H42V42H26z" transform="rotate(-180 34 34)"/>
                </svg>
                <h1>$TenantName Intune Anomalies Report</h1>
            </div>
            <div class="report-date">
                <i class="fas fa-calendar-alt me-2"></i> Report generated on: $ReportDate
            </div>
        </div>
          
        <div class="row mb-4">
            <div class="col-md-4 mb-3">
                <div class="stats-card permanent-bg">
                    <i class="fas fa-exclamation-triangle"></i>
                    <h3>Application Failures</h3>
                    <div class="number">$applicationFailures</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card eligible-bg">
                    <i class="fas fa-users"></i>
                    <h3>Multiple users on non-shared devices</h3>
                    <div class="number">$multipleUsers</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card group-bg">
                    <i class="fas fa-shield-alt"></i>
                    <h3>Not Encrypted Devices</h3>
                    <div class="number">$notEncrypted</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card service-principal-bg">
                    <i class="fas fa-unlink"></i>
                    <h3>No Autopilot Hash</h3>
                    <div class="number">$noAutopilot</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card disabled-bg">
                    <i class="fas fa-clock"></i>
                    <h3>Inactive Devices</h3>
                    <div class="number">$inactiveDevices</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card enabled-bg">
                    <i class="fas fa-exclamation-circle"></i>
                    <h3>Noncompliant Devices</h3>
                    <div class="number">$noncompliantDevices</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card" style="background: linear-gradient(135deg, #ff6b35, #f7931e);">
                    <i class="fas fa-desktop"></i>
                    <h3>OS Edition Overview</h3>
                    <div class="number">$osEditionOverview</div>
                </div>
            </div>
            <div class="col-md-4 mb-3">
                <div class="stats-card" style="background: linear-gradient(135deg, #dc3545, #c82333);">
                    <i class="fas fa-user-slash"></i>
                    <h3>Disabled Primary Users</h3>
                    <div class="number">$disabledPrimaryUsers</div>
                </div>
            </div>
        </div>
  
        <div class="report-tabs">
            <div class="report-tab active" data-panel="application-failures">Application Failures</div>
            <div class="report-tab" data-panel="multiple-users">Multiple Users</div>
            <div class="report-tab" data-panel="not-encrypted">Not Encrypted</div>
            <div class="report-tab" data-panel="no-autopilot">No Autopilot Hash</div>
            <div class="report-tab" data-panel="inactive-devices">Inactive Devices</div>
            <div class="report-tab" data-panel="noncompliant-devices">Noncompliant</div>
            <div class="report-tab" data-panel="os-edition-overview">OS Edition Overview</div>
            <div class="report-tab" data-panel="disabled-primary-users">Disabled Primary Users</div>
              
        </div>
  
        <div id="application-failures" class="report-panel active">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-info-circle me-2"></i>
                <strong>Application Failures:</strong> Shows devices with failed application installations. If the failure count is high it might incidate a wrong packaged application.
            </div>
              
            <div class="filter-container">
                <div class="filter-row">
                    <div class="filter-group">
                        <label for="appFailuresCustomerFilter">Customer</label>
                        <select id="appFailuresCustomerFilter" class="form-select">
                            <option value="">All Customers</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="appFailuresAppFilter">Application</label>
                        <select id="appFailuresAppFilter" class="form-select">
                            <option value="">All Applications</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="appFailuresPlatformFilter">Platform</label>
                        <select id="appFailuresPlatformFilter" class="form-select">
                            <option value="">All Platforms</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="appFailuresVersionFilter">Version</label>
                        <select id="appFailuresVersionFilter" class="form-select">
                            <option value="">All Versions</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="appFailuresPercentageFilter">Failed Device Percentage</label>
                        <select id="appFailuresPercentageFilter" class="form-select">
                            <option value="">All Percentages</option>
                            <option value="0-20">0-20%</option>
                            <option value="20-40">20-40%</option>
                            <option value="40-60">40-60%</option>
                            <option value="60-80">60-80%</option>
                            <option value="80-100">80-100%</option>
                        </select>
                    </div>
                    <div class="filter-buttons">
                        <button class="btn-filter btn-secondary" onclick="clearAppFailuresFilters()">Clear</button>
                    </div>
                </div>
            </div>
              
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-exclamation-triangle"></i> Application Failures
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="appFailuresShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="appFailuresTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Application</th>
                                    <th>Platform</th>
                                    <th>Version</th>
                                    <th>Failed Device Count</th>
                                    <th>Failed Device Percentage</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{APPLICATION_FAILURES_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="multiple-users" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-exclamation-triangle me-2"></i>
                <strong>Multiple Users on user-driven device:</strong> Lists user-driven devices that have multiple users logged on. These devices should typically be re-enrolled as shared devices to ensure proper configuration and security.
            </div>
  
        <div class="filter-container">
            <div class="filter-row">
                <div class="filter-group">
                    <label for="multipleUsersCustomerFilter">Customer</label>
                    <select id="multipleUsersCustomerFilter" class="form-select">
                        <option value="">All Customers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="multipleUsersDeviceFilter">Device Name</label>
                    <select id="multipleUsersDeviceFilter" class="form-select">
                        <option value="">All Devices</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="multipleUsersPrimaryUserFilter">Primary User</label>
                    <select id="multipleUsersPrimaryUserFilter" class="form-select">
                        <option value="">All Users</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="multipleUsersProfileFilter">Enrollment Profile</label>
                    <select id="multipleUsersProfileFilter" class="form-select">
                        <option value="">All Profiles</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="multipleUsersCountFilter">User Count</label>
                    <select id="multipleUsersCountFilter" class="form-select">
                        <option value="">All Counts</option>
                        <option value="2">2 Users</option>
                        <option value="3">3 Users</option>
                        <option value="4+">4+ Users</option>
                    </select>
                </div>
                <div class="filter-buttons">
                    <button class="btn-filter btn-secondary" onclick="clearMultipleUsersFilters()">Clear</button>
                </div>
            </div>
        </div>
  
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-users"></i> Devices with Multiple Users
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="multipleUsersShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="multipleUsersTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Enrollment Profile</th>
                                    <th>User Count</th>
                                    <th>Logged On User IDs</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{MULTIPLE_USERS_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="not-encrypted" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-shield-alt me-2"></i>
                <strong>Not Encrypted Devices:</strong> Displays devices that are not Bitlocker encrypted. This represents a significant security risk as data on these devices could be accessed if the device is lost or stolen.
            </div>
  
        <div class="filter-container">
            <div class="filter-row">
                <div class="filter-group">
                    <label for="notEncryptedCustomerFilter">Customer</label>
                    <select id="notEncryptedCustomerFilter" class="form-select">
                        <option value="">All Customers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="notEncryptedDeviceFilter">Device Name</label>
                    <select id="notEncryptedDeviceFilter" class="form-select">
                        <option value="">All Devices</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="notEncryptedUserFilter">Primary User</label>
                    <select id="notEncryptedUserFilter" class="form-select">
                        <option value="">All Users</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="notEncryptedManufacturerFilter">Manufacturer</label>
                    <select id="notEncryptedManufacturerFilter" class="form-select">
                        <option value="">All Manufacturers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="notEncryptedModelFilter">Model</label>
                    <select id="notEncryptedModelFilter" class="form-select">
                        <option value="">All Models</option>
                    </select>
                </div>
                <div class="filter-buttons">
                    <button class="btn-filter btn-secondary" onclick="clearNotEncryptedFilters()">Clear</button>
                </div>
            </div>
        </div>
  
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-shield-alt"></i> Not Encrypted Devices
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="notEncryptedShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="notEncryptedTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Serial Number</th>
                                    <th>Manufacturer</th>
                                    <th>Model</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{NOT_ENCRYPTED_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="no-autopilot" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-plane me-2"></i>
                <strong>Non-company owned devices:</strong> Shows devices that are missing their hardware hash in Autopilot. These devices can get lost or stolen, and without the hash, they cannot be managed by Autopilot. This can lead to security risks and management challenges.
            </div>
  
        <div class="filter-container">
            <div class="filter-row">
                <div class="filter-group">
                    <label for="noAutopilotCustomerFilter">Customer</label>
                    <select id="noAutopilotCustomerFilter" class="form-select">
                        <option value="">All Customers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noAutopilotDeviceFilter">Device Name</label>
                    <select id="noAutopilotDeviceFilter" class="form-select">
                        <option value="">All Devices</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noAutopilotUserFilter">Primary User</label>
                    <select id="noAutopilotUserFilter" class="form-select">
                        <option value="">All Users</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noAutopilotManufacturerFilter">Manufacturer</label>
                    <select id="noAutopilotManufacturerFilter" class="form-select">
                        <option value="">All Manufacturers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noAutopilotModelFilter">Model</label>
                    <select id="noAutopilotModelFilter" class="form-select">
                        <option value="">All Models</option>
                    </select>
                </div>
                <div class="filter-buttons">
                    <button class="btn-filter btn-secondary" onclick="clearNoAutopilotFilters()">Clear</button>
                </div>
            </div>
        </div>
  
        <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-plane"></i> Non-company owned devices
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="noAutopilotShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="noAutopilotTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Serial Number</th>
                                    <th>Manufacturer</th>
                                    <th>Model</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{NO_AUTOPILOT_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="inactive-devices" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-clock me-2"></i>
                <strong>Inactive Devices (90+ days):</strong> Lists devices that haven't contacted Intune in 90 or more days. These devices may be decommissioned, lost, or experiencing connectivity issues and should be reviewed for cleanup.
            </div>
  
        <div class="filter-container">
            <div class="filter-row">
                <div class="filter-group">
                    <label for="inactiveCustomerFilter">Customer</label>
                    <select id="inactiveCustomerFilter" class="form-select">
                        <option value="">All Customers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="inactiveDeviceFilter">Device Name</label>
                    <select id="inactiveDeviceFilter" class="form-select">
                        <option value="">All Devices</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="inactiveUserFilter">Primary User</label>
                    <select id="inactiveUserFilter" class="form-select">
                        <option value="">All Users</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="inactiveManufacturerFilter">Manufacturer</label>
                    <select id="inactiveManufacturerFilter" class="form-select">
                        <option value="">All Manufacturers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="inactiveModelFilter">Model</label>
                    <select id="inactiveModelFilter" class="form-select">
                        <option value="">All Models</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="inactiveInactivityFilter">Inactivity Period</label>
                    <select id="inactiveInactivityFilter" class="form-select">
                        <option value="">All Periods</option>
                        <option value="90-180">90-180 days</option>
                        <option value="180+">180+ days</option>
                    </select>
                </div>
                <div class="filter-buttons">
                    <button class="btn-filter btn-secondary" onclick="clearInactiveFilters()">Clear</button>
                </div>
            </div>
        </div>
  
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-clock"></i> Inactive Devices (90+ days)
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="inactiveDevicesShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="inactiveDevicesTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Serial Number</th>
                                    <th>Manufacturer</th>
                                    <th>Model</th>
                                    <th>Last Contact</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{INACTIVE_DEVICES_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="noncompliant-devices" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-exclamation-circle me-2"></i>
                <strong>Noncompliant Devices:</strong> Displays devices that don't meet your organization's compliance policies. These devices may have security vulnerabilities or configuration issues that need immediate attention to maintain security standards.
        </div>
  
        <div class="filter-container">
            <div class="filter-row">
                <div class="filter-group">
                    <label for="noncompliantCustomerFilter">Customer</label>
                    <select id="noncompliantCustomerFilter" class="form-select">
                        <option value="">All Customers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noncompliantDeviceFilter">Device Name</label>
                    <select id="noncompliantDeviceFilter" class="form-select">
                        <option value="">All Devices</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noncompliantUserFilter">Primary User</label>
                    <select id="noncompliantUserFilter" class="form-select">
                        <option value="">All Users</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noncompliantManufacturerFilter">Manufacturer</label>
                    <select id="noncompliantManufacturerFilter" class="form-select">
                        <option value="">All Manufacturers</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noncompliantModelFilter">Model</label>
                    <select id="noncompliantModelFilter" class="form-select">
                        <option value="">All Models</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label for="noncompliantReasonFilter">Noncompliant Reason</label>
                    <select id="noncompliantReasonFilter" class="form-select">
                        <option value="">All Reasons</option>
                    </select>
                </div>
                <div class="filter-buttons">
                    <button class="btn-filter btn-secondary" onclick="clearNoncompliantFilters()">Clear</button>
                </div>
            </div>
        </div>
  
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-exclamation-circle"></i> Noncompliant Devices
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="noncompliantShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="noncompliantTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Serial Number</th>
                                    <th>Manufacturer</th>
                                    <th>Model</th>
                                    <th>Compliance Status</th>
                                    <th>Noncompliant Based On</th>
                                    <th>Noncompliant Alert</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{NONCOMPLIANT_DEVICES_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="os-edition-overview" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-desktop me-2"></i>
                <strong>Operating System Edition Overview:</strong> Provides a comprehensive view of device operating system editions across your environment. This helps identify devices that may need OS edition upgrades (e.g., Pro to Enterprise) for enhanced management and security features.
            </div>
  
            <div class="filter-container">
                <div class="filter-row">
                    <div class="filter-group">
                        <label for="osEditionCustomerFilter">Customer</label>
                        <select id="osEditionCustomerFilter" class="form-select">
                            <option value="">All Customers</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="osEditionDeviceFilter">Device Name</label>
                        <select id="osEditionDeviceFilter" class="form-select">
                            <option value="">All Devices</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="osEditionUserFilter">Primary User</label>
                        <select id="osEditionUserFilter" class="form-select">
                            <option value="">All Users</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="osEditionEditionFilter">OS Edition</label>
                        <select id="osEditionEditionFilter" class="form-select">
                            <option value="">All Editions</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="osEditionFriendlyNameFilter">OS Friendly Name</label>
                        <select id="osEditionFriendlyNameFilter" class="form-select">
                            <option value="">All OS Versions</option>
                        </select>
                    </div>
                    <div class="filter-buttons">
                        <button class="btn-filter btn-secondary" onclick="clearOSEditionFilters()">Clear</button>
                    </div>
                </div>
            </div>
  
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-desktop"></i> Operating System Edition Overview
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="osEditionShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="osEditionTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Operating System Edition</th>
                                    <th>OS Friendly Name</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{OS_EDITION_OVERVIEW_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
  
        <div id="disabled-primary-users" class="report-panel">
            <div class="alert alert-info mb-3" role="alert">
                <i class="fas fa-user-slash me-2"></i>
                <strong>Devices with Disabled Primary Users:</strong> Shows devices where the primary user account has been disabled in Microsoft Entra ID. These devices may need to be reassigned to active users or cleaned up to maintain security and proper device management.
            </div>
  
            <div class="filter-container">
                <div class="filter-row">
                    <div class="filter-group">
                        <label for="disabledUsersCustomerFilter">Customer</label>
                        <select id="disabledUsersCustomerFilter" class="form-select">
                            <option value="">All Customers</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="disabledUsersDeviceFilter">Device Name</label>
                        <select id="disabledUsersDeviceFilter" class="form-select">
                            <option value="">All Devices</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="disabledUsersUserFilter">Primary User</label>
                        <select id="disabledUsersUserFilter" class="form-select">
                            <option value="">All Users</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="disabledUsersManufacturerFilter">Manufacturer</label>
                        <select id="disabledUsersManufacturerFilter" class="form-select">
                            <option value="">All Manufacturers</option>
                        </select>
                    </div>
                    <div class="filter-group">
                        <label for="disabledUsersModelFilter">Model</label>
                        <select id="disabledUsersModelFilter" class="form-select">
                            <option value="">All Models</option>
                        </select>
                    </div>
                    <div class="filter-buttons">
                        <button class="btn-filter btn-secondary" onclick="clearDisabledUsersFilters()">Clear</button>
                    </div>
                </div>
            </div>
  
            <div class="card">
                <div class="card-header">
                    <div>
                        <i class="fas fa-user-slash"></i> Devices with Disabled Primary Users
                    </div>
                    <div class="show-all-container">
                        <label class="toggle-switch">
                            <input type="checkbox" id="disabledUsersShowAllToggle">
                            <span class="toggle-slider"></span>
                        </label>
                        <p class="show-all-text">Show all entries</p>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table id="disabledUsersTable" class="table table-striped table-bordered" style="width:100%">
                            <thead>
                                <tr>
                                    <th>Customer</th>
                                    <th>Device Name</th>
                                    <th>Primary User</th>
                                    <th>Serial Number</th>
                                    <th>Manufacturer</th>
                                    <th>Model</th>
                                </tr>
                            </thead>
                            <tbody>
                                {{DISABLED_PRIMARY_USERS_DATA}}
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
          
    </div>
    <footer>
        <p>Generated by Roy Klooster - RK Solutions</p>
    </footer>
      
    <script>
        $(document).ready(function() {
            const themeToggle = document.getElementById('themeToggle');
            const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
              
            function updateTableColors() {
                if (document.documentElement.getAttribute('data-theme') === 'dark') {
                    $('table.dataTable tbody tr').css('background-color', 'var(--datatable-even-row-bg)');
                    $('table.dataTable tbody tr:nth-child(odd)').css('background-color', 'var(--datatable-odd-row-bg)');
                    $('table.dataTable tbody td').css('color', 'var(--text-color)');
                    $('table.dataTable thead th').css({
                        'background-color': 'var(--table-header-bg)',
                        'color': 'var(--table-header-color)'
                    });
                } else {
                    $('table.dataTable tbody tr').css('background-color', 'var(--datatable-even-row-bg)');
                    $('table.dataTable tbody tr:nth-child(odd)').css('background-color', 'var(--datatable-odd-row-bg)');
                    $('table.dataTable tbody td').css('color', 'var(--text-color)');
                    $('table.dataTable thead th').css({
                        'background-color': 'var(--table-header-bg)',
                        'color': 'var(--table-header-color)'
                    });
                }
            }
              
            const savedTheme = localStorage.getItem('theme');
            if (savedTheme === 'dark' || (!savedTheme && prefersDarkScheme.matches)) {
                document.documentElement.setAttribute('data-theme', 'dark');
                themeToggle.checked = true;
            }
              
            themeToggle.addEventListener('change', function() {
                if (this.checked) {
                    document.documentElement.setAttribute('data-theme', 'dark');
                    localStorage.setItem('theme', 'dark');
                } else {
                    document.documentElement.setAttribute('data-theme', 'light');
                    localStorage.setItem('theme', 'light');
                }
                setTimeout(updateTableColors, 50);
            });
              
            $('.report-tab').on('click', function() {
                $('.report-tab').removeClass('active');
                $('.report-panel').removeClass('active');
                $(this).addClass('active');
                const panelId = $(this).data('panel');
                $(`#${panelId}`).addClass('active');
                setTimeout(function() {
                    $.fn.dataTable.tables({ visible: true, api: true }).columns.adjust();
                }, 10);
            });
              
            const tableOptions = {
                dom: 'Bfrtip',
                buttons: [
                    { extend: 'collection', text: '<i class="fas fa-download"></i> Export',
                    buttons: [
                        { extend: 'excel', text: '<i class="fas fa-file-excel"></i> Excel', exportOptions: { columns: ':visible' } },
                        { extend: 'csv', text: '<i class="fas fa-file-csv"></i> CSV', exportOptions: { columns: ':visible' } },
                        { extend: 'pdf', text: '<i class="fas fa-file-pdf"></i> PDF', exportOptions: { columns: ':visible' } },
                        { extend: 'print', text: '<i class="fas fa-print"></i> Print', exportOptions: { columns: ':visible' } }
                    ]
                    },
                    { extend: 'colvis', text: '<i class="fas fa-columns"></i> Columns' }
                ],
                paging: true, searching: true, ordering: true, info: true, responsive: true,
                lengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
                order: [[1, 'asc']],
                language: { search: "<i class='fas fa-search'></i> _INPUT_", searchPlaceholder: "Search records..." },
                drawCallback: function() { updateTableColors(); }
            };
              
            const appFailuresTable = $('#appFailuresTable').DataTable(tableOptions);
            const multipleUsersTable = $('#multipleUsersTable').DataTable({...tableOptions, order: [[4, 'desc']]});
            const notEncryptedTable = $('#notEncryptedTable').DataTable(tableOptions);
            const noAutopilotTable = $('#noAutopilotTable').DataTable(tableOptions);
            const inactiveDevicesTable = $('#inactiveDevicesTable').DataTable({...tableOptions, order: [[6, 'asc']]});
            const noncompliantTable = $('#noncompliantTable').DataTable(tableOptions);
            const osEditionTable = $('#osEditionTable').DataTable(tableOptions);
            const disabledUsersTable = $('#disabledUsersTable').DataTable(tableOptions);
              
            // Populate filter dropdowns
            function populateFilters() {
                // Application Failures filters
                populateSelectFromColumn('appFailuresCustomerFilter', appFailuresTable, 0); // Customer
                populateSelectFromColumn('appFailuresAppFilter', appFailuresTable, 1); // Application
                populateSelectFromColumn('appFailuresPlatformFilter', appFailuresTable, 2); // Platform
                populateSelectFromColumn('appFailuresVersionFilter', appFailuresTable, 3); // Version
                // Note: Percentage filter uses predefined ranges, no need to populate from data
                  
                // Multiple Users filters
                populateSelectFromColumn('multipleUsersCustomerFilter', multipleUsersTable, 0);
                populateSelectFromColumn('multipleUsersDeviceFilter', multipleUsersTable, 1);
                populateSelectFromColumn('multipleUsersPrimaryUserFilter', multipleUsersTable, 2);
                populateSelectFromColumn('multipleUsersProfileFilter', multipleUsersTable, 3);
                  
                // Not Encrypted filters
                populateSelectFromColumn('notEncryptedCustomerFilter', notEncryptedTable, 0);
                populateSelectFromColumn('notEncryptedDeviceFilter', notEncryptedTable, 1);
                populateSelectFromColumn('notEncryptedUserFilter', notEncryptedTable, 2);
                populateSelectFromColumn('notEncryptedManufacturerFilter', notEncryptedTable, 4);
                populateSelectFromColumn('notEncryptedModelFilter', notEncryptedTable, 5);
                  
                // No Autopilot filters
                populateSelectFromColumn('noAutopilotCustomerFilter', noAutopilotTable, 0);
                populateSelectFromColumn('noAutopilotDeviceFilter', noAutopilotTable, 1);
                populateSelectFromColumn('noAutopilotUserFilter', noAutopilotTable, 2);
                populateSelectFromColumn('noAutopilotManufacturerFilter', noAutopilotTable, 4);
                populateSelectFromColumn('noAutopilotModelFilter', noAutopilotTable, 5);
                  
                // Inactive Devices filters
                populateSelectFromColumn('inactiveCustomerFilter', inactiveDevicesTable, 0);
                populateSelectFromColumn('inactiveDeviceFilter', inactiveDevicesTable, 1);
                populateSelectFromColumn('inactiveUserFilter', inactiveDevicesTable, 2);
                populateSelectFromColumn('inactiveManufacturerFilter', inactiveDevicesTable, 4);
                populateSelectFromColumn('inactiveModelFilter', inactiveDevicesTable, 5);
                  
                // Noncompliant Devices filters
                populateSelectFromColumn('noncompliantCustomerFilter', noncompliantTable, 0);
                populateSelectFromColumn('noncompliantDeviceFilter', noncompliantTable, 1);
                populateSelectFromColumn('noncompliantUserFilter', noncompliantTable, 2);
                populateSelectFromColumn('noncompliantManufacturerFilter', noncompliantTable, 4);
                populateSelectFromColumn('noncompliantModelFilter', noncompliantTable, 5);
                populateSelectFromColumn('noncompliantReasonFilter', noncompliantTable, 7);
  
                // OS Edition Overview filters
                populateSelectFromColumn('osEditionCustomerFilter', osEditionTable, 0);
                populateSelectFromColumn('osEditionDeviceFilter', osEditionTable, 1);
                populateSelectFromColumn('osEditionUserFilter', osEditionTable, 2);
                populateSelectFromColumn('osEditionEditionFilter', osEditionTable, 3);
                populateSelectFromColumn('osEditionFriendlyNameFilter', osEditionTable, 4);
  
                // Disabled Primary Users filters
                populateSelectFromColumn('disabledUsersCustomerFilter', disabledUsersTable, 0);
                populateSelectFromColumn('disabledUsersDeviceFilter', disabledUsersTable, 1);
                populateSelectFromColumn('disabledUsersUserFilter', disabledUsersTable, 2);
                populateSelectFromColumn('disabledUsersManufacturerFilter', disabledUsersTable, 4);
                populateSelectFromColumn('disabledUsersModelFilter', disabledUsersTable, 5);
            }
              
            function populateSelectFromColumn(selectId, table, columnIndex) {
                const values = [...new Set(table.column(columnIndex).data().toArray())].sort();
                const select = $(`#${selectId}`);
                values.forEach(value => {
                    if (value && value.trim() !== '') {
                        select.append(`<option value="${value}">${value}</option>`);
                    }
                });
            }
              
            // Application Failures filter functions
            window.applyAppFailuresFilters = function() {
                const customerFilter = $('#appFailuresCustomerFilter').val();
                const appFilter = $('#appFailuresAppFilter').val();
                const platformFilter = $('#appFailuresPlatformFilter').val();
                const versionFilter = $('#appFailuresVersionFilter').val();
                const percentageFilter = $('#appFailuresPercentageFilter').val();
                  
                appFailuresTable.columns().search('').draw();
                  
                if (customerFilter) appFailuresTable.column(0).search('^' + customerFilter + '$', true, false);
                if (appFilter) appFailuresTable.column(1).search('^' + appFilter + '$', true, false);
                if (platformFilter) appFailuresTable.column(2).search('^' + platformFilter + '$', true, false);
                if (versionFilter) appFailuresTable.column(3).search('^' + versionFilter + '$', true, false);
                if (percentageFilter) {
                    let regex = '';
                    if (percentageFilter === '0-20') {
                        regex = '^(0|[1-9]|1[0-9]|20)%$';
                    } else if (percentageFilter === '20-40') {
                        regex = '^(2[0-9]|3[0-9]|40)%$';
                    } else if (percentageFilter === '40-60') {
                        regex = '^(4[0-9]|5[0-9]|60)%$';
                    } else if (percentageFilter === '60-80') {
                        regex = '^(6[0-9]|7[0-9]|80)%$';
                    } else if (percentageFilter === '80-100') {
                        regex = '^(8[0-9]|9[0-9]|100)%$';
                    }
                    if (regex) appFailuresTable.column(5).search(regex, true, false);
                }
                  
                appFailuresTable.draw();
            };
  
            window.clearAppFailuresFilters = function() {
                $('#appFailuresCustomerFilter, #appFailuresAppFilter, #appFailuresPlatformFilter, #appFailuresVersionFilter, #appFailuresPercentageFilter').val('');
                appFailuresTable.search('').columns().search('').draw();
            };
  
            // Multiple Users filter functions
            window.applyMultipleUsersFilters = function() {
                const customerFilter = $('#multipleUsersCustomerFilter').val();
                const deviceFilter = $('#multipleUsersDeviceFilter').val();
                const userFilter = $('#multipleUsersPrimaryUserFilter').val();
                const profileFilter = $('#multipleUsersProfileFilter').val();
                const countFilter = $('#multipleUsersCountFilter').val();
                  
                multipleUsersTable.columns().search('').draw();
                  
                if (customerFilter) multipleUsersTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) multipleUsersTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) multipleUsersTable.column(2).search('^' + userFilter + '$', true, false);
                if (profileFilter) multipleUsersTable.column(3).search('^' + profileFilter + '$', true, false);
                if (countFilter) {
                    if (countFilter === '2') multipleUsersTable.column(4).search('^2$', true, false);
                    else if (countFilter === '3') multipleUsersTable.column(4).search('^3$', true, false);
                    else if (countFilter === '4+') multipleUsersTable.column(4).search('[4-9]|[1-9][0-9]+', true, false);
                }
                  
                multipleUsersTable.draw();
            };
  
            window.clearMultipleUsersFilters = function() {
                $('#multipleUsersCustomerFilter, #multipleUsersDeviceFilter, #multipleUsersPrimaryUserFilter, #multipleUsersProfileFilter, #multipleUsersCountFilter').val('');
                multipleUsersTable.search('').columns().search('').draw();
            };
  
            // Not Encrypted filter functions
            window.applyNotEncryptedFilters = function() {
                const customerFilter = $('#notEncryptedCustomerFilter').val();
                const deviceFilter = $('#notEncryptedDeviceFilter').val();
                const userFilter = $('#notEncryptedUserFilter').val();
                const manufacturerFilter = $('#notEncryptedManufacturerFilter').val();
                const modelFilter = $('#notEncryptedModelFilter').val();
                  
                notEncryptedTable.columns().search('').draw();
                  
                if (customerFilter) notEncryptedTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) notEncryptedTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) notEncryptedTable.column(2).search('^' + userFilter + '$', true, false);
                if (manufacturerFilter) notEncryptedTable.column(4).search('^' + manufacturerFilter + '$', true, false);
                if (modelFilter) notEncryptedTable.column(5).search('^' + modelFilter + '$', true, false);
                  
                notEncryptedTable.draw();
            };
  
            window.clearNotEncryptedFilters = function() {
                $('#notEncryptedCustomerFilter, #notEncryptedDeviceFilter, #notEncryptedUserFilter, #notEncryptedManufacturerFilter, #notEncryptedModelFilter').val('');
                notEncryptedTable.search('').columns().search('').draw();
            };
  
            // No Autopilot filter functions
            window.applyNoAutopilotFilters = function() {
                const customerFilter = $('#noAutopilotCustomerFilter').val();
                const deviceFilter = $('#noAutopilotDeviceFilter').val();
                const userFilter = $('#noAutopilotUserFilter').val();
                const manufacturerFilter = $('#noAutopilotManufacturerFilter').val();
                const modelFilter = $('#noAutopilotModelFilter').val();
                  
                noAutopilotTable.columns().search('').draw();
                  
                if (customerFilter) noAutopilotTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) noAutopilotTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) noAutopilotTable.column(2).search('^' + userFilter + '$', true, false);
                if (manufacturerFilter) noAutopilotTable.column(4).search('^' + manufacturerFilter + '$', true, false);
                if (modelFilter) noAutopilotTable.column(5).search('^' + modelFilter + '$', true, false);
                  
                noAutopilotTable.draw();
            };
  
            window.clearNoAutopilotFilters = function() {
                $('#noAutopilotCustomerFilter, #noAutopilotDeviceFilter, #noAutopilotUserFilter, #noAutopilotManufacturerFilter, #noAutopilotModelFilter').val('');
                noAutopilotTable.search('').columns().search('').draw();
            };
  
            // Inactive Devices filter functions
            window.applyInactiveFilters = function() {
                const customerFilter = $('#inactiveCustomerFilter').val();
                const deviceFilter = $('#inactiveDeviceFilter').val();
                const userFilter = $('#inactiveUserFilter').val();
                const manufacturerFilter = $('#inactiveManufacturerFilter').val();
                const modelFilter = $('#inactiveModelFilter').val();
                const inactivityFilter = $('#inactiveInactivityFilter').val();
                  
                inactiveDevicesTable.columns().search('').draw();
                  
                if (customerFilter) inactiveDevicesTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) inactiveDevicesTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) inactiveDevicesTable.column(2).search('^' + userFilter + '$', true, false);
                if (manufacturerFilter) inactiveDevicesTable.column(4).search('^' + manufacturerFilter + '$', true, false);
                if (modelFilter) inactiveDevicesTable.column(5).search('^' + modelFilter + '$', true, false);
                  
                inactiveDevicesTable.draw();
            };
  
            window.clearInactiveFilters = function() {
                $('#inactiveCustomerFilter, #inactiveDeviceFilter, #inactiveUserFilter, #inactiveManufacturerFilter, #inactiveModelFilter, #inactiveInactivityFilter').val('');
                inactiveDevicesTable.search('').columns().search('').draw();
            };
  
            // Noncompliant Devices filter functions
            window.applyNoncompliantFilters = function() {
                const customerFilter = $('#noncompliantCustomerFilter').val();
                const deviceFilter = $('#noncompliantDeviceFilter').val();
                const userFilter = $('#noncompliantUserFilter').val();
                const manufacturerFilter = $('#noncompliantManufacturerFilter').val();
                const modelFilter = $('#noncompliantModelFilter').val();
                const reasonFilter = $('#noncompliantReasonFilter').val();
                  
                noncompliantTable.columns().search('').draw();
                  
                if (customerFilter) noncompliantTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) noncompliantTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) noncompliantTable.column(2).search('^' + userFilter + '$', true, false);
                if (manufacturerFilter) noncompliantTable.column(4).search('^' + manufacturerFilter + '$', true, false);
                if (modelFilter) noncompliantTable.column(5).search('^' + modelFilter + '$', true, false);
                if (reasonFilter) noncompliantTable.column(7).search('^' + reasonFilter + '$', true, false);
                  
                noncompliantTable.draw();
            };
  
            // OS Edition Overview filter functions
            window.applyOSEditionFilters = function() {
                const customerFilter = $('#osEditionCustomerFilter').val();
                const deviceFilter = $('#osEditionDeviceFilter').val();
                const userFilter = $('#osEditionUserFilter').val();
                const editionFilter = $('#osEditionEditionFilter').val();
                const friendlyNameFilter = $('#osEditionFriendlyNameFilter').val();
                  
                osEditionTable.columns().search('').draw();
                  
                if (customerFilter) osEditionTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) osEditionTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) osEditionTable.column(2).search('^' + userFilter + '$', true, false);
                if (editionFilter) osEditionTable.column(3).search('^' + editionFilter + '$', true, false);
                if (friendlyNameFilter) osEditionTable.column(4).search('^' + friendlyNameFilter + '$', true, false);
                  
                osEditionTable.draw();
            };
  
            // Disabled Primary Users filter functions
            window.applyDisabledUsersFilters = function() {
                const customerFilter = $('#disabledUsersCustomerFilter').val();
                const deviceFilter = $('#disabledUsersDeviceFilter').val();
                const userFilter = $('#disabledUsersUserFilter').val();
                const manufacturerFilter = $('#disabledUsersManufacturerFilter').val();
                const modelFilter = $('#disabledUsersModelFilter').val();
                  
                disabledUsersTable.columns().search('').draw();
                  
                if (customerFilter) disabledUsersTable.column(0).search('^' + customerFilter + '$', true, false);
                if (deviceFilter) disabledUsersTable.column(1).search('^' + deviceFilter + '$', true, false);
                if (userFilter) disabledUsersTable.column(2).search('^' + userFilter + '$', true, false);
                if (manufacturerFilter) disabledUsersTable.column(4).search('^' + manufacturerFilter + '$', true, false);
                if (modelFilter) disabledUsersTable.column(5).search('^' + modelFilter + '$', true, false);
                  
                disabledUsersTable.draw();
            };
  
            window.clearDisabledUsersFilters = function() {
                $('#disabledUsersCustomerFilter, #disabledUsersDeviceFilter, #disabledUsersUserFilter, #disabledUsersManufacturerFilter, #disabledUsersModelFilter').val('');
                disabledUsersTable.search('').columns().search('').draw();
            };
  
            // Auto-apply filters on change - Disabled Primary Users
            $('#disabledUsersCustomerFilter, #disabledUsersDeviceFilter, #disabledUsersUserFilter, #disabledUsersManufacturerFilter, #disabledUsersModelFilter').on('change', function() {
                applyDisabledUsersFilters();
            });
  
            $('#disabledUsersShowAllToggle').on('change', function() {
                disabledUsersTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
  
            window.clearOSEditionFilters = function() {
                $('#osEditionCustomerFilter, #osEditionDeviceFilter, #osEditionUserFilter, #osEditionEditionFilter, #osEditionFriendlyNameFilter').val('');
                osEditionTable.search('').columns().search('').draw();
            };
  
            window.clearNoncompliantFilters = function() {
                $('#noncompliantCustomerFilter, #noncompliantDeviceFilter, #noncompliantUserFilter, #noncompliantManufacturerFilter, #noncompliantModelFilter, #noncompliantReasonFilter').val('');
                noncompliantTable.search('').columns().search('').draw();
            };
  
            // Add automatic filter event listeners after the tables are initialized
            // Add this after the existing table initialization code and before the setTimeout function:
  
            // Auto-apply filters on change - Application Failures
            $('#appFailuresCustomerFilter, #appFailuresAppFilter, #appFailuresPlatformFilter, #appFailuresVersionFilter, #appFailuresPercentageFilter').on('change', function() {
                applyAppFailuresFilters();
            });
  
            // Auto-apply filters on change - Multiple Users
            $('#multipleUsersCustomerFilter, #multipleUsersDeviceFilter, #multipleUsersPrimaryUserFilter, #multipleUsersProfileFilter, #multipleUsersCountFilter').on('change', function() {
                applyMultipleUsersFilters();
            });
  
            // Auto-apply filters on change - Not Encrypted
            $('#notEncryptedCustomerFilter, #notEncryptedDeviceFilter, #notEncryptedUserFilter, #notEncryptedManufacturerFilter, #notEncryptedModelFilter').on('change', function() {
                applyNotEncryptedFilters();
            });
  
            // Auto-apply filters on change - No Autopilot
            $('#noAutopilotCustomerFilter, #noAutopilotDeviceFilter, #noAutopilotUserFilter, #noAutopilotManufacturerFilter, #noAutopilotModelFilter').on('change', function() {
                applyNoAutopilotFilters();
            });
  
            // Auto-apply filters on change - Inactive Devices
            $('#inactiveCustomerFilter, #inactiveDeviceFilter, #inactiveUserFilter, #inactiveManufacturerFilter, #inactiveModelFilter, #inactiveInactivityFilter').on('change', function() {
                applyInactiveFilters();
            });
  
            // Auto-apply filters on change - Noncompliant Devices
            $('#noncompliantCustomerFilter, #noncompliantDeviceFilter, #noncompliantUserFilter, #noncompliantManufacturerFilter, #noncompliantModelFilter, #noncompliantReasonFilter').on('change', function() {
                applyNoncompliantFilters();
            });
  
            // Auto-apply filters on change - OS Edition Overview
            $('#osEditionCustomerFilter, #osEditionDeviceFilter, #osEditionUserFilter, #osEditionEditionFilter, #osEditionFriendlyNameFilter').on('change', function() {
                applyOSEditionFilters();
            });
              
            // Show all toggle functions for each table
            $('#appFailuresShowAllToggle').on('change', function() {
                appFailuresTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
              
            $('#multipleUsersShowAllToggle').on('change', function() {
                multipleUsersTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
              
            $('#notEncryptedShowAllToggle').on('change', function() {
                notEncryptedTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
              
            $('#noAutopilotShowAllToggle').on('change', function() {
                noAutopilotTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
              
            $('#inactiveDevicesShowAllToggle').on('change', function() {
                inactiveDevicesTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
              
            $('#noncompliantShowAllToggle').on('change', function() {
                noncompliantTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
  
            $('#osEditionShowAllToggle').on('change', function() {
                osEditionTable.page.len($(this).is(':checked') ? -1 : 10).draw();
            });
              
            setTimeout(function() {
                populateFilters();
                updateTableColors();
            }, 100);
              
            $(window).on('load', function() {
                setTimeout(updateTableColors, 200);
            });
        });
        </script>
</body>
</html>
'@

    
    # Generate table rows for all application failures
    $applicationFailureRows = ""
    foreach ($item in $Report_ApplicationFailureReport) {
        $applicationFailureRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.Application)</td>
            <td>$($item.Platform)</td>
            <td>$($item.Version)</td>
            <td>$($item.FailedDeviceCount)</td>
            <td>$($item.FailedDevicePercentage)%</td>
        </tr>
"@

    }

    # Generate table rows for devices with multiple users
    $multipleUsersRows = ""
    foreach ($item in $Report_DevicesWithMultipleUsers) {
        $multipleUsersRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td>$($item.PrimaryUser)</td>
            <td>$($item.EnrollmentProfile)</td>
            <td><span class="badge badge-permanent">$($item.usersLoggedOnCount)</span></td>
            <td>$($item.usersLoggedOnIds)</td>
        </tr>
"@

    }

    # Generate table rows for not encrypted devices
    $notEncryptedRows = ""
    foreach ($item in $Report_NotEncryptedDevices) {
        $notEncryptedRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td>$($item.PrimaryUser)</td>
            <td>$($item.Serialnumber)</td>
            <td>$($item.DeviceManufacturer)</td>
            <td>$($item.DeviceModel)</td>
        </tr>
"@

    }

    # Generate table rows for Non-company owned devices
    $noAutopilotHashRows = ""
    foreach ($item in $Report_DevicesWithoutAutopilotHash) {
        $noAutopilotHashRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td>$($item.PrimaryUser)</td>
            <td>$($item.Serialnumber)</td>
            <td>$($item.DeviceManufacturer)</td>
            <td>$($item.DeviceModel)</td>
        </tr>
"@

    }

    # Generate table rows for inactive devices
    $inactiveDevicesRows = ""
    foreach ($item in $Report_InactiveDevices) {
        $inactiveDevicesRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td>$($item.PrimaryUser)</td>
            <td>$($item.Serialnumber)</td>
            <td>$($item.DeviceManufacturer)</td>
            <td>$($item.DeviceModel)</td>
            <td>$($item.LastContact)</td>
        </tr>
"@

    }

    # Generate table rows for noncompliant devices
    $noncompliantDevicesRows = ""
    foreach ($item in $Report_NoncompliantDevices) {
        $statusBadge = '<span class="badge badge-permanent">Noncompliant</span>'
        
        $noncompliantDevicesRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td>$($item.PrimaryUser)</td>
            <td>$($item.Serialnumber)</td>
            <td>$($item.DeviceManufacturer)</td>
            <td>$($item.DeviceModel)</td>
            <td>$statusBadge</td>
            <td>$($item.NoncompliantBasedOn)</td>
            <td>$($item.NoncompliantAlert)</td>
        </tr>
"@

    }

    # Generate table rows for OS Edition Overview
    $osEditionOverviewRows = ""
    foreach ($item in $Report_OperationSystemEdtionOverview) {
        $osEditionOverviewRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td>$($item.PrimaryUser)</td>
            <td>$($item.OperatingSystemEdition)</td>
            <td>$($item.OSFriendlyname)</td>
        </tr>
"@

    }

    # Generate table rows for disabled primary users
    $disabledPrimaryUsersRows = ""
    foreach ($item in $Report_DisabledPrimaryUsers) {
        $disabledPrimaryUsersRows += @"
        <tr>
            <td>$($item.Customer)</td>
            <td>$($item.DeviceName)</td>
            <td><span class="badge badge-permanent">$($item.PrimaryUser)</span></td>
            <td>$($item.Serialnumber)</td>
            <td>$($item.DeviceManufacturer)</td>
            <td>$($item.DeviceModel)</td>
        </tr>
"@

    }

    # Replace placeholders in template with actual values
    $htmlContent = $htmlTemplate
    $htmlContent = $htmlContent.Replace('$TenantName', $TenantName)
    $htmlContent = $htmlContent.Replace('$ReportDate', $currentDate)
    $htmlContent = $htmlContent.Replace('{{APPLICATION_FAILURES_DATA}}', $applicationFailureRows)
    $htmlContent = $htmlContent.Replace('{{MULTIPLE_USERS_DATA}}', $multipleUsersRows)
    $htmlContent = $htmlContent.Replace('{{NOT_ENCRYPTED_DATA}}', $notEncryptedRows)
    $htmlContent = $htmlContent.Replace('{{NO_AUTOPILOT_DATA}}', $noAutopilotHashRows)
    $htmlContent = $htmlContent.Replace('{{INACTIVE_DEVICES_DATA}}', $inactiveDevicesRows)
    $htmlContent = $htmlContent.Replace('{{NONCOMPLIANT_DEVICES_DATA}}', $noncompliantDevicesRows)
    $htmlContent = $htmlContent.Replace('{{OS_EDITION_OVERVIEW_DATA}}', $osEditionOverviewRows)
    $htmlContent = $htmlContent.Replace('{{DISABLED_PRIMARY_USERS_DATA}}', $disabledPrimaryUsersRows)
    $htmlContent = $htmlContent.Replace('$applicationFailures', $Report_ApplicationFailureReport_Count)
    $htmlContent = $htmlContent.Replace('$multipleUsers', $Report_DevicesWithMultipleUsers_Count)
    $htmlContent = $htmlContent.Replace('$notEncrypted', $Report_NotEncryptedDevices_Count)
    $htmlContent = $htmlContent.Replace('$noAutopilot', $Report_DevicesWithoutAutopilotHash_Count)
    $htmlContent = $htmlContent.Replace('$inactiveDevices', $Report_InactiveDevices_Count)
    $htmlContent = $htmlContent.Replace('$noncompliantDevices', $Report_NoncompliantDevices_Count)
    $htmlContent = $htmlContent.Replace('$osEditionOverview', $Report_OperationSystemEdtionOverview_Count)
    $htmlContent = $htmlContent.Replace('$disabledPrimaryUsers', $Report_DisabledPrimaryUsers_Count)

    # Export to HTML file
    $htmlContent | Out-File -FilePath $ExportPath -Encoding utf8

    # Set script-scoped variable for email attachment
    $script:ExportPath = $ExportPath

    Write-Host "INFO: All actions completed successfully."
    Write-Host "INFO: Intune Anomalies Report saved to: $ExportPath" -ForegroundColor Cyan

    # Open the HTML file only if we're not sending email
    if (-not $SendEmail) {
        Invoke-Item $ExportPath
    }
}

function Invoke-GraphRequestWithPaging {
    param (
        [string]$Uri,
        [string]$Method = "GET",
        [int]$PageSize = 1000  # Larger page size = fewer requests
    )
    
    # Add $top parameter for larger pages
    $separator = if ($Uri -contains "?") { "&" } else { "?" }
    $Uri = "$Uri$separator`$top=$PageSize"
    
    $results = [System.Collections.ArrayList]::new()  # More efficient than @()
    $currentUri = $Uri
    
    do {
        try {
            $response = Invoke-MgGraphRequest -Uri $currentUri -Method $Method -OutputType PSObject -ErrorAction Stop
            
            if ($response.value) {
                $null = $results.AddRange($response.value)  # AddRange is faster than +=
            }
            
            $currentUri = $response.'@odata.nextLink'
        } catch {
            Write-Warning "Request failed: $_"
            return $null
        }
    } while ($currentUri)
    
    return $results.ToArray()
}

Function Install-Requirements {

    $PsVersion = $PSVersionTable.PSVersion.Major

    $requiredModules = @(
        "Microsoft.Graph.Authentication"
    )

    foreach ($module in $requiredModules) {
        if ($PsVersion -ge 7) {
            # For PowerShell 7+, install the most recent version
            $moduleInstalled = Get-Module -ListAvailable -Name $module
            
            if (-not $moduleInstalled) {
                Write-Host "Installing latest version of module: $module" -ForegroundColor Cyan
                Install-Module -Name $module -Scope CurrentUser -Force -AllowClobber -SkipPublisherCheck
            } else {
                Write-Host "Module $module is already installed." -ForegroundColor Green
            }
        } else {
            # For PowerShell 5.1, use version 2.25.0
            $moduleVersion = "2.25.0"
            $moduleInstalled = Get-Module -ListAvailable -Name $module | Where-Object { $_.Version -eq $moduleVersion }
        
            if (-not $moduleInstalled) {
                Write-Host "Installing module: $module version $moduleVersion" -ForegroundColor Cyan
                Install-Module -Name $module -Scope CurrentUser -Force -AllowClobber -RequiredVersion $moduleVersion -SkipPublisherCheck
            } else {
                Write-Host "Module $module version $moduleVersion is already installed." -ForegroundColor Green
            }
        }
    }

    # Import the required modules
    foreach ($module in $requiredModules) {
        if ($PsVersion -ge 7) {
            # For PowerShell 7+, import the latest available version
            $importedModule = Get-Module -Name $module
        
            if (-not $importedModule) {
                try {
                    Import-Module -Name $module -Force -ErrorAction Stop
                    Write-Host "Latest version of module $module imported successfully." -ForegroundColor Green
                } catch {
                    Write-Host "Failed to import module $module. Error: $_" -ForegroundColor Red
                    throw
                }
            } else {
                Write-Host "Module $module was already imported." -ForegroundColor Green
            }
        } else {
            # For PowerShell 5.1, import version 2.25.0
            $moduleVersion = "2.25.0"
            $importedModule = Get-Module -Name $module | Where-Object { $_.Version -eq $moduleVersion }
        
            if (-not $importedModule) {
                try {
                    Import-Module -Name $module -RequiredVersion $moduleVersion -Force -ErrorAction Stop
                    Write-Host "Module $module version $moduleVersion imported successfully." -ForegroundColor Green
                } catch {
                    Write-Host "Failed to import module $module version $moduleVersion. Error: $_" -ForegroundColor Red
                    throw
                }
            } else {
                Write-Host "Module $module version $moduleVersion was already imported." -ForegroundColor Green
            }
        }
    }
}

function Connect-ToMgGraph {
    [CmdletBinding(DefaultParameterSetName = "Interactive")]
    param (
        [Parameter(Mandatory = $false, ParameterSetName = "Interactive")]
        [Parameter(Mandatory = $false, ParameterSetName = "ClientSecret")]
        [Parameter(Mandatory = $false, ParameterSetName = "Certificate")]
        [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
        [Parameter(Mandatory = $false, ParameterSetName = "AccessToken")]
        [string[]]$RequiredScopes = @("User.Read", "DeviceManagementManagedDevices.Read.All","DeviceManagementConfiguration.Read.All","DeviceManagementServiceConfig.Read.All", "DeviceManagementApps.Read.All","User.Read.All", "Directory.Read.All", "Mail.Send" ),
        
        [Parameter(Mandatory = $true, ParameterSetName = "ClientSecret")]
        [Parameter(Mandatory = $true, ParameterSetName = "Certificate")]
        [Parameter(Mandatory = $false, ParameterSetName = "Identity")]
        [Parameter(Mandatory = $true, ParameterSetName = "AccessToken")]
        [string]$TenantId,
        
        [Parameter(Mandatory = $true, ParameterSetName = "ClientSecret")]
        [Parameter(Mandatory = $true, ParameterSetName = "Certificate")]
        [string]$ClientId,
        
        [Parameter(Mandatory = $true, ParameterSetName = "ClientSecret")]
        [string]$ClientSecret,
        
        [Parameter(Mandatory = $true, ParameterSetName = "Certificate")]
        [string]$CertificateThumbprint,

        [Parameter(Mandatory = $true, ParameterSetName = "Identity")]
        [switch]$Identity,

        [Parameter(Mandatory = $true, ParameterSetName = "AccessToken")]
        [string]$AccessToken
    )
    
    # Check if Microsoft Graph module is installed and import it
    Install-Requirements
    
    # Determine authentication method based on parameters
    $AuthMethod = $PSCmdlet.ParameterSetName
    Write-Verbose "Using authentication method: $AuthMethod"
    
    # Check if already connected
    $contextInfo = Get-MgContext -ErrorAction SilentlyContinue
    $reconnect = $false
    
    if ($contextInfo) {
        # Check if we have all the required permissions for interactive auth
        if ($AuthMethod -eq "Interactive") {
            $currentScopes = $contextInfo.Scopes
            $missingScopes = $RequiredScopes | Where-Object { $_ -notin $currentScopes }
            
            if ($missingScopes) {
                Write-Verbose "Missing required scopes: $($missingScopes -join ', ')"
                Write-Verbose "Reconnecting with all required scopes..."
                $reconnect = $true
            } else {
                Write-Verbose "Already connected to Microsoft Graph as $($contextInfo.Account) with all required scopes."
                return $contextInfo
            }
        } else {
            # For other auth methods, disconnect and reconnect with the new credentials
            Write-Verbose "Switching to $AuthMethod authentication method..."
            Disconnect-MgGraph -ErrorAction SilentlyContinue
            $reconnect = $true
        }
    } else {
        $reconnect = $true
    }
    
    if ($reconnect) {
        try {
            # Define connection parameters based on authentication method
            switch ($AuthMethod) {
                "Interactive" {
                    Write-Verbose "Connecting to Microsoft Graph using interactive authentication..."
                    Connect-MgGraph -Scopes $RequiredScopes -NoWelcome
                }
                "ClientSecret" {
                    Write-Verbose "Connecting to Microsoft Graph using client secret authentication..."
                    $secureSecret = ConvertTo-SecureString -String $ClientSecret -AsPlainText -Force
                    $clientSecretCredential = New-Object System.Management.Automation.PSCredential($ClientId, $secureSecret)
                    Connect-MgGraph -TenantId $TenantId -ClientSecretCredential $clientSecretCredential -NoWelcome
                }
                "Certificate" {
                    Write-Verbose "Connecting to Microsoft Graph using certificate authentication..."
                    Connect-MgGraph -TenantId $TenantId -ClientId $ClientId -CertificateThumbprint $CertificateThumbprint -NoWelcome
                }
                "Identity" {
                    Write-Verbose "Connecting to Microsoft Graph using managed identity authentication..."
                    if ($TenantId) {
                        Connect-MgGraph -Identity -TenantId $TenantId -NoWelcome
                    } else {
                        Connect-MgGraph -Identity -NoWelcome
                    }
                }
                "AccessToken" {
                    Write-Verbose "Connecting to Microsoft Graph using provided access token..."
                    Connect-MgGraph -AccessToken $AccessToken -TenantId $TenantId -NoWelcome
                }
            }
            
            # Verify connection
            $newContext = Get-MgContext
            if ($newContext) {
                $authDetails = switch ($AuthMethod) {
                    "Interactive" { "as $($newContext.Account)" }
                    "ClientSecret" { "using client secret (App ID: $ClientId)" }
                    "Certificate" { "using certificate authentication (App ID: $ClientId)" }
                    "Identity" { "using managed identity" }
                    "AccessToken" { "using provided access token" }
                }
                
                Write-Verbose "Successfully connected to Microsoft Graph $authDetails"
                return $newContext
            } else {
                throw "Connection attempt completed but unable to confirm connection"
            }
        } catch {
            Write-Error "Error connecting to Microsoft Graph: $_"
            return $null
        }
    }
    
    return $contextInfo
}

function Get-AllDeviceData {
    function Get-OperatingSystemProductType {
        param (
            $Customer
        )

        @{ 
            "0"   = "unknown"
            "4"   = "Windows 10/11 Enterprise"
            "27"  = "Windows 10/11 Enterprise N"
            "48"  = "Windows 10/11 Professional"
            "49"  = "Windows 10/11 Professional for workstation N"
            "72"  = "Windows 10/11 Enterprise Evaluation"
            "119" = "Windows 10 TeamOS"
            "121" = "Windows 10/11 Education"
            "122" = "Windows 10/11 Education N"
            "125" = "Windows 10 Enterprise LTSC"
            "136" = "Hololens"
            "175" = "Windows 10 / 11 Enterprise Multi-session"
        }.$Customer
    }

    function Get-OSFriendlyName {
        param (
            [string]$OperatingSystemVersion
        )

        switch -Regex ($OperatingSystemVersion) {
            "^10\.0\.19043" { return "Windows 10 21H1" }
            "^10\.0\.19044" { return "Windows 10 21H2" }
            "^10\.0\.19045" { return "Windows 10 22H2" }
            "^10\.0\.22000" { return "Windows 11 21H2" }
            "^10\.0\.22621" { return "Windows 11 22H2" }
            "^10\.0\.22631" { return "Windows 11 23H2" }
            "^10\.0\.22635" { return "Windows 11 23H2 Insider Preview" }
            "^10\.0\.261" { return "Windows 11 24H2" }
            default { return "Other" }
        }
    }
    
    function Convert-Size {            
        [cmdletbinding()]            
        param(            
            [validateset("Bytes", "KB", "MB", "GB", "TB")]            
            [string]$From,            
            [validateset("Bytes", "KB", "MB", "GB", "TB")]            
            [string]$To,            
            [Parameter(Mandatory = $true)]            
            [double]$Value,            
            [int]$Precision = 4            
        )            
        switch ($From) {            
            "Bytes" { $value = $Value }            
            "KB" { $value = $Value * 1024 }            
            "MB" { $value = $Value * 1024 * 1024 }            
            "GB" { $value = $Value * 1024 * 1024 * 1024 }            
            "TB" { $value = $Value * 1024 * 1024 * 1024 * 1024 }            
        }            
                    
        switch ($To) {            
            "Bytes" { return $value }            
            "KB" { $Value = $Value / 1KB }            
            "MB" { $Value = $Value / 1MB }            
            "GB" { $Value = $Value / 1GB }            
            "TB" { $Value = $Value / 1TB }            
                    
        }            
          
        $Calc = [Math]::Round($value, $Precision, [MidPointRounding]::AwayFromZero) 
        return "$calc $to" 
                    
    }

    # Optimized Properties List - Only essential properties for better performance
    $Properties = @(
        'Id',                 # Required for compliance data fetching and unique identification
        'DeviceName',
        'ManagedDeviceOwnerType',
        'UserPrincipalName',  # Primary user
        'SerialNumber',
        'ManagedDeviceName',
        'Manufacturer',
        'Model',
        'ProcessorArchitecture',
        'WiFiMacAddress',
        'EthernetMacAddress',
        'TotalStorageSpaceInBytes',
        'FreeStorageSpaceInBytes',
        'EnrolledDateTime',
        'LastSyncDateTime',
        'EnrollmentProfileName',
        'IsEncrypted',
        'DeviceEnrollmentType',
        'OperatingSystem',
        'OSVersion',
        'ComplianceState',
        'usersLoggedOn',      # Contains userId for logged-on users
        'hardwareInformation', # Contains nested properties like tpmVersion, OS details, BiosVersion
        'managementAgent' # Indicates the management agent used (e.g., Intune)
    )

    # Get all Windows Devices from Microsoft Intune
    $AllDeviceData = Invoke-graphRequestWithPaging -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices?`$filter=operatingSystem eq 'Windows'&`$select=$($Properties -join ',')"
    #filter out managed by MDE
    $AllDeviceData = $AllDeviceData | Where-Object { $_.managementAgent -ne "msSense" }
    
    # Get all AutoPilot registered devices under "Enrollment"
    Write-Host "Fetching Autopilot devices..." -ForegroundColor Yellow
    $AutopilotDevices = (Invoke-GraphRequestWithPaging -Uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeviceIdentities")

    # Loop through all devices for device data
    $results = @()
    $totalDevices = $AllDeviceData.Count
    
    Write-Host "Processing $totalDevices devices..." -ForegroundColor Yellow

    for ($i = 0; $i -lt $AllDeviceData.Count; $i++) {
        $DeviceData = $AllDeviceData[$i]
        $currentIndex = $i + 1
        
        # Calculate progress percentage
        $progressPercent = [math]::Round(($currentIndex / $totalDevices) * 100, 1)
        
        # Show progress bar instead of Write-Host
        Write-Progress -Activity "Processing Intune Devices" -Status "Processing device: $($DeviceData.DeviceName)" -CurrentOperation "$currentIndex of $totalDevices devices processed" -PercentComplete $progressPercent

        try {
            # Get detailed device properties
            $DeviceProperties = Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/manageddevices/$($DeviceData.id)?`$select=$($Properties -join ',')" -ErrorAction Stop
            
            # Process Autopilot information
            $AutopilotInfo = $AutopilotDevices | Where-Object { $_.serialnumber -eq $DeviceData.SerialNumber } 
            $HashUploaded = $DeviceData.Serialnumber -in $AutopilotDevices.serialnumber

            # Initialize compliance rule variables
            $allRules = @()
            $uniqueRules = @()

            # Check if device is compliant or not. If not compliant, get compliance rule details
            $FilteredForAlerting = @("DefaultDeviceCompliancePolicy.RequireDeviceCompliancePolicyAssigned", "DefaultDeviceCompliancePolicy.RequireRemainContact")

            if ($DeviceData.complianceState -eq "noncompliant") {
                try {
                    $ComplianceRules = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$($DeviceData.id)/deviceCompliancePolicyStates" -ErrorAction SilentlyContinue).value | Where-Object { $_.State -eq "nonCompliant" -or $_.State -eq "Error" }
                    
                    if ($ComplianceRules -and $ComplianceRules.count -le 10) {
                        foreach ($ComplianceRule in $ComplianceRules) {
                            try {
                                $ruleDetails = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/managedDevices/$($DeviceData.id)/deviceCompliancePolicyStates/$($ComplianceRule.id)/settingStates" -ErrorAction SilentlyContinue).value | Where-Object { $_.state -match 'nonCompliant' }
                                
                                if ($ruleDetails) {
                                    # Add individual rule settings to the collection
                                    foreach ($ruleDetail in $ruleDetails) {
                                        if ($ruleDetail.setting) {
                                            $allRules += $ruleDetail.setting
                                        }
                                    }
                                }
                            } catch {
                                Write-Verbose "Failed to get compliance rule details for $($DeviceData.DeviceName): $_"
                            }
                        }
                        
                        # **FIX**: Get unique values only to eliminate duplicates
                        $uniqueRules = $allRules | Select-Object -Unique
                    }
                } catch {
                    Write-Verbose "Failed to get compliance details for $($DeviceData.DeviceName): $_"
                }
            }

            # Check if all logged in user ID's still exist in Microsoft Entra ID
            $LoggedInUsers = $DeviceProperties.usersLoggedOn.userId | Select-Object -Unique
            $ExistingLoggedInUsers = @()

            if ($LoggedInUsers) {
                foreach ($user in $LoggedInUsers) {
                    if ($user -in $AllEntraIDUsers.Id) {
                        try {
                            $userPrincipalName = (Invoke-MgGraphRequest -Uri "/beta/users/$user" -ErrorAction SilentlyContinue).userprincipalname
                            if ($userPrincipalName) {
                                $ExistingLoggedInUsers += $userPrincipalName
                            }
                        } catch {
                            Write-Verbose "Failed to get user details for ID $user $_"
                        }
                    }
                }
            }

            # Handle storage calculations with null checking
            $TotalStorageFormatted = if ($DeviceProperties.TotalStorageSpaceInBytes -and $DeviceProperties.TotalStorageSpaceInBytes -gt 0) { 
                Convert-Size -From bytes -To GB -Value $DeviceProperties.TotalStorageSpaceInBytes -Precision 2 
            } else { 
                "N/A" 
            }
            
            $FreeStorageFormatted = if ($DeviceProperties.FreeStorageSpaceInBytes -and $DeviceProperties.FreeStorageSpaceInBytes -gt 0) { 
                Convert-Size -From bytes -To GB -Value $DeviceProperties.FreeStorageSpaceInBytes -Precision 2 
            } else { 
                "N/A" 
            }

            # Access hardware information with null checking
            $hardwareInfo = $DeviceProperties.hardwareInformation

            $results += [PSCustomObject][ordered]@{
                Customer                   = $TenantName
                DeviceName                 = $DeviceProperties.DeviceName
                DeviceOwnership            = $DeviceProperties.ManagedDeviceOwnerType
                PrimaryUser                = if ($DeviceProperties.UserPrincipalName) { $DeviceProperties.UserPrincipalName } else { "None" }
                Serialnumber               = $DeviceProperties.SerialNumber
                DeviceManufacturer         = $DeviceProperties.Manufacturer
                DeviceModel                = $DeviceProperties.Model
                ProcessorArchitecture      = if ($hardwareInfo.processorArchitecture) { $hardwareInfo.processorArchitecture } else { $DeviceProperties.processorArchitecture }
                TPMversion                 = if ($hardwareInfo.tpmVersion) { $hardwareInfo.tpmVersion } else { "Unknown" }
                tpmSpecificationVersion    = if ($hardwareInfo.tpmSpecificationVersion) { $hardwareInfo.tpmSpecificationVersion } else { "Unknown" }
                WiFiMAC                    = $DeviceProperties.WiFiMacAddress
                EthernetMAC                = $DeviceProperties.EthernetMacAddress
                TotalStorage               = $TotalStorageFormatted
                FreeStorage                = $FreeStorageFormatted
                EnrolledDate               = $DeviceProperties.EnrolledDateTime
                LastContact                = $DeviceProperties.LastSyncDateTime
                DeviceHashUploaded         = $HashUploaded
                AutopilotGroupTag          = $AutopilotInfo.groupTag
                AutopilotAssignedUser      = if ($AutopilotInfo.userprincipalname) { $AutopilotInfo.userprincipalname } else { $null }
                EnrollmentProfile          = $DeviceProperties.EnrollmentProfileName
                Encrypted                  = $DeviceProperties.IsEncrypted
                DeviceEnrollmentType       = $DeviceProperties.DeviceEnrollmentType 
                usersLoggedOnIds           = if ($ExistingLoggedInUsers) { $ExistingLoggedInUsers -join ', ' } else { "" }
                usersLoggedOnCount         = if ($LoggedInUsers) { $LoggedInUsers.Count } else { 0 }
                Operatingsystem            = $DeviceProperties.OperatingSystem
                OperatingSystemVersion     = $DeviceProperties.OSVersion
                OSFriendlyname             = Get-OSFriendlyName -OperatingSystemVersion $DeviceProperties.OSVersion
                OperatingSystemLanguage    = if ($hardwareInfo.operatingSystemLanguage) { $hardwareInfo.operatingSystemLanguage } else { "Unknown" }
                OperatingSystemEdition     = if ($hardwareInfo.operatingSystemEdition) { $hardwareInfo.operatingSystemEdition } else { "Unknown" }
                operatingSystemProductType = if ($hardwareInfo.operatingSystemProductType) { Get-OperatingSystemProductType -Customer "$($hardwareInfo.operatingSystemProductType)" } else { "Unknown" }
                BiosVersion                = if ($hardwareInfo.systemManagementBIOSVersion) { $hardwareInfo.systemManagementBIOSVersion } else { "Unknown" }
                ComplianceStatus           = $DeviceProperties.ComplianceState
                # **FIX**: Use unique rules to prevent duplicates
                NoncompliantBasedOn        = if ($uniqueRules) { $uniqueRules -join ', ' } else { "" }
                NoncompliantAlert          = if ($uniqueRules) { ($uniqueRules | Where-Object { $_ -notin $FilteredForAlerting }) -join ', ' } else { "" }
            }
        } catch {
            Write-Warning "Error processing device $($DeviceData.DeviceName): $_"
            continue
        }
    }

    # Clear the progress bar when done
    Write-Progress -Activity "Processing Intune Devices" -Completed

    Write-Host "Device processing completed!" -ForegroundColor Green
    Write-Host "Processed $($results.Count) devices out of $totalDevices total devices" -ForegroundColor Green
    
    # Debug output for hardware information availability
    $devicesWithHardwareInfo = $results | Where-Object { $_.TPMversion -ne "Unknown" }
    $devicesWithoutHardwareInfo = $results | Where-Object { $_.TPMversion -eq "Unknown" }
        
    if ($devicesWithoutHardwareInfo.Count -gt 0) {
        Write-Host "Some devices are missing hardware information:" -ForegroundColor Yellow
        foreach ($device in $devicesWithoutHardwareInfo) {
            Write-Host " - $($device.DeviceName) (Serial: $($device.Serialnumber))" -ForegroundColor Gray    
        }
    }
    return $results

}

function Get-ApplicationFailures {

    #$Data = "$Env:AGENT_BUILDDIRECTORY\Data.log"
    $Data = "C:\temp\Data.log"
    if (-not (Test-Path -Path "C:\temp")) {
        New-Item -ItemType Directory -Path "C:\temp" -Force | Out-Null
    }

    $apps = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps?`$filter=(isof(%27microsoft.graph.win32CatalogApp%27)%20or%20isof(%27microsoft.graph.windowsStoreApp%27)%20or%20isof(%27microsoft.graph.microsoftStoreForBusinessApp%27)%20or%20isof(%27microsoft.graph.officeSuiteApp%27)%20or%20(isof(%27microsoft.graph.win32LobApp%27)%20and%20not(isof(%27microsoft.graph.win32CatalogApp%27)))%20or%20isof(%27microsoft.graph.windowsMicrosoftEdgeApp%27)%20or%20isof(%27microsoft.graph.windowsPhone81AppX%27)%20or%20isof(%27microsoft.graph.windowsPhone81StoreApp%27)%20or%20isof(%27microsoft.graph.windowsPhoneXAP%27)%20or%20isof(%27microsoft.graph.windowsAppX%27)%20or%20isof(%27microsoft.graph.windowsMobileMSI%27)%20or%20isof(%27microsoft.graph.windowsUniversalAppX%27)%20or%20isof(%27microsoft.graph.webApp%27)%20or%20isof(%27microsoft.graph.windowsWebApp%27)%20or%20isof(%27microsoft.graph.winGetApp%27))%20and%20(microsoft.graph.managedApp/appAvailability%20eq%20null%20or%20microsoft.graph.managedApp/appAvailability%20eq%20%27lineOfBusiness%27%20or%20isAssigned%20eq%20true)&`$orderby=displayName&").value
   
    $params = @{
        Select  = @(
            "DisplayName"
            "Publisher"
            "Platform"
            "AppVersion"
            "FailedDevicePercentage"
            "FailedDeviceCount"
            "FailedUserCount"
            "ApplicationId"
        )
        Skip    = 0
        Top     = 50
        Filter  = "(FailedDeviceCount gt '0')"
        OrderBy = @(
            "FailedDeviceCount desc"
        )
    }
    Invoke-MgGraphRequest -Body $params -Uri "https://graph.microsoft.com/beta/deviceManagement/reports/getAppsInstallSummaryReport" -Method POST -OutputFilePath $Data

    $DataFile = Get-Content $Data
    # Fix char encoding to UTF-8
    $Response = [system.Text.Encoding]::UTF8.GetString(($DataFile).ToCharArray()) | ConvertFrom-Json

    #Maak een nieuwe array
    $ReturnObject = New-Object System.Collections.ArrayList

    #voor elke waardeverzameling in values
    foreach ($value in $Response.Values) {
        #maak een nieuw lineobject[hashtable]
        $LineObject = @{ }

        #voor elke prop in het het schema
        foreach ($prop in $Response.Schema) {
            $LineObject[$prop.Column] = $value[$Response.Schema.IndexOf($prop)]
        }
        # Check if $LineObject.ApplicationId can be found in $apps
        if ($apps | Where-Object { $_.Id -eq $LineObject.ApplicationId }) {
            $AppAssignment = (Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceAppManagement/mobileApps/$($LineObject.ApplicationId)/?`$expand=assignments").assignments
            $AssignmentStatus = $false
            if ($AppAssignment) {
                $AssignmentStatus = $true
            }
            
            # Use Platform_loc instead of Platform for better readability
            $PlatformName = if ($LineObject.Platform_loc) { $LineObject.Platform_loc } else { $LineObject.Platform }
            
            $ReturnObject.Add([PSCustomObject][ordered]@{
                    Customer               = $tenantname 
                    Application            = ($apps | Where-Object { $_.Id -eq $LineObject.ApplicationId }).displayName   
                    Platform               = $PlatformName
                    Version                = $LineObject.AppVersion
                    AssignmentStatus       = $AssignmentStatus
                    FailedUserCount        = $LineObject.FailedUserCount
                    FailedDeviceCount      = $LineObject.FailedDeviceCount 
                    FailedDevicePercentage = [double]($LineObject.FailedDevicePercentage / 100).toString('0.00')
                }) | Out-Null
        }
    }

    # Clean up temporary data file
    if (Test-Path -Path $Data) {
        Remove-Item -Path $Data -Force
    }

    return $ReturnObject | Sort-Object -Property FailedDeviceCount -Descending
}

function Get-AutopilotProfilesInformation {
(Invoke-GraphRequest -Uri "https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles/" -OutputType PSObject).value        
}

function Send-EmailWithAttachment {
    [CmdletBinding()]
    param(
        # The email addresses of the recipients. e.g. john@contoso.com
        [Parameter(Mandatory = $true, Position = 0)]
        [string[]] $Recipient,
        # HTML file path to attach to the email
        [Parameter(Mandatory = $true)]
        [string] $AttachmentPath,
        # The user id of the sender of the mail. Defaults to the current user.
        [Parameter(Mandatory = $false)]
        [string] $From
    )

    # Check Graph connection
    try {
        $contextInfo = Get-MgContext -ErrorAction Stop
        if (-not $contextInfo) {
            Write-Error "Not connected to Microsoft Graph. Please connect using Connect-MgGraph with appropriate scopes."
            return $false
        }
    } catch {
        Write-Error "Error checking Graph connection: $_"
        return $false
    }

    # Check if file exists and validate size
    if (-not (Test-Path -Path $AttachmentPath)) {
        Write-Error "Attachment file not found: $AttachmentPath"
        return $false
    }
    
    $fileInfo = Get-Item -Path $AttachmentPath
    if ($fileInfo.Length -gt 3MB) {
        Write-Error "Attachment is too large ($(($fileInfo.Length/1MB).ToString('0.00')) MB). Maximum recommended size is 3 MB."
        return $false
    }

    # Get file content as base64
    try {
        $fileName = Split-Path -Path $AttachmentPath -Leaf
        $contentBytes = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes($AttachmentPath))
    } catch {
        Write-Error "Failed to read attachment file: $_"
        return $false
    }

    # Build recipients array
    $toRecipients = @()
    foreach ($email in $Recipient) {
        $toRecipients += @{
            emailAddress = @{
                address = $email
            }
        }
    }

    # Create the mail request body with proper Graph API structure
    $mailRequestBody = @{
        message = @{
            subject      = "$tenantname - Microsoft Entra ID Admin Roles Report"
            toRecipients = $toRecipients
            body         = @{
                contentType = "html"
                content     = @"
    <html>
    <body style="font-family: 'Segoe UI', Arial, sans-serif; color: #333333;">
        <h2 style="color: #0078d4;">Intune Anomalies Report</h2>
        <p>Attached is the latest Intune anomalies report for <strong>$tenantname</strong>.</p>
        <p>This comprehensive report identifies potential issues and anomalies in your Intune environment, including:</p>
        <ul>
            <li><strong>Application Failures:</strong> Apps with high failure rates across devices</li>
            <li><strong>Multiple Users on Single-User Devices:</strong> User-driven devices that should be re-enrolled as shared</li>
            <li><strong>Unencrypted Devices:</strong> Devices without BitLocker encryption (security risk)</li>
            <li><strong>Non-Company Owned Devices:</strong> Devices missing Autopilot hardware hash registration</li>
            <li><strong>Inactive Devices:</strong> Devices not contacting Intune for 90+ days</li>
            <li><strong>Non-Compliant Devices:</strong> Devices failing compliance policies with detailed violation reasons</li>
            <li><strong>OS Edition Overview:</strong> Device operating system editions for license optimization</li>
            <li><strong>Disabled Primary Users:</strong> Devices assigned to disabled user accounts</li>
        </ul>
        <p><strong>Key Features:</strong></p>
        <ul>
            <li>Interactive dashboard with filtering and export capabilities</li>
            <li>Dark/light theme support</li>
            <li>Detailed compliance violation breakdown</li>
            <li>Actionable insights for IT administrators</li>
        </ul>
        <p>Open the attached HTML report in any web browser to access the full interactive dashboard with advanced filtering options.</p>
        <p style="color: #666666; font-style: italic; margin-top: 20px;">Generated automatically by RK Solutions Intune Anomalies Report - Please do not reply to this email.</p>
    </body>
    </html>
"@

            }
            attachments  = @(
                @{
                    "@odata.type" = "#microsoft.graph.fileAttachment"
                    name          = $fileName
                    contentType   = "text/html"
                    contentBytes  = $contentBytes
                }
            )
        }
    }

    # Determine the endpoint URL
    $sendMailUri = "https://graph.microsoft.com/v1.0/me/sendMail"
    if ($From) {
        # Use the /users/{id}/ endpoint for other users
        $sendMailUri = "https://graph.microsoft.com/v1.0/users/$From/sendMail"
    }

    try {
        # Convert to JSON with proper depth
        $jsonBody = ConvertTo-Json -InputObject $mailRequestBody -Depth 20

        # Enable verbose output for debugging
        Write-Verbose "Request body:"
        Write-Verbose $jsonBody

        # Send the request with error details
        $response = Invoke-MgGraphRequest -Method POST -Uri $sendMailUri -Body $jsonBody -ErrorAction Stop
        Write-Host "Email sent successfully from: $from" -ForegroundColor Green
        Write-Host "Email sent successfully to: $($Recipient -join ', ')" -ForegroundColor Green
        Write-Host "Email sent successfully with attachment: $fileName" -ForegroundColor Green
        return $true
    } catch {
        $errorDetails = $_
        Write-Host "Failed to send email. Error: $($errorDetails.Exception.Message)" -ForegroundColor Red

        # Additional error details for debugging
        Write-Verbose "Error details:"
        Write-Verbose $errorDetails

        # Check if we have more detailed error information
        if ($errorDetails.ErrorDetails) {
            Write-Verbose "Error response content:"
            Write-Verbose $errorDetails.ErrorDetails.Message
        }

        return $false
    }

}

#Connect to the Graph API
Write-Verbose "Connecting to Graph API..."
try {
    # Determine which authentication method to use based on parameters
    $connectionParams = @{
        RequiredScopes = $RequiredScopes
        Verbose        = $VerbosePreference -eq 'Continue'
    }

    # Add parameters based on which ones were provided
    if ($PSCmdlet.ParameterSetName -eq "Interactive") {
        if ($TenantId) { $connectionParams.TenantId = $TenantId }
        if ($ClientId) { $connectionParams.ClientId = $ClientId }
    } elseif ($PSCmdlet.ParameterSetName -eq "ClientSecret") {
        $connectionParams.TenantId = $TenantId
        $connectionParams.ClientId = $ClientId
        $connectionParams.ClientSecret = $ClientSecret
    } elseif ($PSCmdlet.ParameterSetName -eq "Certificate") {
        $connectionParams.TenantId = $TenantId
        $connectionParams.ClientId = $ClientId
        $connectionParams.CertificateThumbprint = $CertificateThumbprint
    } elseif ($PSCmdlet.ParameterSetName -eq "Identity") {
        $connectionParams.Identity = $true
        if ($TenantId) { $connectionParams.TenantId = $TenantId }
    } elseif ($PSCmdlet.ParameterSetName -eq "AccessToken") {
        $connectionParams.AccessToken = $AccessToken
        $connectionParams.TenantId = $TenantId
    }
    
    $connected = Connect-ToMgGraph @connectionParams

    if ($connected) {
        Write-Verbose "Connected to Graph API successfully."

        # Get Tenant Name
        $tenantInfo = Invoke-MgGraphRequest -Uri "beta/organization" -Method Get -OutputType PSObject
        $tenantname = $tenantInfo.value[0].displayName

        # Collect all users in Microsoft Entra ID
        $AllEntraIDUsers = Invoke-GraphRequestWithPaging -Uri "https://graph.microsoft.com/beta/users/?$select=id,userPrincipalName,userType,accountEnabled" | Where-Object { $_.UserType -eq "Member" }
        $DisabledEntraUsers = $AllEntraIDUsers | Where-Object { $_.accountEnabled -eq $false } | Select-Object id, userPrincipalName, userType, accountEnabled
      

        # Collect data
        Write-Host "Starting device data collection..." -ForegroundColor Yellow
        $DeviceData = Get-AllDeviceData


        $AutopilotProfilesInformation = Get-AutopilotProfilesInformation
        $UserDrivenAutopilotProfiles = $AutopilotProfilesInformation | Where-Object { $_.outOfBoxExperienceSettings.deviceUsageType -eq "SingleUser" }
        
        # Application failures overview
        $Report_ApplicationFailureReport = Get-ApplicationFailures 
        # Overview of user driven devices with multiple users. These devices should be re-enrolled as shared device
        $Report_DevicesWithMultipleUsers = $DeviceData | Where-Object { $_.usersLoggedOnCount -gt 1 -and $_.EnrollmentProfile -in $UserDrivenAutopilotProfiles.displayName } | Select-Object Customer, DeviceName, PrimaryUser, EnrollmentProfile, usersLoggedOnCount, usersLoggedOnIds
        # Overview of device operating system edtions. This gives a clean overview to check if your device is incorrectly not elevated to Enterprise for example
        $Report_OperationSystemEdtionOverview = $DeviceData | Select-Object Customer, DeviceName, PrimaryUser, OperatingSystemEdition, OSFriendlyname
        # Not Encrypted Devices
        $Report_NotEncryptedDevices = $DeviceData | Where-Object { $_.Encrypted -eq $false } | Select-Object Customer, DeviceName, PrimaryUser, Serialnumber, DeviceManufacturer, DeviceModel
        # Non-company owned devices
        $Report_DevicesWithoutAutopilotHash = $DeviceData | Where-Object { $_.DeviceHashUploaded -eq $false } | Select-Object Customer, DeviceName, PrimaryUser, Serialnumber, DeviceManufacturer, DeviceModel
        # Inactive devices in the last 90 days
        $Report_InactiveDevices = $DeviceData | Where-Object { $_.LastContact -lt (Get-Date).AddDays(-90) } | Select-Object Customer, DeviceName, PrimaryUser, Serialnumber, DeviceManufacturer, DeviceModel, LastContact
        # # Noncompliant Devices
        # $Report_NoncompliantDevices = $DeviceData | where-object { $_.ComplianceStatus -eq "noncompliant" } | Select-Object Customer, DeviceName, PrimaryUser, Serialnumber, DeviceManufacturer, DeviceModel, ComplianceStatus, NoncompliantBasedOn, NoncompliantAlert
        # Intune devices with disabled primary users
        $Report_DisabledPrimaryUsers = $DeviceData | Where-Object { $_.PrimaryUser -in $DisabledEntraUsers.userPrincipalName } | Select-Object Customer, DeviceName, PrimaryUser, Serialnumber, DeviceManufacturer, DeviceModel

        # Noncompliant Devices - Create separate rows for each noncompliant reason
        $Report_NoncompliantDevices = @()
        $NoncompliantDevicesRaw = $DeviceData | Where-Object { $_.ComplianceStatus -eq "noncompliant" }
        
        foreach ($device in $NoncompliantDevicesRaw) {
            if ($device.NoncompliantBasedOn) {
                # Split the reasons and create a row for each
                $reasons = $device.NoncompliantBasedOn -split ', '
                foreach ($reason in $reasons) {
                    if ($reason.Trim()) {
                        $Report_NoncompliantDevices += [PSCustomObject]@{
                            Customer            = $device.Customer
                            DeviceName          = $device.DeviceName
                            PrimaryUser         = $device.PrimaryUser
                            Serialnumber        = $device.Serialnumber
                            DeviceManufacturer  = $device.DeviceManufacturer
                            DeviceModel         = $device.DeviceModel
                            ComplianceStatus    = $device.ComplianceStatus
                            NoncompliantBasedOn = $reason.Trim()
                            NoncompliantAlert   = $device.NoncompliantAlert
                        }
                    }
                }
            } else {
                # Add device without specific reason
                $Report_NoncompliantDevices += [PSCustomObject]@{
                    Customer            = $device.Customer
                    DeviceName          = $device.DeviceName
                    PrimaryUser         = $device.PrimaryUser
                    Serialnumber        = $device.Serialnumber
                    DeviceManufacturer  = $device.DeviceManufacturer
                    DeviceModel         = $device.DeviceModel
                    ComplianceStatus    = $device.ComplianceStatus
                    NoncompliantBasedOn = "Unknown"
                    NoncompliantAlert   = $device.NoncompliantAlert
                }
            }
        }
        
        New-IntuneAnomaliesHTMLReport -TenantName $tenantname `
            -Report_ApplicationFailureReport $Report_ApplicationFailureReport `
            -Report_DevicesWithMultipleUsers $Report_DevicesWithMultipleUsers `
            -Report_NotEncryptedDevices $Report_NotEncryptedDevices `
            -Report_DevicesWithoutAutopilotHash $Report_DevicesWithoutAutopilotHash `
            -Report_InactiveDevices $Report_InactiveDevices `
            -Report_NoncompliantDevices $Report_NoncompliantDevices `
            -Report_OperationSystemEdtionOverview $Report_OperationSystemEdtionOverview `
            -Report_DisabledPrimaryUsers $Report_DisabledPrimaryUsers

        # Send email with the report
        if ($SendEmail) {
            $emailSent = Send-EmailWithAttachment -Recipient $Recipient -AttachmentPath $script:ExportPath -From $From
    
            if ($emailSent) {
                Write-Host "INFO: Email sent successfully." -ForegroundColor Green
            } else {
                Write-Host "ERROR: Failed to send email." -ForegroundColor Red
            }
        } else {
            Write-Host "INFO: Email sending is disabled. Set -SendEmail to $true to enable." -ForegroundColor Yellow
        }

        # Clean up the report file
        if ($SendEmail) {
            if (Test-Path -Path $script:ExportPath) {
                Remove-Item -Path $script:ExportPath -Force
                Write-Host "INFO: Temporary report file deleted." -ForegroundColor Green
            } else {
                Write-Host "INFO: No temporary report file found to delete." -ForegroundColor Yellow
            }
        }
    
    } else {
        throw "Failed to connect to Microsoft Graph API."
    }
} catch { 
    Write-Error "Error: $_"
    throw $_
} finally {
    # Disconnect from Microsoft Graph if connected
    $contextInfo = Get-MgContext -ErrorAction SilentlyContinue
    if ($contextInfo) {
        Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null 
        Write-Host "Disconnected from Microsoft Graph." -ForegroundColor Green
    } else {
        Write-Host "No active connection to disconnect." -ForegroundColor Yellow
    }
}