Búsqueda de sitios web

Crear un informe de uso de actividad de correo para dominios con PowerShell


Me preguntaron qué tan fácil sería generar un informe sobre la cantidad de correos electrónicos enviados por dominio en un inquilino de Microsoft 365. Mi respuesta inicial se centró en el registro de seguimiento de mensajes, con la idea de que se pudiera extraer el dominio de cada correo electrónico saliente y contarlos. Esta fue una mala idea. El registro de seguimiento de mensajes solo contiene datos de los últimos diez días y está lleno de información sobre mensajes del sistema, como la replicación de carpetas públicas (para aquellos que todavía usan carpetas públicas). En cualquier caso, se necesitaría mucho trabajo para extraer y refinar la información para responder la pregunta.

Informes de uso de correo

Entonces tuve una idea genial. ¿Por qué no utilizar los informes de uso de correo generados por Microsoft para usarlos en lugares como el centro de administración de Microsoft 365? La API Graph GetEmailActivityUserDetail devuelve datos de actividad de correo de los usuarios durante los últimos 7, 30, 90 o 180 días. Por ejemplo, este comando devuelve datos de actividad de los últimos 90 días y los almacena en un archivo CSV:

Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/reports/getEmailActivityUserDetail(period='D90')" -OutputFilePath 'c:\temp\Data.csv'

Los datos devueltos para cada cuenta de usuario se ven así:

Report Refresh Date      : 2023-07-22
User Principal Name      : Jeff.Clark@office365itpros.com
Display Name             : Jeff Clark
Is Deleted               : False
Deleted Date             :
Last Activity Date       : 2023-07-22
Send Count               : 129
Receive Count            : 637
Read Count               : 692
Meeting Created Count    : 0
Meeting Interacted Count : 0
Assigned Products        : OFFICE 365 E3
Report Period            : 90

Además, debido a que Microsoft calcula los datos de la actividad del correo diariamente (siempre hay un par de días de retraso), recuperar estos datos será mucho más rápido y escalable que intentar recuperar y procesar eventos de seguimiento de mensajes.

Lo mejor de todo es que uso estas API en el script de actividad del usuario de Microsoft 365, para poder reutilizar parte del código.

Acceso del SDK de Microsoft Graph PowerShell a los datos de uso

El uso de solicitudes de Graph API generalmente significa que necesita una aplicación registrada para tener los permisos necesarios para ejecutar las solicitudes. El SDK de Microsoft Graph PowerShell incluye cmdlets para acceder a los datos de actividad del usuario, lo que facilita un poco las cosas si desea ejecutar comandos interactivos o un script interactivo. Por ejemplo, para recuperar los últimos siete días de actividad de uso de correo, conéctese a Graph con los permisos necesarios (para leer datos de actividad, leer el directorio para obtener información del usuario y cambiar la configuración de ocultación del usuario; llegaremos a eso más adelante). y luego ejecute el cmdlet Get-MgReportEmailActivityUserDetail:

Connect-MgGraph -Scopes ReportSettings.ReadWrite.All, Directory.Read.All, Reports.Read.All
Get-MgReportEmailActivityUserDetail -Period 'D7' -OutFile 'c:\temp\d7.csv'

El guión que escribí realizó los siguientes pasos iniciales:

  • Ejecute Get-MgReportEmailActivityUserDetail para recuperar los datos de uso del correo durante 7, 30, 90 y 180 días.
  • El cmdlet escribe los datos de uso del correo en un archivo CSV. Terminamos con 4 archivos, uno para cada período, que el script puede importar a una matriz.
  • Encuentre todas las cuentas de usuario con licencia con Get-MgUser. El código que uso es:
[array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All | Sort-Object UserPrincipalName
  • Para cada cuenta, obtenga su actividad de uso de correo y cree un mapa de la actividad de correo de la cuenta durante 6, 30, 90 y 180 días.
  • Escriba la información en una lista de PowerShell.

Aquí está el código que escribí:

Write-Output "Fetching mail activity usage report data..."
Get-MgReportEmailActivityUserDetail -Period 'D7' -OutFile 'c:\temp\d7.csv'
Get-MgReportEmailActivityUserDetail -Period 'D30' -OutFile 'c:\temp\d30.csv'
Get-MgReportEmailActivityUserDetail -Period 'D90' -OutFile 'c:\temp\d90.csv'
Get-MgReportEmailActivityUserDetail -Period 'D180' -OutFile 'c:\temp\d180.csv'
# Import the data into arrays
[array]$D7Data = Import-CSV 'c:\temp\d7.csv' | Sort-Object 'User Principal Name'
[array]$D30Data = Import-CSV 'c:\temp\d30.csv' | Sort-Object 'User Principal Name'
[array]$D90ata = Import-CSV 'c:\temp\d90.csv' | Sort-Object 'User Principal Name'
[array]$D180Data = Import-CSV 'c:\temp\d180.csv' | Sort-Object 'User Principal Name'

# Process mailboxes
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($User in $Users) {
    [array]$D7Email = $D7Data | Where-Object {$_.'User Principal Name' -eq $User.UserPrincipalName}
    [array]$D30Email = $D30Data| Where-Object {$_.'User Principal Name' -eq $User.UserPrincipalName}
    [array]$D90Email = $D90ata | Where-Object {$_.'User Principal Name' -eq $User.UserPrincipalName}
    [array]$D180Email = $D180Data | Where-Object {$_.'User Principal Name' -eq $User.UserPrincipalName}

    If ($D7Email.'Report Refresh Date') {
      $ReportDate = Get-Date($D7Email.'Report Refresh Date') -format dd-MMM-yyyy
    } Else {
      $ReportDate = $Null }

    If ($D7Email.'Last Activity Date') {
      $LastActivityDate = Get-Date($D7Email.'Last Activity Date') -format  dd-MMM-yyyy   
    } Else {                              
      $LastActivityDate = $Null }      
    
    $ReportLine = [PSCustomObject] @{  
        User            = $User.UserPrincipalName
        Name            = $User.DisplayName      
        'Data Date'     = $ReportDate            
        'Last Activity' = $LastActivityDate      
        'D7 Mail In'    = $D7Email.'Receive Count'
        'D7 Mail Out'   = $D7Email.'Send Count'         
        'D30 Mail In'   = $D30Email.'Receive Count'  
        'D30 Mail Out'  = $D30EMail.'Send Count'     
        'D90 Mail In'   = $D90Email.'Receive Count'   
        'D90 Mail Out'  = $D90Email.'Send Count'      
        'D180 Mail In'  = $D180Email.'Receive Count'  
        'D180 Mail Out' = $D180Email.'Send Count'     
        Domain         = $User.Mail.Split('@')[1]}    
    $Report.Add($ReportLine)               
}    

Ahora tenemos una serie de registros para cuentas de usuario. Así es como se ve uno:

User          : Jeff.Clark@office365itpros.com
Name          : Jeff Clark
Data Date     : 22-Jul-2023
Last Activity : 22-Jul-2023
D7 Mail In    : 53
D7 Mail Out   : 9
D30 Mail In   : 105
D30 Mail Out  : 17
D90 Mail In   : 200
D90 Mail Out  : 27
D180 Mail In  : 637
D180 Mail Out : 129
Domain        : Office365itpros.com

Canalizar los datos a Out-GridView brinda una buena descripción general de la actividad de uso del correo para las cuentas en los cuatro períodos (Figura 1).

Para calcular la actividad de correo electrónico para los dominios, el script ejecuta el cmdlet Get-MgDomain para recuperar el conjunto de dominios registrados para el inquilino y recorre los dominios para obtener información sobre la actividad del usuario capturada de antemano. Luego mide la suma de la cifra de 180 días de correo enviado para calcular el total de correos electrónicos enviados por personas que utilizan el dominio. Aquí está el código:

[array]$Domains = Get-MgDomain | Select-Object -ExpandProperty Id 
$OutputData = [System.Collections.Generic.List[Object]]::new()     
ForEach ($Domain in $Domains) {                         
    $DomainData = $Report | Where-Object {$_.Domain -eq $Domain}  
    $DomainSendCount = ($DomainData.'D180 Mail out' | Measure-Object -Sum).Sum 
    $DomainOutput = [PSCustomObject] @{   
       'Domain'     = $Domain          
       'Send Count' = $DomainSendCount } 
    $OutputData.Add($DomainOutput)                                                          
 }                                                                                                        

# Display the domain data
$OutputData | Sort-Object 'Send Count' -Descending

El resultado resultante se ve así:

Domain                             Send Count
------                             ----------
redmondwork.org                          2503
office365itpros.com                       212
office365itproebook.com                     0

Manejo de datos de usuario ofuscados

Por supuesto, no es necesario escribir PowerShell para acceder a los datos de uso. Puede ir al centro de administración de Microsoft 365 y descargar los datos de la actividad del correo electrónico en un archivo CSV desde allí (Figura 2). Al ejecutar Excel para procesar el archivo CSV con una clasificación y algunas sumas, pronto se revelará la información.

Pero mire la información reportada en el centro de administración de Microsoft 365. Está ofuscado porque la configuración de los informes para el inquilino dicta que se debe ocultar la información personal. Los administradores pueden cambiar la configuración de los informes para exponer la información real, pero eso es sólo una molestia y existe la posibilidad de que la configuración no se restablezca a su valor original.

Afortunadamente, podemos manejar esta situación en código. Este fragmento comprueba si la configuración de visualización de nombres ocultos es Verdadera. Si es así, el script lo restablece a False para exponer los datos reales.

If ((Get-MgBetaAdminReportSetting).DisplayConcealedNames -eq $True) {
    $Parameters = @{ displayConcealedNames = $False }
    Update-MgBetaAdminReportSetting -BodyParameter $Parameters
    $DisplayConcealedNames = $True
}

Una vez completado el procesamiento, el script puede restablecer el valor a Verdadero con:

If ($DisplayConcealedNames -eq $True) {
    $Parameters = @{ displayConcealedNames = $True }
    Update-MgBetaAdminReportSetting -BodyParameter $Parameters
    $DisplayConcealedNames = $Null
}

Cambiar la configuración de visualización de nombres ocultos es la razón por la que el script necesita el permiso ReportSettings.ReadWrite.All. Puede descargar el script completo desde GitHub.

Nunca perder el tiempo con PowerShell

Esta es una respuesta larga a una pregunta que pensé que sería rápida. Sin embargo, escribir PowerShell nunca es una pérdida de tiempo y esta respuesta me permitió mostrar cómo usar Microsoft Graph para PowerShell SDK (V2) para descargar datos de uso y cambiar la configuración de los informes. ¡Nunca se sabe cuándo este conocimiento podría resultar útil!

Migración bajo demanda

Migre todas sus cargas de trabajo y Active Directory con una solución integral de migración de inquilino a inquilino de Office 365.

Artículos relacionados