Búsqueda de sitios web

Cómo encontrar grupos de Microsoft 365 con miembros invitados


Existe una variedad de métodos para encontrar grupos con miembros invitados

Por mucho que me gustaran las API Graph, a veces no son la opción correcta para un trabajo. Tomemos el ejemplo de un lector que quería encontrar todos los grupos de Microsoft 365 en el inquilino con miembros invitados. Querían utilizar las API Graph para filtrar grupos según la membresía, pero descubrieron que esto no es posible. En cambio, el tipo de código necesario para realizar el trabajo sería:

  • Encuentra todas las cuentas de invitados.
  • Para cada cuenta de invitado, busque los grupos a los que pertenece.
  • Informar los grupos con invitados.

Esto suena sencillo. El único problema es el tiempo necesario para interrogar a Azure AD para encontrar el conjunto de grupos para cada cuenta de invitado, seguido de una llamada a Get-MgGroup para recuperar el nombre para mostrar porque Get-MgUserMemberGroup devuelve sólo un conjunto de identificadores de grupo en lugar de detalles completos del grupo. En cualquier caso, esto es lo que se me ocurrió:

[array]$GuestAccounts = Get-MgUser -All -Filter "UserType eq 'Guest'" | Select -ExpandProperty Id
[array]$AllGroups = $Null
ForEach ($Guest in $GuestAccounts) {
   [array]$Groups = Get-MgUserMemberGroup -UserId $Guest -SecurityEnabledOnly:$false 
   $AllGroups += $Groups }
$GraphGroups = $AllGroups | Sort -Unique
ForEach ($Group in $GraphGroups) { 
    $G = Get-MgGroup -GroupId $Group 
    If ($G.GroupTypes -like "*Unified*") {
       Write-Host ("Microsoft 365 Group {0} found" -f $G.DisplayName) }
}

Código lento pero funcional

El código funciona, pero es lento. En mi inquilino con 170 cuentas de invitados y 217 grupos de Microsoft 365, el código tardó poco más de 10 segundos en encontrar los 12 grupos con miembros invitados. Eso está bien para un script único, pero podemos hacerlo mejor en términos de rendimiento y funcionalidad.

El problema inmediato es la falta de filtrado disponible para los cmdlets del SDK de Microsoft Graph PowerShell para buscar grupos con invitados. Esto obliga a la necesidad de conseguir a todos los invitados y luego encontrar los grupos a los que pertenecen. Otra complejidad es que Get-MgUserMemberGroup devuelve todos los tipos de grupos a los que puede pertenecer un invitado. En la mayoría de los casos, estos son grupos de Microsoft 365, pero puede agregar una cuenta de invitado a una lista de distribución, por lo que es necesaria una verificación adicional para garantizar que solo procesamos grupos de Microsoft 365.

Uso de Get-UnifiedGroup para buscar grupos con invitados

Sin embargo, hay disponible un filtro adecuado para el cmdlet Get-UnifiedGroup. Este no es un cmdlet Graph, pero demuestra que a menudo existen varias formas de resolver problemas en Microsoft 365. De hecho, la solución es muy fácil con Get-UnifiedGroup porque Exchange Online realiza un seguimiento del número de invitados. en cada grupo en una propiedad filtrable, lo que significa que podemos usar un filtro del lado del servidor para encontrar el conjunto de grupos con miembros invitados:

[array]$ExoGroups = Get-UnifiedGroup -Filter {GroupExternalMemberCount -gt 0}

El comando se ejecutó en menos de dos segundos, lo que es una buena mejora.

Detectar grupos que no deberían tener miembros invitados

Ahora sabemos qué grupos de Microsoft 365 tienen miembros invitados. Esa es información interesante, pero podemos usar los datos para verificar si algún invitado está en grupos que tienen etiquetas de confidencialidad que bloquean el acceso de los invitados. Si un administrador asigna una etiqueta de confidencialidad que bloquea el acceso de invitados a un grupo, la etiqueta de confidencialidad impide la adición de nuevos miembros invitados, pero no tiene ningún efecto sobre los invitados existentes. Estos miembros continúan disfrutando de acceso completo a los recursos del grupo. El hecho de que estos invitados permanezcan crea una inconsistencia que amerita una revisión para decidir si la etiqueta es incorrecta o los invitados deben ser eliminados.

Para verificar el conjunto de grupos que identificamos, necesitamos saber qué etiquetas de confidencialidad tienen configuraciones de administración de contenedores (para controlar equipos, grupos y sitios) que prohíben a los miembros invitados. Para hacer esto:

  • Ejecute el cmdlet Set-Label para buscar todas las etiquetas.
  • Busque el conjunto con la configuración de gestión de contenedores.
  • Filtre las etiquetas que bloquean el acceso de invitados.

Este código hace el trabajo y crea dos tablas hash: una con el conjunto de etiquetas de administración de contenedores y la otra con las etiquetas que permiten el acceso de invitados.

Connect-IPPSSession
[array]$Labels = Get-Label
$ContainerLabels = @{}
$LabelsAllowingGuests = @{}
ForEach ($Label in $Labels) { # Find out which labels apply blocks to guest users
       $LabelGuestAccess = $True
       $LabelActions = $Label.LabelActions | ConvertFrom-Json      
       ForEach ($LabelAction in $LabelActions) {
          If (($LabelAction.Type -eq "protectgroup") -and ($Label.ContentType -Like "*Site*")) {
             $Settings = $LabelAction.Settings
             $ContainerLabels.Add([String]$Label.ImmutableId, $Label.DisplayName)
             ForEach ($Setting in $Settings) {
                If ($Setting.Key -eq "allowaccesstoguestusers" -and $Setting.Value -eq "true") {
                  $LabelsAllowingGuests.Add([String]$Label.ImmutableId, $Label.DisplayName)}}}
}}
Write-Host “The following labels allow guest access to Groups, Teams, and Sites”
$LabelsAllowingGuests | Format-Table Value

Con las tablas hash completas, podemos verificar la etiqueta de confidencialidad asignada a cada grupo para asegurarnos de que sea coherente. Si un grupo tiene una etiqueta que no permite invitados, marcamos el grupo para que un administrador decida si los invitados deben quedarse o ser eliminados. Si la decisión es permitir invitados en la membresía de un grupo, sería mejor asignar una etiqueta de confidencialidad que permita el acceso de invitados.

ForEach ($Group in $ExoGroups) {
   $CheckLabel = $LabelsAllowingGuests.Item($Group.SensitivityLabel.Guid)
   # Write-Host "Group" $Group.DisplayName "Label" $LabelDisplayName
   If (!($CheckLabel)) { 
        $BadLabel = $ContainerLabels.Item($Group.SensitivityLabel.Guid)
        Write-Host ("The label assigned to the {0} group doesn't allow guests ({1})" -f $Group.DisplayName, $BadLabel ) }
}

The label assigned to the Corporate Business Development group doesn't allow guests (Limited Access)
The label assigned to the Sales Department team group doesn't allow guests (Limited Access)

Velocidad y eficacia

Y eso es todo. Encontramos grupos con miembros invitados y verificamos que los grupos tuvieran una etiqueta de confidencialidad adecuada. El uso de un filtro del lado del servidor para encontrar los grupos significa que el rendimiento es mucho mejor con Get-UnifiedGroup de lo que es posible actualmente con los cmdlets Graph.

Como nota al margen, en los últimos años, Microsoft ha desarrollado el conjunto de controles disponibles para la gestión de contenedores. Un ejemplo reciente es el control sobre la capacidad de compartir externamente del sitio. Incluso si no desea utilizar etiquetas de confidencialidad para proteger documentos de Office (y archivos PDF), usar etiquetas para la administración de contenedores es una excelente manera de aplicar configuraciones consistentes en equipos, grupos y sitios.

Artículos relacionados