Intune/Get-DeviceComplianceReport.ps1
|
<#
.SYNOPSIS Reports Intune managed device compliance status across the tenant. .DESCRIPTION Queries Microsoft Graph for all Intune managed devices and reports their compliance state, platform, and key details. Useful for reviewing device posture, identifying noncompliant devices, and generating compliance reports for clients. Requires Microsoft.Graph.DeviceManagement module and DeviceManagementManagedDevices.Read.All permission. .PARAMETER ComplianceState Filter results by compliance state. Valid values: All, Compliant, NonCompliant, Unknown. Defaults to All. .PARAMETER Platform Filter results by device platform. Valid values: All, Windows, iOS, Android, macOS. Defaults to All. .PARAMETER OutputPath Optional path to export results as CSV. If not specified, results are returned to the pipeline. .EXAMPLE PS> . .\Common\Connect-Service.ps1 PS> Connect-Service -Service Graph -Scopes 'DeviceManagementManagedDevices.Read.All' PS> .\Intune\Get-DeviceComplianceReport.ps1 Lists all managed devices with their compliance status. .EXAMPLE PS> .\Intune\Get-DeviceComplianceReport.ps1 -ComplianceState NonCompliant -Platform Windows Shows only noncompliant Windows devices. .EXAMPLE PS> .\Intune\Get-DeviceComplianceReport.ps1 -OutputPath '.\compliance-report.csv' Exports full compliance report to CSV. #> [CmdletBinding()] param( [Parameter()] [ValidateSet('All', 'Compliant', 'NonCompliant', 'Unknown')] [string]$ComplianceState = 'All', [Parameter()] [ValidateSet('All', 'Windows', 'iOS', 'Android', 'macOS')] [string]$Platform = 'All', [Parameter()] [string]$OutputPath ) $ErrorActionPreference = 'Stop' # Verify Graph connection if (-not (Assert-GraphConnection)) { return } # Map platform filter to Graph operatingSystem values $platformMap = @{ 'Windows' = 'Windows' 'iOS' = 'iOS' 'Android' = 'Android' 'macOS' = 'macOS' } Write-Verbose "Retrieving managed devices..." try { $devices = Get-MgDeviceManagementManagedDevice -All } catch { Write-Error "Failed to retrieve managed devices: $_" return } # Apply platform filter if ($Platform -ne 'All') { $targetOS = $platformMap[$Platform] $devices = $devices | Where-Object { $_.OperatingSystem -eq $targetOS } Write-Verbose "Filtered to platform: $Platform ($($devices.Count) devices)" } # Apply compliance state filter if ($ComplianceState -ne 'All') { $stateFilter = switch ($ComplianceState) { 'Compliant' { 'compliant' } 'NonCompliant' { 'noncompliant' } 'Unknown' { 'unknown' } } $devices = $devices | Where-Object { $_.ComplianceState -eq $stateFilter } Write-Verbose "Filtered to compliance state: $ComplianceState ($($devices.Count) devices)" } $results = foreach ($device in $devices) { [PSCustomObject]@{ DeviceName = $device.DeviceName UserDisplayName = $device.UserDisplayName UserPrincipalName = $device.UserPrincipalName OperatingSystem = $device.OperatingSystem OSVersion = $device.OsVersion ComplianceState = $device.ComplianceState IsEncrypted = $device.IsEncrypted LastSyncDateTime = $device.LastSyncDateTime EnrolledDateTime = $device.EnrolledDateTime Model = $device.Model Manufacturer = $device.Manufacturer SerialNumber = $device.SerialNumber ManagementAgent = $device.ManagementAgent } } $results = @($results) | Sort-Object -Property ComplianceState, DeviceName # Summary output $total = $results.Count $compliant = ($results | Where-Object { $_.ComplianceState -eq 'compliant' }).Count $nonCompliant = ($results | Where-Object { $_.ComplianceState -eq 'noncompliant' }).Count Write-Verbose "Total: $total | Compliant: $compliant | NonCompliant: $nonCompliant | Other: $($total - $compliant - $nonCompliant)" if ($OutputPath) { $results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 Write-Output "Exported $($results.Count) devices to $OutputPath" } else { Write-Output $results } |