Jerarquía de Active Directory: obtener todos los usuarios dentro de un grupo, incluidos los grupos secundarios

Un usuario Pregunto ✅

mof

Hola,

He estado jugando con Active Directory como fuente de datos en PowerBI por un tiempo, tratando de hacer informes.

Un informe que me interesa es «Usuarios en el grupo de administradores».

Mi grupo de administradores tiene una cantidad de usuarios, así como un grupo: administradores de dominio.

Los administradores de dominio también tienen un grupo: administradores de seguridad.

Estoy tratando de navegar por el árbol de alguna manera en M o DAX para poder obtener una lista de «En el grupo de administradores, todos los usuarios son x, y y z», donde x está en Administradores, y está en Administradores de dominio yz está en Administradores de seguridad.

He estado pensando en ver si puedo obtener una lista de «este grupo es un miembro de este grupo» (que puedo hacer usando top.memberOf) pero parece que no puedo averiguar cómo navegar de Administradores de seguridad a Administradores, por lo que puedo ver que Security Admins es miembro de Domain admins and Administrators.

Si pudiera hacer eso, desde allí podría decir que dado que el usuario z está en Administradores de seguridad, también está en Administradores de dominio y Administradores.

Específicamente, estoy tratando de encontrar una solución genérica aquí, en lugar de codificar mi árbol en el programa.

¿Estoy ladrando al árbol equivocado? ¿Cómo hago este tipo de consulta recursiva en M/DAX?

@Moof,

Ayude a publicar datos de muestra de sus tablas y publique el resultado esperado basado en datos de muestra aquí.

Saludos,
lidia

mof

En respuesta a v-yuezhe-msft

O, colocándolo de otra manera…

Tengo una jerarquía de grupos en ActiveDirectory y un montón de usuarios que pertenecen a esos grupos.

Security Administrators es miembro de Domain Admins, que es miembro de Administrators. Cada uno de estos grupos tiene usuarios en él. Quiero filtrar por Administradores de grupo y obtener usuarios de todos los subgrupos.

Esencialmente, usando la fecha de la muestra, el resultado que busco es:

Resultado de muestra.png

El código que estoy usando para llegar allí es el siguiente:

let
    Source = ActiveDirectory.Domains("lapsang.example"),
    lapsang.example = Source{[Domain="lapsang.example"]}[#"Object Categories"],
    user1 = lapsang.example{[Category="user"]}[Objects],
    #"Expanded top" = Table.ExpandRecordColumn(user1, "top", {"cn", "memberOf"}, {"top.cn", "top.memberOf"}),
    #"Removed Other Columns" = Table.SelectColumns(#"Expanded top",{"top.cn", "top.memberOf", "distinguishedName"}),
    #"Expanded top.memberOf" = Table.ExpandListColumn(#"Removed Other Columns", "top.memberOf"),
    #"Expanded top.memberOf1" = Table.ExpandRecordColumn(#"Expanded top.memberOf", "top.memberOf", {"distinguishedName", "memberOf"}, {"top.memberOf.distinguishedName", "top.memberOf.memberOf"}),
    #"Reordered Columns1" = Table.ReorderColumns(#"Expanded top.memberOf1",{"top.cn", "distinguishedName", "top.memberOf.distinguishedName", "top.memberOf.memberOf"}),
    #"Expanded top.memberOf.memberOf" = Table.ExpandListColumn(#"Reordered Columns1", "top.memberOf.memberOf"),
    #"Expanded top.memberOf.memberOf1" = Table.ExpandRecordColumn(#"Expanded top.memberOf.memberOf", "top.memberOf.memberOf", {"distinguishedName", "memberOf"}, {"top.memberOf.memberOf.distinguishedName", "top.memberOf.memberOf.memberOf"}),
    #"Expanded top.memberOf.memberOf.memberOf" = Table.ExpandListColumn(#"Expanded top.memberOf.memberOf1", "top.memberOf.memberOf.memberOf"),
    #"Expanded top.memberOf.memberOf.memberOf1" = Table.ExpandRecordColumn(#"Expanded top.memberOf.memberOf.memberOf", "top.memberOf.memberOf.memberOf", {"distinguishedName", "memberOf"}, {"top.memberOf.memberOf.memberOf.distinguishedName", "top.memberOf.memberOf.memberOf.memberOf"}),
    #"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Expanded top.memberOf.memberOf.memberOf1", {"top.cn", "distinguishedName", "top.memberOf.memberOf.memberOf.memberOf"}, "Attribute", "Value"),
    #"Grouped Rows" = Table.Group(#"Unpivoted Columns", {"top.cn", "distinguishedName", "Value"}, {{"Count", each Table.RowCount(_), type number}}),
    #"Renamed Columns" = Table.RenameColumns(#"Grouped Rows",{{"Value", "InGroup"}}),
    #"Removed Columns" = Table.RemoveColumns(#"Renamed Columns",{"Count"})
in
    #"Removed Columns"

Ahora, como puede ver, he usado Table.ExpandListColumn y Table.ExpandRecordColumn varias veces allí, y no puedo garantizar que si consulto un AD diferente, habré logrado obtener todos los niveles de expansión.

¿Hay alguna forma de recurrir a la tabla, de modo que lo haga tantas veces como sea necesario y luego deje un resultado sin pivotar?

claitonjs

En respuesta a mof

¡Hola! Tengo la misma pregunta. ¿Tienes alguna actualización?

mof

En respuesta a v-yuezhe-msft

Vale, me ha llevado un poco de tiempo organizar un entorno de prueba.

He configurado un nuevo dominio AD. El grupo de administradores integrados tiene lo siguiente:

Grupo de administradores.png

Y luego llené la jerarquía de la siguiente manera:

Grupo de administradores de dominioGrupo de administradores de dominioGrupo de administradores de seguridadGrupo de administradores de seguridad

Como puede ver, una jerarquía bastante simple.

Estoy tratando de configurar una pantalla de auditoría que muestre los miembros de un grupo, incluidos los subgrupos que están en el grupo. Entonces, si tuviera que filtrar por los administradores del grupo, obtendría el siguiente resultado esperado para los usuarios:

  • lapsangadmin
  • Siuan Sanche (administrador)
  • Lean Sharif (administrador)

Así que ahora entro en Power BI y uso el conector AD para Usuarios. Esto me da una tabla bastante difícil de manejar:

Consulta de usuarios sin editarConsulta de usuarios sin editar

Cuando lo filtro un poco y amplío la columna «superior», obtengo:

Usuarios primer filtro.png

De nuevo, amplío esas listas en filas separadas, y amplío los registros, y obtengo…

Usuarios expandidos.png

El código que uso para llegar es:

let
    Source = ActiveDirectory.Domains("lapsang.example"),
    lapsang.example = Source{[Domain="lapsang.example"]}[#"Object Categories"],
    user1 = lapsang.example{[Category="user"]}[Objects],
    #"Expanded top" = Table.ExpandRecordColumn(user1, "top", {"cn", "memberOf"}, {"top.cn", "top.memberOf"}),
    #"Removed Other Columns" = Table.SelectColumns(#"Expanded top",{"top.cn", "top.memberOf", "distinguishedName"}),
    #"Expanded top.memberOf" = Table.ExpandListColumn(#"Removed Other Columns", "top.memberOf"),
    #"Expanded top.memberOf1" = Table.ExpandRecordColumn(#"Expanded top.memberOf", "top.memberOf", {"distinguishedName"}, {"top.memberOf.distinguishedName"}),
    #"Reordered Columns" = Table.ReorderColumns(#"Expanded top.memberOf1",{"top.cn", "distinguishedName", "top.memberOf.distinguishedName"})
in
    #"Reordered Columns"

con esto, puedo decir que lapsangadmin está en Administradores y Administradores de dominio, que Siuan Sanche (administrador) está en Administradores de dominio y que Leane Sharif (administrador) está en Administradores de seguridad.

Pero no puedo filtrar por Administradores y obtener los tres.

Así que empiezo a mirar el objeto de grupo en su lugar, que es una consulta inicial igualmente poco apetecible:

Grupos sin filtrar.png

En la parte superior, nuevamente hay una columna «memberOf», que tiene una lista de otros registros:

Grupos primer filtro.png

Y de nuevo, expandir eso me da:

Grupos expandidos.png

El código que uso para llegar aquí es:

let
    Source = ActiveDirectory.Domains("lapsang.example"),
    lapsang.example = Source{[Domain="lapsang.example"]}[#"Object Categories"],
    user1 = lapsang.example{[Category="user"]}[Objects],
    #"Expanded top" = Table.ExpandRecordColumn(user1, "top", {"cn", "memberOf"}, {"top.cn", "top.memberOf"}),
    #"Removed Other Columns" = Table.SelectColumns(#"Expanded top",{"top.cn", "top.memberOf", "distinguishedName"}),
    #"Expanded top.memberOf" = Table.ExpandListColumn(#"Removed Other Columns", "top.memberOf"),
    #"Expanded top.memberOf1" = Table.ExpandRecordColumn(#"Expanded top.memberOf", "top.memberOf", {"distinguishedName"}, {"top.memberOf.distinguishedName"}),
    #"Reordered Columns" = Table.ReorderColumns(#"Expanded top.memberOf1",{"top.cn", "distinguishedName", "top.memberOf.distinguishedName"})
in
    #"Reordered Columns"

Así que aquí es donde estoy atascado.

Eventualmente, podría seguir expandiendo el miembro de hasta que me quede sin cosas, y luego descentrar las columnas de nombre distinguido resultantes en una sola. La cuestión es que estoy tratando de hacer de esta una solución genérica que no necesita saber cuántas veces se expande, porque mientras que en este caso de prueba, solo tengo una jerarquía simple como esta, en algunos de los directorios activos que tratar con esta jerarquía puede llegar hasta 6 u 8 grupos de profundidad.

Así que supongo que estoy preguntando: ¿cómo hago este tipo de recursividad en M, de modo que pueda obtener una tabla de todos los padres que puede tener un grupo, sin necesidad de hacerlo un número específico de veces?

Supongo que estoy tratando de conseguir una tabla como esta:

Grupo Contenida en
Administradores Administradores
Administradores de seguridad Administradores de seguridad
Administradores de seguridad Administradores de dominio
Administradores de seguridad Administradores
Administradores de dominio Administradores de dominio
Administradores de dominio Administradores

…y así

Desde allí, puedo vincular a mis usuarios a esa columna de grupo y luego filtrar por un resumen de la columna contenida en.

Cualquier pista se agradece con gratitud…

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *