Get-DevicesInGroup.ps1
<#PSScriptInfo
.VERSION 1.0.0 .GUID 50db3d8c-c711-4c50-8396-3ca68b01b27d .AUTHOR Giovanni Solone .TAGS powershell entra microsoft graph devices groups .LICENSEURI https://opensource.org/licenses/MIT .PROJECTURI https://github.com/gioxx/Nebula.Scripts/Entra/Get-DevicesInGroup.ps1 #> # Requires -Version 7.0 <# .SYNOPSIS The script allows obtaining a list of devices in an Entra group. .DESCRIPTION This script can be used to obtain an ordered list of devices (Id, Hostname, Owner) that are within an Entra group. Allows you to make it easier to create a report otherwise unavailable in the Intune or Enter dashboard. It also allows the results to be exported to a CSV file for later and more convenient analysis. .PARAMETER GroupName The name of the Entra group to retrieve devices from. .PARAMETER ExportCSV When specified, the script will export the results to a CSV file. .EXAMPLE .\Get-DevicesInGroup.ps1 -GroupName "All Windows 11 Devices" Runs the script interactively, allowing you to view the results. .EXAMPLE .\Get-DevicesInGroup.ps1 -GroupName "All Windows 11 Devices" -ExportCSV Runs the script and exports the results to a CSV file. .NOTES Credits: https://www.reddit.com/r/PowerShell/comments/1c814xa/using_graph_api_via_powershell_to_report_entra/ https://o365reports.com/2023/04/18/get-azure-ad-devices-report-using-powershell/ Modification History: - #> param ( [Parameter(Mandatory = $true)] [string] $GroupName, [switch] $ExportCSV ) if (-not (Get-MgContext)) { Connect-MgGraph -Scopes "Group.Read.All", "Device.Read.All", "Directory.Read.All" -NoWelcome -ErrorAction Stop } try { $groupId = (Get-MgGroup -Filter "displayName eq '$GroupName'").Id } catch { Write-Error "Group '$GroupName' not found in your tenant. $_" exit } $group = Get-MgGroup -GroupId $groupId -ErrorAction Stop Write-Host "Group $groupId ($($group.DisplayName))" $devices = Get-MgGroupMember -GroupId $groupId -All $results = @() $counter = 0 foreach ($device in $devices) { $props = $device.AdditionalProperties $displayName = $props.displayName $owners = Get-MgDeviceRegisteredOwner -DeviceId $device.Id -All -ErrorAction SilentlyContinue | Select-Object -ExpandProperty AdditionalProperties # $ownerUPNs = @($owners.userPrincipalName) -join ',' $ownerUPNs = $owners | ForEach-Object { if ($_ -and $_["displayName"] -and $_["userPrincipalName"]) { "$($_["displayName"]) ($($_["userPrincipalName"]))" } elseif ($_["userPrincipalName"]) { $_["userPrincipalName"] } else { "N/A" } } $ownerUPNs = $ownerUPNs -join ', ' $results += [PSCustomObject]@{ DeviceId = $device.Id DisplayName = $displayName Owners = if ($ownerUPNs) { $ownerUPNs } else { 'N/A' } } Write-Progress -Activity "Searching for devices" -Status "Retrieved $counter of $($devices.Count): $($displayName)" -PercentComplete (($counter / $devices.Count) * 100) $counter++ } $results | Format-Table -AutoSize if ($ExportCSV) { $CSVName = $group.DisplayName -replace '[^a-zA-Z0-9]', '_' $CSVName = $CSVName -replace '_+', '_' $CSVName = $CSVName.TrimEnd('_') $exportPath = "Devices_$($CSVName)_$(Get-Date -Format 'yyyyMMdd').csv" $results | Export-Csv -Path $exportPath -NoTypeInformation -Encoding UTF8 Write-Host "Exported to $exportPath" -ForegroundColor Green } |