Public/Get-IntuneDeviceComplianceReport.ps1
|
function Get-IntuneDeviceComplianceReport { <# .SYNOPSIS Reports on Intune managed device compliance status. .DESCRIPTION Pulls all Intune managed devices and evaluates compliance state, OS version currency, encryption status, last check-in time, and ownership type. Flags non-compliant devices, stale devices that haven't checked in, and devices running outdated OS versions. .PARAMETER StaleDays Days since last check-in before flagging as stale. Defaults to 30. .PARAMETER OSFilter Filter to a specific OS platform (Windows, iOS, Android, macOS). .EXAMPLE Get-IntuneDeviceComplianceReport -StaleDays 14 -OSFilter Windows #> [CmdletBinding()] param( [Parameter()] [ValidateRange(1, 180)] [int]$StaleDays = 30, [Parameter()] [ValidateSet('Windows', 'iOS', 'Android', 'macOS', 'All')] [string]$OSFilter = 'All' ) begin { Test-GraphConnection $results = [System.Collections.Generic.List[PSObject]]::new() } process { $devices = Get-MgDeviceManagementManagedDevice -All -Property @( 'id', 'deviceName', 'userPrincipalName', 'operatingSystem', 'osVersion', 'complianceState', 'lastSyncDateTime', 'enrolledDateTime', 'managementAgent', 'ownerType', 'isEncrypted', 'model', 'manufacturer', 'serialNumber' ) if ($OSFilter -ne 'All') { $devices = $devices | Where-Object { $_.OperatingSystem -eq $OSFilter } } foreach ($device in $devices) { $findings = @() # Compliance state if ($device.ComplianceState -ne 'compliant') { $findings += "NON-COMPLIANT ($($device.ComplianceState))" } # Last sync check $daysSinceSync = if ($device.LastSyncDateTime) { [math]::Round(((Get-Date) - $device.LastSyncDateTime).TotalDays) } else { -1 } if ($daysSinceSync -gt $StaleDays) { $findings += "STALE ($daysSinceSync days since sync)" } # Encryption check if (-not $device.IsEncrypted -and $device.OperatingSystem -in @('Windows', 'macOS')) { $findings += 'NOT ENCRYPTED' } # OS version staleness (flag very old versions) $osVersionFlag = $false if ($device.OperatingSystem -eq 'Windows' -and $device.OsVersion) { # Flag Windows 10 devices (should be on 11 or at least recent 10 build) if ($device.OsVersion -match '^10\.0\.(1[0-8]\d{3})') { $findings += "OUTDATED OS ($($device.OsVersion))" $osVersionFlag = $true } } $results.Add([PSCustomObject]@{ DeviceName = $device.DeviceName UserPrincipalName = $device.UserPrincipalName OS = $device.OperatingSystem OSVersion = $device.OsVersion ComplianceState = $device.ComplianceState IsEncrypted = $device.IsEncrypted OwnerType = $device.OwnerType Manufacturer = $device.Manufacturer Model = $device.Model SerialNumber = $device.SerialNumber LastSync = $device.LastSyncDateTime DaysSinceSync = $daysSinceSync EnrolledDate = $device.EnrolledDateTime ManagementAgent = $device.ManagementAgent Finding = if ($findings.Count -gt 0) { $findings -join ' | ' } else { 'OK' } }) } } end { $flagged = $results | Where-Object { $_.Finding -ne 'OK' } $nonCompliant = $results | Where-Object { $_.ComplianceState -ne 'compliant' } Write-Host " Devices scanned: $($results.Count) | Non-compliant: $($nonCompliant.Count) | Findings: $($flagged.Count)" -ForegroundColor Gray $results | Sort-Object Finding, DeviceName } } |