Usar filtros para orientar buzones y cuentas de Azure AD
Los scripts de PowerShell a menudo comienzan por encontrar un conjunto de cuentas de usuario de Azure AD o buzones de correo de Exchange para procesar. El enfoque clásico es ejecutar un cmdlet como Get-ExoMailbox o Get-MgUser para encontrar los objetos deseados. Sin embargo, las cosas pueden complicarse un poco cuando intenta recuperar el conjunto óptimo. Por ejemplo:
- Solo buzones de usuario (excluye buzones compartidos y de sala).
- Solo cuentas con licencia (enfóquese en cuentas de Azure AD con licencias para usar los servicios de Microsoft 365).
El primer conjunto se encuentra fácilmente con:
[array]$Mailboxes = Get-ExoMailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited
El segundo con:
Select-MgProfile Beta [array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All
La sintaxis del último ejemplo es más compleja porque usa un filtro Graph para buscar cuentas con al menos una licencia (el recuento es mayor que 0) que son miembros (no invitados) del arrendatario. También es a lo que Microsoft se refiere como una consulta avanzada contra objetos de Azure AD, razón por la cual está presente el parámetro de nivel de coherencia. El comando Select-MgProfile le dice al SDK que use el punto de conexión beta, que es la única forma disponible actualmente para recuperar información de licencia para cuentas de Azure AD.
El problema es que las cuentas que usan los buzones compartidos y los buzones de sala pueden tener licencias. Los buzones de correo compartidos necesitan licencias para usar un archivo o tener una mayor cuota de buzón, mientras que los buzones de sala tienen licencias cuando los usan los dispositivos de Teams Rooms. Es posible que su secuencia de comandos no necesariamente quiera procesar estas cuentas porque la intención es tratar con cuentas que pertenecen a humanos en lugar de habitaciones o dispositivos.
Después de crear la matriz de buzones de correo compartidos y de sala, es fácil filtrar la matriz de usuarios para eliminar las cuentas que no están en esa matriz:
[array]$NonUserAccounts = Get-ExoMailbox -RecipientTypeDetails SharedMailbox, RoomMailbox -ResultSize Unlimited | Select-Object UserPrincipalName, ExternalDirectoryObjectId Write-Host "Removing non-user accounts from set to be processed..." $Users = $Users | Where-Object {$_.Id -notin $NonUserAccounts.ExternalDirectoryObjectId}
El resultado es una matriz que contiene cuentas de Azure AD con licencia que pertenecen a humanos. Uso esta técnica en el script para crear un informe HTML de los gerentes y sus informes directos.
Buscar cuentas de usuario de Azure AD para empleados
Azure AD incluye varios atributos para los datos de los empleados. Tres atributos importantes son:
- EmployeeId: un valor de cadena que contiene el identificador de empleado asignado por la organización. A menudo, esto es un número.
- EmployeeHireDate: un valor de fecha para cuando el empleado se unió a la organización.
- EmployeeType: un valor de cadena para indicar el tipo de empleado. Por ejemplo, podría almacenar valores como «Temporal», «Permanente» y «Tiempo parcial» en este atributo.
Los atributos de los empleados no forman parte del conjunto predeterminado que devuelve el gráfico. Puede filtrar según los atributos de forma normal, pero si desea ver los datos, debe especificar los atributos en la solicitud de gráfico. Por ejemplo, este comando Get-MgUser encuentra cuentas miembro con algún valor en el atributo EmployeeId sin incluir el valor del atributo en los datos devueltos por Graph. La comparación con un espacio es una de las debilidades a tener en cuenta cuando se trabaja con el Gráfico.
[array]$Employees = Get-MgUser -filter "userType eq 'Member' and EmployeeId ge ' '" $Employees | Format-Table DisplayName, EmployeeId DisplayName EmployeeId ----------- ---------- Rene Artois Tony Redmond
Para ver los datos de los empleados, especifique las propiedades para que regrese la llamada:
[array]$Employees = Get-MgUser -filter "userType eq 'Member' and EmployeeId ge ' '" -Property Id, displayname, userprincipalname, employeeid, employeehiredate, employeetype $Employees | Format-Table DisplayName, EmployeeId, EmployeeType, EmployeeHireDate DisplayName EmployeeId EmployeeType EmployeeHireDate ----------- ---------- ------------ ---------------- Rene Artois 111888 Permanent 08/03/2018 00:00:00 Tony Redmond 150847 Permanent 01/01/2011 00:00:00
Desafortunadamente, Graph no admite el filtrado según el tipo de empleado o las propiedades de fecha de contratación del empleado (consulte esta página como referencia). Si desea filtrar según la fecha de contratación, cree la matriz de empleados como se muestra arriba y use un filtro del lado del cliente. Por ejemplo, este código busca empleados contratados en los últimos diez años:
$CheckDate = (Get-Date).AddDays(-3650) $Employees | Where-Object {$CheckDate -as [datetime] -lt $_.EmployeeHireDate}
Mientras que este comando encuentra cuentas con el tipo de empleado marcado como permanente.
$Employees | Where-Object {$_.EmployeeType -eq "Permanent"}
También necesitará un filtro del lado del cliente para usar los operadores de comparación similares, de coincidencia y otros disponibles en PowerShell. Las solicitudes de gráficos se limitan a eq, and, or, y comienzan con cuando se evalúan las cuentas de usuario de Azure AD.
Encuentre usuarios de Azure AD con atributos personalizados de Exchange
El uso de cualquier consulta en Azure AD depende de que haya datos precisos en los atributos consultados. Mi experiencia es que relativamente pocos inquilinos de Microsoft 365 completan los atributos de empleados disponibles en Azure AD. Esto puede deberse a que muchas organizaciones son híbridas o tienen otras razones para no usar los atributos de los empleados (como no saber que están disponibles) o porque se están usando otros esquemas. Por ejemplo, las organizaciones que usan Active Directory y Exchange Server a veces marcan cuentas «humanas» almacenando un valor en un atributo personalizado (extensión). El atributo puede almacenar valores como Empleado, Temporal, Consultor y Cuenta de servicio para indicar el propósito de la cuenta. Este ejemplo busca cuentas de Azure AD con licencia donde ExtensionAttribute2 almacena «Empleado» para marcar cuentas que pertenecen a humanos.
[array]$EmployeeAccounts = Get-MgUser -Filter "onPremisesExtensionAttributes/extensionAttribute2 eq 'Employee' and assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All
Si su organización usa atributos personalizados de Exchange para almacenar información de los empleados, no hay una buena razón para cambiar al uso de los atributos de Azure AD, a menos que quiera o necesite usar los atributos de Exchange para un propósito diferente. El cambio es una cuestión de leer los atributos de Exchange Online y escribirlos en Azure AD, por lo que es sencillo. Aquí hay un código simple para ilustrar cómo obtener los detalles de los empleados de Exchange Online y escribirlos en la cuenta de Azure AD del usuario. El valor de EmployeeType se toma de CustomAttribute2, mientras que el valor de EmployeeHireDate proviene de la fecha de creación del buzón.
[array]$Mailboxes = Get-ExoMailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited -Properties CustomAttribute2, WhenCreated ForEach ($Mbx in $Mailboxes) { Update-MgUser -UserId $Mbx.ExternalDirectoryObjectId -EmployeeType $Mbx.CustomAttribute2 -EmployeeHireDate (Get-Date($Mbx.WhenCreated)) }
División del procesamiento
A veces, una organización abarca tantas cuentas que lleva mucho tiempo obtener todas las cuentas. En estas circunstancias, puede dividir el procesamiento dividiendo las cuentas en conjuntos convenientes. Algunas personas usan departamentos como base para el procesamiento y otras usan países. En este ejemplo, buscamos cuentas con licencia de Azure AD según el apellido. La Figura 1 muestra el resultado.
[array]$Surnames = "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "W", "X", "Y", "Z" ForEach ($S in $Surnames) { $Filter = "assignedLicenses/`$count ne 0 and userType eq 'Member' and startsWith(surname,('$S'))" [array]$Users = Get-MgUser -Filter $Filter -ConsistencyLevel eventual -CountVariable Records -All If ($Users) { Write-Host ("{0} users have surname starting with {1}" -f $Users.count, $S) Write-Host "---------------------------------------------" $Users | Format-Table DisplayName, Surname Write-Host "" } Else { Write-Host ("No users found with surname starting with {0}" -f $S) } }
Figura 1: busque usuarios de Azure AD con el primer carácter de su apellido
Parte de una Transición
Hacer llamadas efectivas para encontrar buzones o cuentas de Azure AD puede ser la creación o el fracaso de un script de PowerShell. El cambio del módulo obsoleto de Azure AD a los comandos Graph API o Graph SDK introduce un nuevo formato de filtro con el que es más difícil trabajar y carece de la flexibilidad disponible a través de los operadores de comparación estándar de PowerShell. La actualización de secuencias de comandos para usar Graph puede ser un desafío a veces, pero la forma positiva de ver las cosas es que ofrece la oportunidad de mejorar la eficiencia del código. Eso no es algo importante para las organizaciones pequeñas y medianas, pero marca una gran diferencia cuando se administran decenas de miles de cuentas o buzones.