Búsqueda de sitios web

Cree un informe de archivos de SharePoint Online con el SDK de Graph PowerShell


Actualización del script de informe de archivos de SharePoint Online para usar el SDK de Graph PowerShell

En julio de 2022, escribí sobre el uso de las API Graph para generar informes sobre archivos en una biblioteca de documentos de SharePoint Online. La estructura del script era sencilla: seleccionar un sitio, seleccionar una biblioteca de documentos dentro del sitio e informar los archivos y carpetas encontrados dentro de la biblioteca. Fue mi primera oportunidad de trabajar con SharePoint Online usando Graph API y fue una experiencia de aprendizaje invaluable.

El tiempo y la tecnología avanzan y es posible hacer el mismo trabajo con el SDK de Microsoft Graph PowerShell. Prefiero usar el SDK de Graph PowerShell cuando sea posible porque es más fácil trabajar con él. Los cmdlets renuevan los tokens de acceso cuando es necesario y se encargan de la paginación al recuperar datos. Los cmdlets generan objetos de PowerShell, etc. Claro, el SDK de Graph PowerShell tiene algunas debilidades irritantes, pero generalmente trato de usar sus cmdlets en lugar de solicitudes de Graph API siempre que sea posible.

Microsoft lanzó la V2 del SDK de Graph PowerShell en 2023. Decidí reescribir el script para usar los cmdlets del SDK de Graph para explorar qué tan capaz es el SDK para manejar contenido de SharePoint Online. Microsoft tiene una versión preliminar de Graph API para la administración de SharePoint Online que imita algunas de las funciones disponibles en el módulo PowerShell de administración de SharePoint Online. No se ha avanzado mucho en el desarrollo de este módulo y no lo cubro aquí.

SharePoint Online incluye la opción Exportar a Excel en su menú de puntos suspensivos. Esta opción genera un archivo de consulta web de Microsoft Excel (.iqy) para conectarse a la ubicación actual en el sitio de SharePoint y exportar información sobre elementos y carpetas a una tabla en un libro de Excel. Útilmente, la exportación incluye todas las propiedades que se muestran en la vista predeterminada. Podrías usar esta opción en lugar del script que estoy a punto de explicar, ¡pero entonces no aprenderías a interactuar con SharePoint Online usando los cmdlets de Graph SDK!

Sitios, unidades y elementos de unidad

La gente está familiarizada con el concepto de sitios de SharePoint Online. El script comienza utilizando el cmdlet Get-MgSite para buscar sitios con nombres para mostrar o descripciones coincidentes. El primer ejemplo busca usando una cadena, el segundo usando una variable:

Get-MgSite -Search 'Projects'
$SiteName = 'Office 365'
Get-MgSite -Search ($SiteName)

SharePoint Online recorta el conjunto de sitios para excluir cualquier sitio al que el usuario que inició sesión no pueda acceder. Incluso las cuentas que tienen las funciones de administrador de SharePoint o administrador global no pueden acceder a un sitio a menos que sean miembros del sitio. El conjunto de sitios devueltos por Get-MgSite incluye los sitios creados para canales privados y compartidos de Teams. El script maneja esto pidiendo al usuario que seleccione un sitio. El valor devuelto incluye un identificador de sitio, que se ve así:

Office365itpros.sharepoint.com,acfe74d8-edfb-436d-924b-e018666605ee,a2aba197-5f1d-4864-a2c7-4daf0ff6379b

Los sitios de SharePoint Online tienen una biblioteca de documentos predeterminada llamada Documentos (en inglés). Sin embargo, un sitio puede abarcar varias bibliotecas de documentos. En términos de API, se conocen como unidades. El cmdlet Get-MgSiteDrive recupera el conjunto de unidades de un sitio:

[array]$Drives = Get-MgSiteDrive -SiteId $Site.Id

Cada unidad tiene un identificador (Id) similar a este:

b!2HT-rPvtbUOSS-AYZmYF7pehq6IdX2RIosdNrw_2N5t7xp_DBXMQTalVjpKlwdxk

Con un identificador de sitio y un identificador de unidad, podemos recuperar los elementos (elementos de unidad) en la unidad. Las unidades incluyen archivos y carpetas, por lo que se requiere algo de trabajo para procesar los dos tipos de elementos. El script incluye una función llamada Get-DriveItems para procesar archivos en una carpeta, incluido el procesamiento recursivo de elementos en carpetas anidadas. Para comenzar, el script comienza en la carpeta raíz (nivel superior):

Get-DriveItems -Drive $Drive.Id -FolderId "root"

La información recopilada para cada archivo incluye su nombre para mostrar, la carpeta a la que pertenece, el autor y quién modificó por última vez el archivo, las fechas de creación y última modificación, el tamaño del archivo y si se le asignan etiquetas de retención y confidencialidad. La Figura 1 muestra el script en ejecución.

La carpeta más grande que probé contenía 6.523 archivos.

Obtener la etiqueta de retención de un archivo

Las etiquetas de retención son compatibles con los inquilinos con Office 365 E3 y versiones posteriores. No todos los inquilinos utilizan etiquetas de retención, por lo que lo primero es verificar si hay etiquetas de retención. El script utiliza el cmdlet Get-MgSecurityLabelRetentionLabel para comprobar las etiquetas de retención. La ejecución del cmdlet requiere el consentimiento para el permiso RecordsManagement.Read.All.

# Discover if the tenant uses retention labels
[array]$RetentionLabels = Get-MgSecurityLabelRetentionLabel
If ($RetentionLabels) {
    $Global:RetentionLabelsAvailable = $true
} Else {
    $Global:RetentionLabelsAvailable = $false
}

Luego, el script sabe si debe intentar recuperar la etiqueta de retención de un archivo. Los cmdlets de Graph SDK cubren la administración de etiquetas de retención, pero no la recuperación de información de etiquetas de retención de un archivo. Para obtener la etiqueta de retención, el script utiliza una solicitud Graph:

If ($RetentionLabelsAvailable -eq $true) {
  Try {
    $Uri = ("https://graph.microsoft.com/v1.0/drives/{0}/items/{1}/retentionLabel" -f $Drive, $File.Id)
   [array]$RetentionLabelInfo = Invoke-MgGraphRequest -Uri $Uri -Method Get
   RetentionLabelName = $RetentionLabelInfo.name
   } Catch {
   Write-Host ("Error reading retention label data from file {0}" -f $File.Name) 
   }
}

Obtener la etiqueta de confidencialidad para un archivo

El cmdlet Get-MgBetaUserSecurityInformationProtectionSensitivityLabel recupera etiquetas de confidencialidad disponibles (publicadas) para la cuenta de usuario que inició sesión, lo que requiere consentimiento para el permiso InformationProtectionPolicy.Read. Este código ejecuta el cmdlet para recuperar el conjunto de etiquetas de confidencialidad y crea una tabla hash a partir del identificador y el nombre de la etiqueta. También se define una matriz que contiene los tipos de archivos admitidos por las etiquetas de confidencialidad.

$Account = (Get-MgContext).Account
[array]$SensitivityLabels = Get-MgBetaUserSecurityInformationProtectionSensitivityLabel -UserId $Account
If ($SensitivityLabels) {
    $Global:SensitivityLabelsAvailable = $true
    [array]$Global:ValidFileTypes = "docx", "pptx", "xlsx", "pdf"
    $Global:SensitivityLabelsHash = @{}
    ForEach ($Label in $SensitivityLabels) {
        $SensitivityLabelsHash.Add($Label.Id, $Label.Name)
    }
} Else {
    $Global:SensitivityLabelsAvailable = $false
}

Para recuperar la etiqueta de confidencialidad de un archivo, el script utiliza la API extractSensitivityLabels. Un archivo puede tener varias etiquetas de confidencialidad, pero solo una etiqueta puede aplicar protección mediante cifrado basado en administración de derechos. Como puede ver, se utiliza una solicitud POST. Esto se debe a que la API actualiza el sitio de SharePoint Online con detalles de la etiqueta de confidencialidad. Como señalé en un artículo anterior, esta acción puede provocar que se generen errores de etiquetas incompatibles.

If ($SensitivityLabelsAvailable -eq $true) {
  # Only check for sensitivity labels if they are available
  $FileType = $File.Name.Split(".")[1]
  If ($FileType -in $ValidFileTypes) { 
    $Uri = ("https://graph.microsoft.com/beta/sites/{0}/drive/items/{1}/extractSensitivityLabels" -f $Site.Id, $file.id)
    Try {
     [array]$SensitivityLabelInfo = Invoke-MgGraphRequest -Uri $Uri -Method POST 
     If ($SensitivityLabelInfo.labels.sensitivityLabelId) { 
       [array]$LabelName = $SensitivityLabelsHash[$SensitivityLabelInfo.labels.sensitivityLabelId]
     } Catch {
        Write-Host ("Error reading sensitivity label data from file {0}" -f $File.Name) 
       }
     }
}  

A veces se producen errores al leer las etiquetas de confidencialidad de los archivos y verá un mensaje como este:

Error al leer los datos de la etiqueta de confidencialidad del archivo Capítulo 1 - Descripción general de Office 365 - Final.docx

Una de las razones por las que esto sucede es cuando un archivo está protegido por Office Information Rights Management (IRM) en lugar de una etiqueta de confidencialidad. La solución es eliminar IRM del archivo abriendo la sección Proteger documento de la información del archivo y configurando la protección en acceso sin restricciones (Figura 2).

Otro motivo es que al archivo se le asigna una etiqueta de confidencialidad que se eliminó del inquilino o se cambió a una subetiqueta o desde ella. La solución aquí es pedirle al autor (que siempre tiene derechos para abrir un archivo) que abra el archivo y le asigne una etiqueta de confidencialidad diferente. Estoy seguro de que existen otras razones por las que la API podría fallar. Es solo que no he encontrado esas condiciones.

La salida del informe

El script procesa archivos a entre 225 y 300 archivos por minuto. Generalmente, cuantos menos archivos con etiquetas de confidencialidad se encuentren en un sitio, más rápido se ejecutará el script. Para ejecutar el script más rápido, edite el código para eliminar las líneas que obtienen información sobre el conjunto de etiquetas de confidencialidad definidas en el inquilino y las líneas que llaman a la API extractSensitivityLabels para recuperar la etiqueta de confidencialidad de un archivo.

El resultado es una lista de PowerShell (que se muestra en la Figura 3). El script también exporta el contenido de la lista a un archivo CSV.

Puede descargar el script completo desde GitHub.

La IA generativa hace que los desechos digitales sean peligrosos

Existe la tentación de dejar los archivos en paz en los sitios de SharePoint. Las políticas de retención ayudan a mantener bajo control el aumento del número de archivos, pero no eliminarán ningún archivo que tenga una etiqueta de retención con un período de retención más largo. Como puede ver en la Figura 3, algunos de los sitios que uso contienen archivos que se remontan a 2017. A menos que la cuota de almacenamiento del inquilino esté bajo presión, los administradores no tienen motivos para dedicar tiempo a buscar y eliminar archivos obsoletos y potencialmente engañosos.

Así fue hasta que llegó la era de la IA generativa. Herramientas como Copilot para Microsoft 365 pueden acceder a cualquier archivo en cualquier sitio disponible para el usuario que ha iniciado sesión. Copilot no tiene idea de si el contenido de un archivo es preciso o relevante. El contenido simplemente proporciona más palabras con las que Copilot puede trabajar a medida que genera resultados en respuesta a las indicaciones (solicitudes) de los usuarios. A menos que los usuarios de Copilot examinen los resultados generados, existe la posibilidad de que entre información inexacta. Ésa es una buena razón para eliminar archivos antiguos y obsoletos de SharePoint Online en lugar de dejar que los desechos digitales se acumulen en su lugar.

Con suerte, este script ayudará a las personas a comprender cómo usar el SDK de Microsoft Graph PowerShell para navegar por los sitios de SharePoint Online y obtener una idea de cuánto contenido antiguo persiste. El siguiente paso lógico podría ser editar el archivo CSV para eliminar los elementos que deben conservarse y utilizar el resto como entrada para su eliminación mediante la API Eliminar elemento. ¡Ese es un tema digno de otro artículo!

Artículos relacionados