Public/Get-GkRoleAssignableGroup.ps1
|
function Get-GkRoleAssignableGroup { <# .SYNOPSIS Report role-assignable ("privileged") groups and their owners, flagging ownerless ones. .DESCRIPTION Reads GET /groups filtered to isAssignableToRole eq true. These groups can be granted directory roles, so their owners and members are effectively privileged — a common assessment focus ("privileged unprotected groups"). Owners are resolved per group and ownerless groups are flagged. Requires Group.Read.All. Uses the ConsistencyLevel: eventual advanced-query header. .PARAMETER OwnerlessOnly Return only role-assignable groups that have no owners. .PARAMETER AsReport Flatten Owners to a '; '-joined string and add ReportGeneratedUtc. .EXAMPLE Get-GkRoleAssignableGroup All role-assignable groups with owners and ownerless flag. .EXAMPLE Get-GkRoleAssignableGroup -OwnerlessOnly Privileged groups nobody owns — a governance gap. .EXAMPLE Get-GkRoleAssignableGroup -AsReport | Export-Csv .\role-assignable-groups.csv -NoTypeInformation .OUTPUTS PSGraphKit.RoleAssignableGroup #> [CmdletBinding()] [OutputType('PSGraphKit.RoleAssignableGroup')] param( [switch] $OwnerlessOnly, [switch] $AsReport ) begin { Test-GkConnection -FunctionName 'Get-GkRoleAssignableGroup' | Out-Null $now = [datetime]::UtcNow } process { $select = 'id,displayName,groupTypes,securityEnabled,mailEnabled,visibility,isAssignableToRole' $groups = Invoke-GkGraphRequest -CallerFunction 'Get-GkRoleAssignableGroup' -Headers @{ ConsistencyLevel = 'eventual' } ` -Uri "/groups?`$filter=isAssignableToRole eq true&`$count=true&`$select=$select&`$top=999" foreach ($g in $groups) { $id = [string](Get-GkDictValue $g 'id') $ownerNames = @() if ($id) { try { $owners = Invoke-GkGraphRequest -CallerFunction 'Get-GkRoleAssignableGroup' -Uri "/groups/$id/owners?`$select=id,displayName" $ownerNames = @($owners | ForEach-Object { [string](Get-GkDictValue $_ 'displayName') } | Where-Object { $_ }) } catch { Write-Verbose "PSGraphKit: owners unavailable for group $id : $($_.Exception.Message)" } } if ($OwnerlessOnly -and $ownerNames.Count -gt 0) { continue } $obj = [ordered]@{ PSTypeName = 'PSGraphKit.RoleAssignableGroup' DisplayName = [string](Get-GkDictValue $g 'displayName') Owners = if ($AsReport) { $ownerNames -join '; ' } else { $ownerNames } OwnerCount = $ownerNames.Count IsOwnerless = ($ownerNames.Count -eq 0) Visibility = [string](Get-GkDictValue $g 'visibility') Id = $id } if ($AsReport) { $obj['ReportGeneratedUtc'] = $now } [pscustomobject]$obj } } } |