Búsqueda de sitios web

Mejore el rendimiento de Microsoft Graph PowerShell con procesamiento por lotes


El procesamiento por lotes (también conocido como procesamiento por lotes JSON) se puede usar con Microsoft Graph PowerShell para mejorar el rendimiento de los scripts existentes que necesitan interactuar con servicios en Microsoft 365, Microsoft Entra o Microsoft Intune.

El concepto de procesamiento por lotes es bastante simple. Usted recopila la información para realizar múltiples solicitudes y luego las envía como un "lote" a la API de Microsoft Graph. Esto le permite realizar muchas solicitudes al mismo tiempo, mejorando así el tiempo total de sus scripts.

¿Qué es el procesamiento por lotes de solicitudes?

El procesamiento por lotes de solicitudes permite que las aplicaciones combinen múltiples solicitudes a Microsoft Graph para mejorar el rendimiento y reducir la latencia. También se puede utilizar en Microsoft Graph PowerShell para ayudar a los administradores a mejorar el rendimiento de las tareas y scripts de administración.

Un lote de solicitudes es una colección de solicitudes dentro de un único objeto JSON, que en PowerShell se puede almacenar dentro de una variable. El objeto JSON se puede generar de varias formas, entre ellas:

  • Definiéndolo manualmente entre aquí-cadenas.
  • Definiendo una tabla hash y convirtiéndola a JSON.
  • Construyendo un objeto a través de código y convirtiéndolo a JSON (más eficiente)

Luego, el lote se puede enviar a Microsoft Graph mediante los cmdlets Invoke-RestMethod o Invoke-MgGraphRequest con el método POST.

¿Cuándo debería utilizar solicitudes por lotes?

El uso del mecanismo de procesamiento por lotes de solicitudes en Microsoft Graph agrega complejidad a sus scripts. Entonces, si bien puede mejorar el rendimiento de su código y el "tiempo de salida", generalmente hace que su código sea menos legible para otras personas que puedan necesitar leerlo o heredarlo. Por lo tanto, solo recomiendo realizar solicitudes por lotes cuando deba realizar muchas solicitudes a Microsoft Graph (más de 20).

Un ejemplo de dónde puede beneficiarse es si elimina muchos usuarios o dispositivos de su entorno. Si bien es fácil utilizar el filtrado con Microsoft Graph para recuperar una lista de objetos, eliminarlos requeriría solicitudes de eliminación individuales. Suponga que necesita eliminar 100 objetos de su directorio, en lugar de enviar 100 solicitudes individuales a Microsoft Graph y esperar a que cada una se ejecute antes de que comience la siguiente. En ese caso, se pueden agrupar en grupos de 20, por lo que solo necesitará realizar 5 solicitudes a Microsoft Graph.

Los beneficios de rendimiento del procesamiento por lotes en PowerShell

He realizado algunas pruebas prácticas sobre el uso de procesamiento por lotes y los beneficios de rendimiento. Para ello, he creado 2000 usuarios de prueba en Microsoft Entra (estos usuarios no tienen licencia ni están aprovisionados). 1000 usuarios los tengo almacenados en la variable $1to1000 y los otros 1000 están almacenados en la variable $1001to2000.

Este es el primer script a continuación que se ejecutó para eliminar 1000 usuarios. Este script envió una solicitud individual para eliminar a cada usuario.

Foreach ($user in $1to1000){
        Remove-MgUser -UserId $user.id
}

Con el cmdlet Measure-Command, el tiempo total hasta completar la eliminación de usuarios fue de 33 segundos.

Luego ejecuté el siguiente script, que agrupa las solicitudes en grupos de 20 y luego las envía como una sola solicitud.

for($i=0;$i -lt $1001to2000.count;$i+=20){
    $batch = @{}
    $batch['requests'] = ($1001to2000[$i..($i+19)] | select @{n='id';e={$_.id}},@{n='method';e={'DELETE'}},`
    @{n='url';e={"/users/$($_.id)"}})
    Invoke-mggraphrequest -Method POST -URI "https://graph.microsoft.com/v1.0/`$batch" -body ($batch | convertto-json) -OutputType PSObject
}

Puede ver que el tiempo total hasta la finalización es de 12 segundos, lo cual es una mejora significativa.

Ejemplo de solicitud por lotes

A continuación se muestra un ejemplo de solicitud por lotes JSON para Microsoft Graph. Puede ver que el cuerpo de la solicitud está rodeado por cadenas aquí (@' '@).

Las cadenas aquí se pueden especificar con una comilla simple (como se ve a continuación) o usando comillas dobles. La diferencia es que las comillas simples toman el texto literalmente y no expandirán las variables. Sin embargo, una comilla doble permitirá variables expandibles.

Luego, el cmdlet Invoke-MgGraphRequest se utiliza con el método POST. También utilicé una comilla invertida ( ` ) en la ruta web del URI. Esto garantiza que la cadena $batch se tome literalmente y no se expanda como una variable, lo cual es necesario para una solicitud por lotes.

La variable $batch que contiene el cuerpo de la solicitud se usa luego con la variable -body para enviar la solicitud.

$batch = @'
{
  "requests": [
    {
      "id": "1",
      "method": "GET",
      "url": "/users/[email "
    },
    {
      "id": "2",
      "method": "GET",
      "url": "/users/[email "
    },
    {
      "id": "3",
      "method": "GET",
      "url": "/users/[email "
    }
  ]
}
'@

$response = Invoke-MgGraphRequest `
-Method POST `
-URI "https://graph.microsoft.com/beta/`$batch" `
-body $batch `
-OutputType PSObject

Guardar la respuesta a una variable garantiza que pueda consultar los datos utilizando la notación de puntos. Puede utilizar el siguiente ejemplo para extraer los nombres de usuario y las direcciones de correo electrónico de los usuarios definidos en la solicitud por lotes.

$response.responses.body | Select UserPrincipalName, proxyaddresses | ft

Generando solicitudes por lotes

En mi ejemplo anterior, demostré los beneficios de rendimiento del uso de solicitudes por lotes. Con esto, utilicé un bucle For de PowerShell para generar el lote JSON para cada solicitud, donde, lo más importante, cada solicitud era una repetición contra un objeto diferente del mismo tipo. Esto le permite utilizar eficientemente el procesamiento por lotes con PowerShell; de lo contrario, no sería práctico. Aquí está el código de la plantilla:

for($i=0;$i -lt $objects.count;$i+=20){
    $batch = @{}
    $batch['requests'] = ($objects[$i..($i+19)] | select @{n='id';e={$_.id}},@{n='method';e={'DELETE'}},`
	@{n='url';e={"/users/$($_.id)"}})
    invoke-mggraphrequest -Method POST -URI "https://graph.microsoft.com/v1.0/`$batch" -body ($batch | convertto-json) -OutputType PSObject
}

Para desglosar la lógica detrás de esto, un bucle For (o declaración For) tiene tres piezas clave de información dentro de su sintaxis, que he resaltado en la imagen a continuación en la primera línea.

$i=0. Este comando se ejecutará antes de que comience el ciclo. Se utiliza para crear e inicializar una variable con un valor inicial 0.

$i -lt $obectos.count. Esta declaración es la condición (o regla) y dice que se debe seguir realizando este ciclo mientras la variable inicial $i sea menor que la cantidad total de objetos en la colección (o matriz).

$i+=20. Esta es la declaración de devolución. Esto se ejecutará en cada bucle y se agregarán 20 al valor de $i. Entonces, en el primer bucle $i=0, luego en el siguiente bucle $i=20, luego 40 y así sucesivamente.

Esto permite que el código se ejecute en bucle mientras se suma 20 a $i en cada bucle, lo cual es esencial en el siguiente paso.

La matriz $objects está resaltada a continuación y luego, entre corchetes, hay un selector de rango. En la primera pasada del bucle $i=0 y $i+19=19, esto seleccionará los primeros 20 objetos dentro de la matriz que se incluirán en el primer solicitud por lotes.

La declaración de retorno luego agregará 20 a $i listo para el segundo ciclo; durante el segundo ciclo, $i=20 y $i+19=39, seleccionando los siguientes 20 elementos de la matriz y agregándolos a la siguiente solicitud por lotes. Esto continuará hasta que $i sea menor que el total de objetos en la matriz. El resultado es que todos los objetos de la matriz se enviarán a Microsoft Graph dentro de una solicitud por lotes.

Terminando

Si bien las solicitudes por lotes pueden mejorar drásticamente el rendimiento de sus scripts, utilícelas con prudencia, ya que la complejidad adicional podría ser un problema cuando se trabaja en colaboración en scripts, especialmente si el impacto general en el rendimiento es mínimo.

También hay muchas formas diferentes de generar solicitudes por lotes. Anteriormente demostré cómo generar solicitudes mediante programación usando la declaración For en PowerShell. Esto funciona para tipos de solicitudes repetidas. Sin embargo, un método alternativo tal vez sea almacenar la información de la solicitud fuera de su secuencia de comandos (como en un archivo CSV) y luego importarla a través del código.

Artículos relacionados