private/tenantinfo/devices/Add-ZtDeviceOverview.ps1
|
<#
.SYNOPSIS Add Device overview information to tenant info. #> function Add-ZtDeviceOverview { [CmdletBinding()] param( $Database ) Write-ZtProgress -Activity 'Getting device overview' -Status 'Processing' $deviceSummaryRows = Invoke-DatabaseQuery -Database $Database -Sql @" select operatingSystem, count(*) count from Device group by operatingSystem order by operatingSystem "@ $windowsCount = ($deviceSummaryRows | Where-Object { $_.operatingSystem -eq 'Windows' } | Measure-Object -Property count -Sum).Sum $macOSCount = ($deviceSummaryRows | Where-Object { $_.operatingSystem -in @('MacMDM', 'macOS') } | Measure-Object -Property count -Sum).Sum $iosCount = ($deviceSummaryRows | Where-Object { $_.operatingSystem -in @('iOS', 'IPhone', 'iPadOS') } | Measure-Object -Property count -Sum).Sum $androidCount = ($deviceSummaryRows | Where-Object { $_.operatingSystem -like 'Android*' } | Measure-Object -Property count -Sum).Sum $linuxCount = ($deviceSummaryRows | Where-Object { $_.operatingSystem -eq 'Linux' } | Measure-Object -Property count -Sum).Sum $discoveredDeviceTotal = ($deviceSummaryRows | Measure-Object -Property count -Sum).Sum if ($null -eq $windowsCount) { $windowsCount = 0 } if ($null -eq $macOSCount) { $macOSCount = 0 } if ($null -eq $iosCount) { $iosCount = 0 } if ($null -eq $androidCount) { $androidCount = 0 } if ($null -eq $linuxCount) { $linuxCount = 0 } if ($null -eq $discoveredDeviceTotal) { $discoveredDeviceTotal = 0 } $deviceSummary = [PSCustomObject]@{ description = 'All devices by operating system.' deviceOperatingSystemSummary = [PSCustomObject]@{ windowsCount = $windowsCount macOSCount = $macOSCount iosCount = $iosCount androidCount = $androidCount linuxCount = $linuxCount } totalDevices = $discoveredDeviceTotal } $desktopRows = Invoke-DatabaseQuery -Database $Database -Sql @" select operatingSystem, trustType, isCompliant, count(*) count from Device where operatingSystem in ('Windows', 'MacMDM') and trustType is not null group by operatingSystem, trustType, isCompliant order by operatingSystem, trustType, isCompliant "@ $windowsRows = @($desktopRows | Where-Object { $_.operatingSystem -eq 'Windows' }) $macRows = @($desktopRows | Where-Object { $_.operatingSystem -eq 'MacMDM' }) $windowsTotal = ($windowsRows | Measure-Object -Property count -Sum).Sum $macTotal = ($macRows | Measure-Object -Property count -Sum).Sum $windowsEntraJoined = ($windowsRows | Where-Object { $_.trustType -eq 'AzureAd' } | Measure-Object -Property count -Sum).Sum $windowsHybridJoined = ($windowsRows | Where-Object { $_.trustType -eq 'ServerAd' } | Measure-Object -Property count -Sum).Sum $windowsEntraRegistered = ($windowsRows | Where-Object { $_.trustType -eq 'Workplace' } | Measure-Object -Property count -Sum).Sum $entraJoinedCompliant = ($windowsRows | Where-Object { $_.trustType -eq 'AzureAd' -and $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum $hybridJoinedCompliant = ($windowsRows | Where-Object { $_.trustType -eq 'ServerAd' -and $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum $registeredCompliant = ($windowsRows | Where-Object { $_.trustType -eq 'Workplace' -and $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum $entraJoinedNoncompliant = ($windowsRows | Where-Object { $_.trustType -eq 'AzureAd' -and $_.isCompliant -eq $false } | Measure-Object -Property count -Sum).Sum $hybridJoinedNoncompliant = ($windowsRows | Where-Object { $_.trustType -eq 'ServerAd' -and $_.isCompliant -eq $false } | Measure-Object -Property count -Sum).Sum $registeredNoncompliant = ($windowsRows | Where-Object { $_.trustType -eq 'Workplace' -and $_.isCompliant -eq $false } | Measure-Object -Property count -Sum).Sum $macCompliant = ($macRows | Where-Object { $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum $macNoncompliant = ($macRows | Where-Object { $_.isCompliant -eq $false } | Measure-Object -Property count -Sum).Sum if ($null -eq $windowsTotal) { $windowsTotal = 0 } if ($null -eq $macTotal) { $macTotal = 0 } if ($null -eq $windowsEntraJoined) { $windowsEntraJoined = 0 } if ($null -eq $windowsHybridJoined) { $windowsHybridJoined = 0 } if ($null -eq $windowsEntraRegistered) { $windowsEntraRegistered = 0 } if ($null -eq $entraJoinedCompliant) { $entraJoinedCompliant = 0 } if ($null -eq $hybridJoinedCompliant) { $hybridJoinedCompliant = 0 } if ($null -eq $registeredCompliant) { $registeredCompliant = 0 } if ($null -eq $entraJoinedNoncompliant) { $entraJoinedNoncompliant = 0 } if ($null -eq $hybridJoinedNoncompliant) { $hybridJoinedNoncompliant = 0 } if ($null -eq $registeredNoncompliant) { $registeredNoncompliant = 0 } if ($null -eq $macCompliant) { $macCompliant = 0 } if ($null -eq $macNoncompliant) { $macNoncompliant = 0 } $entraJoinedUnmanaged = $windowsEntraJoined - ($entraJoinedCompliant + $entraJoinedNoncompliant) $hybridJoinedUnmanaged = $windowsHybridJoined - ($hybridJoinedCompliant + $hybridJoinedNoncompliant) $registeredUnmanaged = $windowsEntraRegistered - ($registeredCompliant + $registeredNoncompliant) $macUnmanaged = $macTotal - ($macCompliant + $macNoncompliant) $desktopNodes = [System.Collections.Generic.List[object]]::new() foreach ($link in @( @{ source = 'Desktop devices'; target = 'Windows'; value = $windowsTotal }, @{ source = 'Desktop devices'; target = 'macOS'; value = $macTotal }, @{ source = 'Windows'; target = 'Entra joined'; value = $windowsEntraJoined }, @{ source = 'Windows'; target = 'Entra registered'; value = $windowsEntraRegistered }, @{ source = 'Windows'; target = 'Entra hybrid joined'; value = $windowsHybridJoined }, @{ source = 'Entra joined'; target = 'Compliant'; value = $entraJoinedCompliant }, @{ source = 'Entra joined'; target = 'Non-compliant'; value = $entraJoinedNoncompliant }, @{ source = 'Entra joined'; target = 'Unmanaged'; value = $entraJoinedUnmanaged }, @{ source = 'Entra hybrid joined'; target = 'Compliant'; value = $hybridJoinedCompliant }, @{ source = 'Entra hybrid joined'; target = 'Non-compliant'; value = $hybridJoinedNoncompliant }, @{ source = 'Entra hybrid joined'; target = 'Unmanaged'; value = $hybridJoinedUnmanaged }, @{ source = 'Entra registered'; target = 'Compliant'; value = $registeredCompliant }, @{ source = 'Entra registered'; target = 'Non-compliant'; value = $registeredNoncompliant }, @{ source = 'Entra registered'; target = 'Unmanaged'; value = $registeredUnmanaged }, @{ source = 'macOS'; target = 'Compliant'; value = $macCompliant }, @{ source = 'macOS'; target = 'Non-compliant'; value = $macNoncompliant }, @{ source = 'macOS'; target = 'Unmanaged'; value = $macUnmanaged } )) { if ($link.value -gt 0) { $desktopNodes.Add([PSCustomObject]$link) } } $desktopDevicesSummary = [PSCustomObject]@{ description = 'Desktop devices (Windows and macOS) by join type and compliance status.' nodes = $desktopNodes totalDevices = $windowsTotal + $macTotal entrajoined = $windowsEntraJoined entrahybridjoined = $windowsHybridJoined entrareigstered = $windowsEntraRegistered } $mobileRows = Invoke-DatabaseQuery -Database $Database -Sql @" select operatingSystem, isCompliant, count(*) count from Device where operatingSystem like 'Android%' or operatingSystem in ('iOS', 'IPhone', 'iPadOS') group by operatingSystem, isCompliant order by operatingSystem, isCompliant "@ $androidRows = @($mobileRows | Where-Object { $_.operatingSystem -like 'Android*' }) $iosRows = @($mobileRows | Where-Object { $_.operatingSystem -in @('iOS', 'IPhone', 'iPadOS') }) $androidTotal = ($androidRows | Measure-Object -Property count -Sum).Sum $iosTotal = ($iosRows | Measure-Object -Property count -Sum).Sum $androidCompliant = ($androidRows | Where-Object { $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum $iosCompliant = ($iosRows | Where-Object { $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum if ($null -eq $androidTotal) { $androidTotal = 0 } if ($null -eq $iosTotal) { $iosTotal = 0 } if ($null -eq $androidCompliant) { $androidCompliant = 0 } if ($null -eq $iosCompliant) { $iosCompliant = 0 } $androidNoncompliant = [Math]::Max(0, $androidTotal - $androidCompliant) $iosNoncompliant = [Math]::Max(0, $iosTotal - $iosCompliant) $mobileNodes = [System.Collections.Generic.List[object]]::new() foreach ($link in @( @{ source = 'Mobile devices'; target = 'Android'; value = $androidTotal }, @{ source = 'Mobile devices'; target = 'iOS'; value = $iosTotal }, @{ source = 'Android'; target = 'Compliant'; value = $androidCompliant }, @{ source = 'Android'; target = 'Non-compliant'; value = $androidNoncompliant }, @{ source = 'iOS'; target = 'Compliant'; value = $iosCompliant }, @{ source = 'iOS'; target = 'Non-compliant'; value = $iosNoncompliant } )) { if ($link.value -gt 0) { $mobileNodes.Add([PSCustomObject]$link) } } $mobileSummary = [PSCustomObject]@{ description = 'Mobile devices by platform and compliance status.' nodes = $mobileNodes totalDevices = $androidTotal + $iosTotal } $ownershipRows = Invoke-DatabaseQuery -Database $Database -Sql @" select deviceOwnership, count(*) count from Device where accountEnabled and "isManaged" group by deviceOwnership order by deviceOwnership "@ $corporate = ($ownershipRows | Where-Object { $_.deviceOwnership -eq 'Company' } | Select-Object -ExpandProperty count) $personal = ($ownershipRows | Where-Object { $_.deviceOwnership -eq 'Personal' } | Select-Object -ExpandProperty count) if ($null -eq $corporate) { $corporate = 0 } if ($null -eq $personal) { $personal = 0 } $deviceOwnership = [PSCustomObject]@{ corporateCount = $corporate personalCount = $personal } $complianceRows = Invoke-DatabaseQuery -Database $Database -Sql @" select isCompliant, count(*) count from Device group by isCompliant order by isCompliant "@ $compliantCount = ($complianceRows | Where-Object { $_.isCompliant -eq $true } | Measure-Object -Property count -Sum).Sum $totalComplianceCount = ($complianceRows | Measure-Object -Property count -Sum).Sum if ($null -eq $compliantCount) { $compliantCount = 0 } if ($null -eq $totalComplianceCount) { $totalComplianceCount = 0 } $nonCompliantCount = [Math]::Max(0, $totalComplianceCount - $compliantCount) if (($compliantCount + $nonCompliantCount) -le 0 -and $discoveredDeviceTotal -gt 0) { $nonCompliantCount = $discoveredDeviceTotal } $deviceCompliance = [PSCustomObject]@{ '@odata.context' = $null id = $null inGracePeriodCount = 0 configManagerCount = 0 unknownDeviceCount = 0 notApplicableDeviceCount = 0 compliantDeviceCount = $compliantCount remediatedDeviceCount = 0 nonCompliantDeviceCount = $nonCompliantCount errorDeviceCount = 0 conflictDeviceCount = 0 } $managedSummaryRow = Invoke-DatabaseQuery -Database $Database -Sql @" select sum(case when operatingSystem = 'Windows' then 1 else 0 end) as windowsCount, sum(case when operatingSystem in ('MacMDM', 'macOS') then 1 else 0 end) as macOSCount, sum(case when operatingSystem in ('iOS', 'IPhone') then 1 else 0 end) as iOSCount, sum(case when operatingSystem like 'Android%' then 1 else 0 end) as androidCount, sum(case when operatingSystem = 'Linux' then 1 else 0 end) as linuxCount, count(*) as totalCount from Device where accountEnabled and "isManaged" "@ $fallbackWindows = $managedSummaryRow.windowsCount -as [int] $fallbackMacOS = $managedSummaryRow.macOSCount -as [int] $fallbackIOS = $managedSummaryRow.iOSCount -as [int] $fallbackAndroid = $managedSummaryRow.androidCount -as [int] $fallbackLinux = $managedSummaryRow.linuxCount -as [int] if ($null -eq $fallbackWindows) { $fallbackWindows = 0 } if ($null -eq $fallbackMacOS) { $fallbackMacOS = 0 } if ($null -eq $fallbackIOS) { $fallbackIOS = 0 } if ($null -eq $fallbackAndroid) { $fallbackAndroid = 0 } if ($null -eq $fallbackLinux) { $fallbackLinux = 0 } $fallbackManagedDevices = [PSCustomObject]@{ deviceOperatingSystemSummary = [PSCustomObject]@{ windowsCount = $fallbackWindows macOSCount = $fallbackMacOS iosCount = $fallbackIOS androidCount = $fallbackAndroid linuxCount = $fallbackLinux } enrolledDeviceCount = $fallbackWindows + $fallbackMacOS + $fallbackIOS + $fallbackAndroid desktopCount = $fallbackWindows + $fallbackMacOS mobileCount = $fallbackIOS + $fallbackAndroid totalCount = $fallbackWindows + $fallbackMacOS + $fallbackIOS + $fallbackAndroid } if (Get-ZtLicense Intune) { Write-PSFMessage 'Intune license found. Using Intune API for device details.' -Level Debug -Tag License try { $managedDevices = Invoke-ZtGraphRequest -RelativeUri 'deviceManagement/managedDeviceOverview' -ApiVersion 'beta' $managedDesktopCount = $managedDevices.deviceOperatingSystemSummary.windowsCount + $managedDevices.deviceOperatingSystemSummary.macOSCount $managedMobileCount = $managedDevices.deviceOperatingSystemSummary.iOSCount + $managedDevices.deviceOperatingSystemSummary.androidCount $managedTotalCount = $managedDesktopCount + $managedMobileCount if ($managedTotalCount -gt 0) { $managedDevices | Add-Member -MemberType NoteProperty -Name desktopCount -Value $managedDesktopCount -Force $managedDevices | Add-Member -MemberType NoteProperty -Name mobileCount -Value $managedMobileCount -Force $managedDevices | Add-Member -MemberType NoteProperty -Name totalCount -Value $managedTotalCount -Force } else { $managedDevices = $fallbackManagedDevices } } catch { Write-PSFMessage 'Failed to retrieve Intune managed device overview. Falling back to Entra device data.' -Level Warning -Tag License $managedDevices = $fallbackManagedDevices } } else { Write-PSFMessage 'Intune license not found. Using Entra device data for device details.' -Level Debug -Tag License $managedDevices = $fallbackManagedDevices } $deviceOverview = [PSCustomObject]@{ DeviceSummary = $deviceSummary DesktopDevicesSummary = $desktopDevicesSummary ManagedDevices = $managedDevices MobileSummary = $mobileSummary DeviceCompliance = $deviceCompliance DeviceOwnership = $deviceOwnership } Add-ZtTenantInfo -Name 'DeviceOverview' -Value $deviceOverview Write-ZtProgress -Activity 'Getting device overview' -Status 'Completed' } |