Utilice una identidad administrada de Azure Automation con Exchange Online
Exchange en línea y automatización de Azure
Actualizado el 15 de febrero de 2024
En un artículo anterior, exploré cómo usar los módulos SDK de Microsoft Teams y Microsoft Graph PowerShell con identidades administradas de Azure Automation. En ese momento, noté que Exchange Online no admitía identidades administradas. El problema desapareció cuando Microsoft lanzó la V3.0 del módulo de administración de Exchange Online, completo con soporte para identidades administradas. Para conectarse a Exchange Online con una identidad administrada es necesario especificar la organización a la que conectarse, y eso es todo.
Connect-ExchangeOnline -ManagedIdentity -Organization office365itpros.onmicrosoft.comLa entidad de servicio que pertenece a la identidad administrada necesita permiso para realizar acciones de administración de Exchange Online. Noté que no es posible crear un nuevo grupo de Microsoft 365 con el cmdlet Newew-UnifiedGroup. Esto podría ser un problema temporal o quizás este cmdlet aún no sea capaz de funcionar con una identidad administrada.
Actualización: utilice siempre la última versión del módulo de administración de Exchange Online (V3.0 o superior) para conectarse a Exchange Online con Azure Automation. Los métodos que se describen a continuación son ahora sólo de interés histórico. Consulte la documentación de Microsoft para obtener más información. Microsoft aún no ha actualizado algunos cmdlets de administración de grupos de Microsoft 365 para que funcionen con Azure Automation después de autenticarse con una identidad administrada. La funcionalidad de estos cmdlets se puede reemplazar con cmdlets del SDK de Microsoft Graph PowerShell o solicitudes de Graph API.
Uso de identidades administradas con Exchange PowerShell V1
Mientras esperamos que Microsoft entregue un módulo de producción, es posible utilizar el módulo Exchange V1 anterior con una identidad administrada. El MVP Vasil Michev explica cómo en su blog. Antes de continuar, es importante decir que Microsoft tampoco admite este método. Funciona, pero si lo usa en producción, no espere poder llamar al soporte de Microsoft si algo sale mal.
El paso importante en el proceso es asignar la función Administrar Exchange como aplicación a la entidad de servicio de la identidad administrada que elija utilizar. Esto se hace mediante:
- Obtener los detalles de la aplicación empresarial de Microsoft registrada para la administración de Exchange.
- Obteniendo el identificador de permiso para la función Administrar Exchange como aplicación del conjunto de funciones definidas para la aplicación de administración de Exchange.
- Usar la información para asignar la función Administrar Exchange como aplicación a la entidad de servicio para la identidad administrada.
Una vez más, PowerShell es la única forma de realizar la tarea. Aquí está el código que utilicé:
$ExoApp = Get-MgServicePrincipal -Filter "AppId eq '00000002-0000-0ff1-ce00-000000000000'"
$AppPermission = $ExoApp.AppRoles | Where-Object {$_.DisplayName -eq "Manage Exchange As Application"}
$AppRoleAssignment = @{
"PrincipalId" = $ManagedIdentityApp.Id
"ResourceId" = $ExoApp.Id
"AppRoleId" = $AppPermission.Id
}
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ManagedIdentityApp.Id -BodyParameter $AppRoleAssignment
Una vez que la entidad de servicio tenga la función que le permite actuar como administrador de Exchange, podemos ponerlo a trabajar. Este código es un ejemplo del uso de la identidad administrada para iniciar sesión en Exchange Online usando un token de acceso generado para la identidad (usando una cuenta especial llamada OAuthUser@ más el identificador del inquilino (OAuthUser@a662313f-14fc-43a2-9a7a-d2e27f4f3478 en este caso). Después de conectarnos, ejecutamos algún código estándar de Exchange PowerShell para encontrar todos los buzones de correo de los usuarios y devolver algunas estadísticas de los buzones.
# Get token with Service Principal for managed identity
$ResourceURI = "https://outlook.office365.com/"
$TokenAuthURI = $env:IDENTITY_ENDPOINT + "?resource=$resourceURI&api-version=2019-08-01"
$TokenResponse = Invoke-RestMethod -Method Get -Headers @{"X-IDENTITY-HEADER"="$env:IDENTITY_HEADER"} -Uri $tokenAuthURI
$AccessToken = $TokenResponse.access_token
$Authorization = "Bearer {0}" -f $accessToken
$Password = ConvertTo-SecureString -AsPlainText $Authorization -Force
$Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList "OAuthUser@a662313f-14fc-43a2-9a7a-d2e27f4f3478",$Password
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/PowerShell-LiveId?BasicAuthToOAuthConversion=true -Credential $Ctoken -Authentication Basic -AllowRedirection -Verbose
Import-PSSession $Session | Format-List
$Mbx = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited
$MbxList = [System.Collections.Generic.List[Object]]::new()
ForEach ($M in $Mbx) {
$Stats = Get-MailboxStatistics -Identity $M.DistinguishedName
$MLine = [PSCustomObject][Ordered]@{ # Write out details of the private channel and its members
Mailbox = $M.DisplayName
UPN = $M.UserPrincipalName
Items = $Stats.ItemCount
Size = $Stats.TotalItemSize
LastInteraction = $Stats.LastInteraction
ProhbitSendQuota = $M.ProhibitSendReceiveQuota }
$MbxList.Add($MLine) }
$MbxList | Sort-Object Items -Descending | Format-Table Mailbox, Items, Size
Remove-PSSession $Session
El código funciona (Figura 1) con la gran advertencia de que solo están disponibles los cmdlets antiguos (el conjunto que se originó localmente). No se puede utilizar ninguno de los cmdlets basados en REST más nuevos que se encuentran en el módulo de administración de Exchange Online (como Get-EXOMailbox).
Uso del módulo Exchange Online V2
Si desea utilizar los cmdlets del módulo Exchange Online V2 para aprovechar su velocidad y confiabilidad al recuperar grandes cantidades de objetos, puede hacerlo, pero no con una identidad administrada (por ahora). En su lugar, podría utilizar algunas de las técnicas exploradas en artículos anteriores, en particular almacenar las credenciales de nombre de usuario y contraseña en Azure Key Vault. La cuenta debe tener la función de administrador de Exchange para poder realizar tareas administrativas de Exchange. Esta podría ser una etapa intermedia para permitir la automatización de algunos procesamientos periódicos repetitivos mientras se espera que Microsoft perfeccione el soporte de identidad administrada para Exchange Online.
Tome el script que escribí para verificar los buzones de correo compartidos para obtener las licencias adecuadas. Normalmente, los buzones de correo compartidos no necesitan licencias, pero una vez que un buzón compartido almacena más de 50 GB de contenido, tiene un archivo o está en suspensión por litigio, las reglas cambian y el buzón necesita una licencia Exchange Online Plan 2. Puede ignorar el requisito, pero eventualmente Exchange impedirá que el buzón reciba y envíe correos electrónicos, y ese es un mal lugar para estar.
El script utiliza los cmdlets Get-ExoMailbox y Get-ExoMailboxStatistics para interactuar con los buzones y el cmdlet Get-MgUserLicenseDetail (del SDK de Microsoft Graph PowerShell). ) para comprobar el estado de la licencia de las cuentas de Azure AD propietarias de los buzones de correo compartidos.
Para ejecutar el script en Azure Automation, incluí el código para iniciar sesión en el SDK de Microsoft Graph PowerShell con una cuenta administrada y obtuve las credenciales de la cuenta de Azure Key Vault. Aquí está el código para recuperar las credenciales y conectarse a Exchange:
# Connect to AzAccount to access Key Vault to fetch variables used by the script
$AzConnection = Connect-AzAccount -Identity | Out-Null
# Get username and password from Key Vault
$UserName = Get-AzKeyVaultSecret -VaultName "Office365ITPros" -Name "ExoAccountName" -AsPlainText
$UserPassword = Get-AzKeyVaultSecret -VaultName "Office365ITPros" -name "ExoAccountPassword" -AsPlainText
# Create credentials object from the username and password
[securestring]$SecurePassword = ConvertTo-SecureString $UserPassword -AsPlainText -Force
[pscredential]$UserCredentials = New-Object System.Management.Automation.PSCredential ($UserName, $SecurePassword)
Connect-ExchangeOnline -Credential $UserCredentials
Después de eso, solo fue cuestión de actualizar ligeramente el código del script para cambiar algunos detalles (como eliminar algunas instancias de Write-Host y actualizar otras para usar Write-Output en su lugar). - no tiene sentido incluir muchos resultados informativos cuando se ejecuta un script en Azure Automation). También incluí un comando Disconnect-ExchangeOnline en el script para eliminar la conexión a Exchange Online cuando finalice el script. Esto evita encontrar problemas al ejecutar el script varias veces en rápida sucesión durante las pruebas, ya que Azure Automation no permite más de tres conexiones simultáneas.
Como esperaba, todo funcionó sin problemas (Figura 2). No pasé por el proceso de creación de resultados adecuados para el consumo de los administradores. Esto se podría hacer utilizando cualquiera de estos métodos conocidos:
- Publicar un mensaje en un canal de Teams.
- Crear un documento en un sitio de SharePoint Online.
- Envío de correo electrónico.
Siguiente paso: producción
De los dos métodos, prefiero usar el segundo, ya que siempre prefiero usar los cmdlets de Exchange Online V2. Es interesante conectarse a los módulos V1 utilizando una identidad administrada, pero es más práctico utilizar los cmdlets V2, especialmente porque serán la base de la solución de producción. Mientras tanto, obtener credenciales de Azure Key Vault no es perfecto, pero funciona y eso suele ser lo más importante.

