Cuando publiqué en junio la nota de que la aprobación de varios administradores ahora se aplica a la automatización a través de Graph API, se convirtió en una de las páginas más leídas de este sitio, y los correos que siguieron preguntaban todos lo mismo: no qué había cambiado, sino cómo programarlo. Esta guía es ese recorrido. Cubre qué protege la aprobación de varios administradores (MAA) a octubre de 2026, cómo diseñar directivas de acceso y grupos de aprobadores sin quedarse fuera, los clics exactos que hace un aprobador humano en el centro de administración y, después, la parte por la que la mayoría vino: cómo un script que crea un objeto protegido recibe una solicitud de aprobación, cómo espera, cómo un aprobador puede aprobar desde Graph y cómo el script termina el trabajo. Cada punto de conexión, encabezado, permiso y límite está comprobado contra Microsoft Learn. Donde añado mi propia opinión, lo digo.
Qué es la aprobación de varios administradores y por qué ahora cubre la automatización de Graph
Según la información general de Microsoft Learn, las directivas de acceso de MAA “requieren que una segunda cuenta administrativa apruebe un cambio antes de que se aplique”. Una directiva de acceso nombra un tipo de perfil protegido y el grupo de cuentas autorizadas a aprobar cambios en él. Cuando cualquier cuenta cambia un recurso protegido, Intune retiene el cambio hasta que otra cuenta lo aprueba explícitamente; los aprobadores también pueden rechazar. La justificación empresarial, las notas del aprobador y la decisión acaban en el registro de auditoría de Intune.
Hasta junio de 2026, solo se interceptaban las acciones interactivas (delegadas) de administrador. Si una entidad de servicio ejecutaba el mismo borrado o despliegue de script con un token de solo aplicación, pasaba sin más. La entrada de What’s new de Microsoft para la semana del 22 de junio de 2026 cerró esa brecha: “La aprobación de varios administradores (MAA) ahora se aplica a las llamadas API realizadas por automatización a través de Microsoft Graph API, no solo a las acciones interactivas de administrador”. Vienen dos salvaguardas con ello. La aplicación a llamadas API solo afecta a inquilinos que ya tienen directivas de acceso de MAA configuradas; no habilita MAA en ningún sitio. Y según el procedimiento de Graph API, “MAA solo se aplica a operaciones que modifican recursos protegidos (POST, PATCH, PUT, DELETE). Las operaciones de solo lectura (GET) no se ven afectadas”.
Por qué lo hizo Microsoft es evidente en cuanto se piensa como un atacante. Un secreto de cliente filtrado de una aplicación con DeviceManagementManagedDevices.ReadWrite.All era antes un botón de borrado para todo el inquilino. Ahora la misma llamada produce una solicitud de aprobación que un humano tiene que leer antes de que ocurra nada.
Recursos protegidos
La información general enumera siete tipos de recurso. La enumeración operationApprovalPolicyType de Graph contiene muchos más valores (autopilot, windows365, endpointPrivilegeManagement, filter, appProtectionPolicy y otros), pero la enumeración es un superconjunto de lo que el servicio aplica hoy. Solo los siete documentados están protegidos, las directivas de protección de aplicaciones quedan excluidas explícitamente y las correcciones (remediations) no están en la lista.
| Recurso (tipo de perfil) | Qué desencadena la aprobación | Desde cuándo, según What’s new |
|---|---|---|
| Aplicaciones | Despliegues de aplicaciones: crear, editar, eliminar, asignar. No se aplica a las directivas de protección de aplicaciones. | GA la semana del 28 de agosto de 2023; alcance Windows frente a no Windows añadido en agosto de 2024 (2408) |
| Scripts | Despliegue de scripts de PowerShell en dispositivos Windows | Uno de los dos tipos de directiva originales (app, script) del esquema de Graph |
| Acciones de dispositivo | Borrar, retirar y eliminar | Borrar añadido la semana del 18 de agosto de 2025 (2508); retirar y eliminar figuran en la información general |
| Control de acceso basado en roles | Cualquier cambio en roles: permisos, grupos de administradores, asignaciones de grupos de miembros | Semana del 18 de agosto de 2025 (2508) |
| Configuración del inquilino | Categorías de dispositivo: crear, editar, eliminar | Semana del 15 de septiembre de 2025 (2509) |
| Directivas de cumplimiento | Crear y gestionar directivas de cumplimiento | Semana del 2 de marzo de 2026 (2602) |
| Directivas de configuración | Directivas creadas a través del catálogo de configuración | Semana del 2 de marzo de 2026 (2602) |
| Directivas de acceso (la propia MAA) | Cualquier cambio en una directiva de acceso, incluidas sus exclusiones | Protegidas automáticamente; no seleccionables como tipo de perfil |
Dos notas sobre la tabla. “Todas las acciones de un recurso protegido están protegidas, incluidas, entre otras: Editar, Crear, Modificar, Eliminar, Asignar” es la redacción de Microsoft, así que un cambio de asignación en una aplicación existente cuenta. Y la aplicación de junio de 2026 a las llamadas Graph de solo aplicación afecta a todas las filas a la vez; no hay una suscripción por tipo para la automatización.
Requisitos previos, roles y licencias
Microsoft describe tres roles en el flujo de trabajo de MAA, y la distinción importa para la automatización porque una entidad de servicio solo puede ser el tercero.
Administrador de directivas de acceso. Crea y gestiona las directivas de acceso. Microsoft recomienda un rol personalizado de Intune con los cuatro permisos del grupo Multi Admin Approval de la referencia de roles personalizados (Create access policy, Read access policy, Update access policy, Delete access policy) en lugar del rol privilegiado Intune Administrator de Entra. El quinto permiso de ese grupo, Approval for Multi Admin Approval, es el que necesita el segundo administrador para aprobar una directiva de acceso nueva o modificada.
Aprobador. Debe cumplir las tres condiciones: pertenecer al grupo de aprobadores asignado a la directiva de acceso; tener el permiso Read específico del recurso para el tipo que aprueba (por ejemplo ManagedDevices/Read para aprobar la eliminación de un dispositivo); y el propio grupo de aprobadores debe estar añadido como grupo de miembros a al menos una asignación de rol de Intune. Si el grupo no está asignado a un rol, Microsoft dice que “los miembros del grupo de aprobadores se quitan del grupo periódicamente”, lo que en mi experiencia es la causa más común de que las aprobaciones dejen de funcionar misteriosamente. El grupo debe ser un grupo de seguridad (las listas de distribución, los grupos de Microsoft 365 y los grupos de seguridad habilitados para correo “fallan silenciosamente al resolver la pertenencia de aprobadores”), y los miembros deben ser directos porque la pertenencia anidada “puede dar lugar a un comportamiento poco fiable”.
Solicitante del cambio. Necesita el permiso RBAC ordinario de Intune para la acción (MobileApps/Create, RemoteTasks/Wipe). La misma cuenta envía la solicitud y después selecciona Complete. Para la automatización, esta es su entidad de servicio, y Microsoft es explícito: “Las aplicaciones no pueden aprobar ni rechazar solicitudes de MAA; solo las cuentas de administrador interactivas pueden aprobar solicitudes”.
Nadie puede aprobar su propia solicitud, incluidos los administradores globales y los administradores de Intune. De forma predeterminada, cada administrador participante necesita una licencia de Intune; la configuración Allow access to unlicensed admins elimina ese requisito, y Microsoft advierte de que es irreversible.
Permisos de Graph
Estos son los permisos documentados en las páginas de referencia beta. Todo lo específico de MAA vive en beta; la referencia v1.0 no tiene recurso operationApprovalPolicy ni operationApprovalRequest, y se aplica la nota estándar de Microsoft: las API beta de Intune están admitidas pero cambian con más frecuencia que v1.0.
| Llamada | Permisos documentados (delegados y de aplicación) |
|---|---|
Listar, obtener, crear, actualizar, eliminar operationApprovalPolicies | DeviceManagementRBAC.Read.All, DeviceManagementRBAC.ReadWrite.All |
Listar u obtener operationApprovalRequests | DeviceManagementConfiguration.Read.All, DeviceManagementConfiguration.ReadWrite.All, DeviceManagementRBAC.Read.All, DeviceManagementRBAC.ReadWrite.All |
approve, reject, cancelMyRequest, retrieveMyRequests, retrieveRequestStatus | DeviceManagementConfiguration.Read.All, DeviceManagementRBAC.Read.All |
Crear un deviceManagementScript (el ejemplo práctico) | DeviceManagementScripts.ReadWrite.All o DeviceManagementConfiguration.ReadWrite.All |
Listar auditEvents (v1.0) | DeviceManagementApps.Read.All, DeviceManagementApps.ReadWrite.All |
El permiso de Graph es necesario pero no suficiente. La comprobación RBAC de Intune sigue ejecutándose encima, así que una aplicación con DeviceManagementConfiguration.ReadWrite.All y sin asignación de rol de Intune se comporta de forma distinta a un administrador delegado con el mismo ámbito.
Diseño de las directivas de acceso
Cuántas directivas
Cada directiva de acceso admite un único tipo de perfil, así que un inquilino que quiera proteger aplicaciones, scripts, acciones de dispositivo, RBAC, directivas de cumplimiento y de configuración necesita al menos seis directivas. Mi patrón es una directiva por tipo que comparte un grupo de aprobadores de punto de conexión, más una directiva separada para el tipo Role que creo al final. Solo divido las directivas de aplicaciones por plataforma (la versión de agosto de 2024 permite limitar una directiva de aplicaciones a aplicaciones Windows, no Windows o ambas) cuando dos equipos distintos se aprueban mutuamente.
Grupos de aprobadores
Cree un grupo de seguridad dedicado por nivel de aprobación, asígnelo directamente a un rol de Intune (basta con un rol personalizado que lleve los permisos Read del recurso) y mantenga a los miembros directos. Póngales nombres que se lean bien en el registro de auditoría: SG-Intune-MAA-Approvers-Endpoint, SG-Intune-MAA-Approvers-RBAC. Incluya al menos dos aprobadores en cada uno, en zonas horarias distintas si trabaja en modo follow-the-sun, porque las solicitudes expiran.
Consideraciones de emergencia (break-glass)
MAA no tiene interruptor de omisión de emergencia e Intune no envía notificaciones, así que planifique tres modos de fallo.
- Todos los aprobadores no disponibles. La solicitud expira a los 3 días. La mitigación es el tamaño del grupo y una rotación de guardia, no una omisión.
- El interbloqueo de Role. Una directiva de acceso Role protege todos los cambios de RBAC, incluida la asignación de rol que necesita su grupo de aprobadores. La recuperación documentada por Microsoft es eliminar la directiva Role en Tenant administration > Multi Admin Approval > Access policies, esperar de 3 a 5 minutos, corregir las asignaciones en Tenant administration > Roles y volver a crear la directiva. Evítelo configurando todas las demás directivas y verificando RBAC antes de habilitar el tipo Role.
- Automatización que no puede esperar. Use la pestaña Exclusions para eximir a una aplicación empresarial concreta de una directiva. Las exclusiones se aplican solo a tokens de solo aplicación (las llamadas delegadas de la misma aplicación siguen interceptándose), tienen un máximo de 50 aplicaciones por directiva de acceso, necesitan la aprobación de un segundo administrador, y cada adición, eliminación o modificación se registra en el registro de auditoría. La advertencia de Microsoft es directa: cada exclusión “crea una brecha en su flujo de trabajo de aprobación que podría explotarse si la aplicación excluida se ve comprometida”.
Mi regla para las exclusiones: solo para herramientas de proveedores que no puedo cambiar, limitadas a la única directiva que necesitan, credenciales de certificado en lugar de secretos de cliente, y una directiva de acceso condicional para identidades de carga de trabajo que bloquee la entidad de servicio desde fuera de los intervalos IP conocidos. Esa directiva requiere licencias Workload Identities Premium y solo cubre entidades de servicio de un único inquilino registradas en el suyo, pero para una aplicación que puede borrar dispositivos sin aprobación, vale la licencia.
Crear una directiva
En el centro de administración: Tenant administration > Multi Admin Approval > Access policies > Create. En Basics defina un nombre y el único Profile type; en Approvers seleccione Add groups; en Exclusions opcionalmente Add enterprise applications; en Review + submit for approval escriba una Business justification y seleccione Submit for approval. Un segundo administrador con Approval for Multi Admin Approval aprueba; el primer administrador vuelve a la directiva y selecciona Complete.
A través de Graph es un único POST. Como las propias directivas de acceso están protegidas, espere también en esta llamada el flujo de aprobación que se describe más abajo.
POST https://graph.microsoft.com/beta/deviceManagement/operationApprovalPolicies
Content-Type: application/json
{
"@odata.type": "#microsoft.graph.operationApprovalPolicy",
"displayName": "MAA - Windows scripts",
"description": "Second-admin approval for PowerShell script deployments",
"policyType": "script",
"policyPlatform": "notApplicable",
"policySet": {
"@odata.type": "microsoft.graph.operationApprovalPolicySet",
"policyType": "script",
"policyPlatform": "notApplicable"
},
"approverGroupIds": [ "<approver security group object ID>" ]
}GET https://graph.microsoft.com/beta/deviceManagement/operationApprovalPolicies lista lo que tiene. displayName tiene un límite de 128 caracteres y description de 1024.
El flujo de aprobación para un administrador humano
Enviar
El solicitante usa el flujo normal de creación o edición. En la última página antes de guardar aparece un campo Business justification; rellénelo, porque es lo que lee el aprobador, y envíe. Si ya hay una solicitud pendiente para el mismo objeto, Intune bloquea la nueva con un mensaje. El estado se ve en Tenant administration > Multi Admin Approval > My requests, y una solicitud pendiente puede retirarse allí con Cancel request.
Aprobar o rechazar
El aprobador va a Tenant administration > Multi Admin Approval > Received requests (la información general también llama a esta lista All requests), o al panel consolidado Tenant administration > Admin tasks, que muestra las solicitudes de MAA junto a las tareas de seguridad de Defender y las solicitudes de elevación de Endpoint Privilege Management y requiere Organization > Read para abrirse. Seleccione el vínculo Business justification, lea el cambio, escriba Approver notes y elija Approve request o Reject request. Las notas vuelven a la vista My requests del solicitante, que es como se comunica un motivo de rechazo. Desde la semana del 27 de abril de 2026 (versión de servicio 2604), las pestañas My requests y All requests también muestran una columna Agent Response para las solicitudes de scripts de Windows PowerShell cuando el Change Review Agent tiene una sugerencia; esa integración está en versión preliminar.
Completar
La aprobación no aplica el cambio. El solicitante original abre la solicitud y selecciona Complete; Intune la procesa, el estado pasa a Completed y una notificación de consola confirma el éxito o el fallo. La automatización reproduce este paso como el reenvío con el código de aprobación.
Ciclo de vida y expiración
| Estado en el centro de administración | Valor status de Graph | Significado |
|---|---|---|
| Needs approval | needsApproval | A la espera de un aprobador |
| Approved | approved | Aprobada; a la espera de que el solicitante haga Complete |
| Completed | completed | Cambio aplicado |
| Rejected | rejected | Rechazada por un aprobador; envíe una nueva solicitud si sigue siendo necesaria |
| Canceled | cancelled | Retirada por el solicitante |
| Expired | expired | No procesada en 3 días; debe volver a enviarse |
Palabras exactas de Microsoft: “Si una solicitud no se procesa más en 3 días, pasa a Expired y debe volver a enviarse. Cada cambio de estado permanece visible hasta 30 días después del cambio”. Cada solicitud también lleva un expirationDateTime, que es el valor que su automatización debería vigilar en lugar de codificar 72 horas.
Automatización: el flujo de trabajo de Graph API
Puntos de conexión y versión de la API
Todo lo que sigue está en el punto de conexión beta. Hoy no hay equivalente v1.0, así que fije su código a estas URL y siga la serie Intune What’s New para el día en que se muevan.
| Propósito | Solicitud |
|---|---|
| Listar directivas de acceso | GET /beta/deviceManagement/operationApprovalPolicies |
| Crear una directiva de acceso | POST /beta/deviceManagement/operationApprovalPolicies |
| Listar solicitudes de aprobación | GET /beta/deviceManagement/operationApprovalRequests |
| Obtener una solicitud | GET /beta/deviceManagement/operationApprovalRequests/{id} |
| Mis propias solicitudes | GET /beta/deviceManagement/operationApprovalRequests/retrieveMyRequests |
| Si un objeto está bloqueado por una solicitud pendiente | POST /beta/deviceManagement/operationApprovalRequests/retrieveRequestStatus con entityId y entityType |
| Aprobar | POST /beta/deviceManagement/operationApprovalRequests/{id}/approve |
| Rechazar | POST /beta/deviceManagement/operationApprovalRequests/{id}/reject |
| Cancelar mi solicitud | POST /beta/deviceManagement/operationApprovalRequests/cancelMyRequest con { "id": "..." } |
| Pista de auditoría | GET /v1.0/deviceManagement/auditEvents |
Solo aplicación frente a delegado
El protocolo de aprobación es idéntico para ambos tipos de token; los encabezados y los códigos de estado no cambian. Lo que cambia es quién puede hacer qué.
- Una entidad de solo aplicación (credenciales de cliente) puede enviar cambios protegidos, leer el estado de la solicitud, reenviar con el código de aprobación y ser excluida de una directiva. No puede aprobar ni rechazar, y la solicitud que crea registra la aplicación en
requestor.application. - Un token delegado actúa como el administrador que inició sesión. Puede enviar, leer y, si ese administrador está en el grupo de aprobadores y tiene el permiso Read del recurso, aprobar o rechazar la solicitud de otra persona. Nunca puede aprobar la suya, y las exclusiones no se aplican a las llamadas delegadas aunque la aplicación esté excluida.
La consecuencia de diseño: la identidad de su canalización envía, un humano aprueba (en el portal o con una llamada delegada de Graph desde una sesión en la que inició sesión) y la identidad de su canalización completa. No construya una segunda entidad de servicio como “aprobador”; Microsoft dice que no funcionará, y desvirtuaría el propósito.
Paso 1: enviar con un encabezado de justificación
Añada x-msft-approval-justification a la solicitud de modificación. El valor debe estar codificado en Base64; el valor de ejemplo de Microsoft YXBwIG9ubHkgdGVzdA== se decodifica como app only test. El ejemplo siguiente crea un script de Windows PowerShell; su encabezado se decodifica como CHG0012345: deploy pilot script to Ring 0.
POST https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts
Content-Type: application/json
x-msft-approval-justification: Q0hHMDAxMjM0NTogZGVwbG95IHBpbG90IHNjcmlwdCB0byBSaW5nIDA=
{
"@odata.type": "#microsoft.graph.deviceManagementScript",
"displayName": "BHG - Pilot script",
"description": "Created by automation under Multi Admin Approval",
"scriptContent": "V3JpdGUtT3V0cHV0ICJIZWxsbyBXb3JsZCI=",
"runAsAccount": "system",
"enforceSignatureCheck": false,
"fileName": "Pilot.ps1",
"runAs32Bit": false,
"roleScopeTagIds": ["0"]
}Sin el encabezado, la llamada falla con un error que indica que el encabezado x-msft-approval-justification es obligatorio; el procedimiento lo describe como un HTTP 400.
Paso 2: leer el 412 y conservar el código de aprobación
Aquí es donde se rompen la mayoría de los scripts. Un envío correcto no devuelve 201 Created. Devuelve HTTP 412 Precondition Failed con un código de error externo de Graph BadRequest, y la respuesta lleva un encabezado x-msft-approval-code. La guía de Microsoft: “Use la presencia de este encabezado junto con HTTP 412 como la señal de que MAA aceptó la solicitud y creó una solicitud de aprobación”. Guarde el método, la URL, el cuerpo y el código; necesitará los cuatro más adelante.
HTTP/1.1 412 Precondition Failed
x-msft-approval-code: aabb1234-5678-9012-abcd-ef0123456789
Content-Type: application/json
{
"error": {
"code": "BadRequest",
"message": "{ \"Message\": \"Approval Required. Request Approval using the request ID returned as part of the x-msft-approval-code response header. x-msft-approval-code: aabb1234-5678-9012-abcd-ef0123456789 ...\" }"
}
}Paso 3: esperar, sondear, notificar
Intune no notifica a nadie, así que su script tiene que hacerlo. El código de aprobación es el identificador de la solicitud, así que puede leer la solicitud directamente o usar la forma con filtro que Microsoft muestra en el procedimiento. Publique la justificación y un puntero a Tenant administration > Multi Admin Approval en lo que sus aprobadores lean de verdad, y use expirationDateTime para decidir cuándo escalar.
GET https://graph.microsoft.com/beta/deviceManagement/operationApprovalRequests/aabb1234-5678-9012-abcd-ef0123456789GET https://graph.microsoft.com/beta/deviceManagement/operationApprovalRequests?$filter=requestId eq 'aabb1234-5678-9012-abcd-ef0123456789'Antes de enviar nada, retrieveRequestStatus le dice si el objeto de destino ya está bloqueado por la solicitud pendiente de otra persona (entityLocked: true), lo que le permite fallar pronto en lugar de toparse con el error de “ya pendiente”.
Paso 4: aprobar a través de Graph
Un aprobador humano puede actuar desde Graph con un token delegado en lugar del portal. justification tiene un límite de 1024 caracteres; approvalSource es opcional y su valor predeterminado es unknown.
POST https://graph.microsoft.com/beta/deviceManagement/operationApprovalRequests/aabb1234-5678-9012-abcd-ef0123456789/approve
Content-Type: application/json
{
"justification": "Approved per CHG0012345 after reviewing the script content in the request pane",
"approvalSource": "adminConsole"
}Rechazar tiene la misma forma contra /reject. Ambos devuelven 200 OK con un cuerpo de cadena. Las tablas de permisos de estas acciones enumeran permisos de aplicación, pero el procedimiento es categórico en que las aplicaciones no pueden aprobar ni rechazar, así que trate la ruta delegada como la única que funciona.
Paso 5: reenviar con el código de aprobación
Cuando status sea approved, repita la solicitud idéntica sustituyendo el encabezado de justificación por x-msft-approval-code. Es el equivalente en la API a que el solicitante seleccione Complete, y devuelve el 201 Created normal con el nuevo objeto.
POST https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts
Content-Type: application/json
x-msft-approval-code: aabb1234-5678-9012-abcd-ef0123456789
{ ...the same body as Step 1... }Ejemplo práctico completo en PowerShell
Esto usa Connect-MgGraph e Invoke-MgGraphRequest del SDK de PowerShell de Microsoft Graph. No encontré cmdlets dedicados para los puntos de conexión de aprobación de operaciones en la referencia de Microsoft.Graph.Beta.DeviceManagement.Administration, e Invoke-MgGraphRequest es la vía documentada por Microsoft para “API para las que aún no existe un cmdlet equivalente”. -SkipHttpErrorCheck evita que el 412 lance una excepción, mientras que -ResponseHeadersVariable y -StatusCodeVariable capturan el encabezado y el código de estado.
El primer script se conecta como solo aplicación con un certificado, envía un script de Windows PowerShell, espera la aprobación y completa.
#Requires -Modules Microsoft.Graph.Authentication
<#
Submit-IntuneScriptWithMaa.ps1
App-only automation that creates a Windows PowerShell script in Intune under Multi Admin Approval.
The app registration needs DeviceManagementScripts.ReadWrite.All (create the script) and
DeviceManagementConfiguration.Read.All or DeviceManagementRBAC.Read.All (read approval requests).
#>
param(
[Parameter(Mandatory)] [string] $TenantId,
[Parameter(Mandatory)] [string] $ClientId,
[Parameter(Mandatory)] [string] $CertificateThumbprint,
[string] $Justification = "CHG0012345: deploy pilot script to Ring 0",
[int] $PollIntervalSeconds = 300
)
Connect-MgGraph -ClientId $ClientId -TenantId $TenantId -CertificateThumbprint $CertificateThumbprint -NoWelcome
$uri = "https://graph.microsoft.com/beta/deviceManagement/deviceManagementScripts"
$scriptText = 'Write-Output "Hello from Intune"'
$body = @{
"@odata.type" = "#microsoft.graph.deviceManagementScript"
displayName = "BHG - Pilot script"
description = "Created by automation under Multi Admin Approval"
scriptContent = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($scriptText))
runAsAccount = "system"
enforceSignatureCheck = $false
fileName = "Pilot.ps1"
runAs32Bit = $false
roleScopeTagIds = @("0")
} | ConvertTo-Json -Depth 5
# Step 1: submit with the Base64 justification header. Expect HTTP 412 plus x-msft-approval-code.
$encodedJustification = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($Justification))
$null = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $body -ContentType "application/json" `
-Headers @{ "x-msft-approval-justification" = $encodedJustification } `
-SkipHttpErrorCheck -ResponseHeadersVariable responseHeaders -StatusCodeVariable statusCode
if ($statusCode -eq 201) {
Write-Output "Created immediately: scripts are not MAA-protected in this tenant, or this app is excluded."
return
}
# Step 2: the 412 is the success signal. Pull the approval code out of the response headers.
$codeKey = $responseHeaders.Keys | Where-Object { $_ -ieq "x-msft-approval-code" } | Select-Object -First 1
if ($statusCode -ne 412 -or -not $codeKey) {
throw "Unexpected HTTP $statusCode without an approval code. Check Graph permissions and Intune RBAC."
}
$approvalCode = @($responseHeaders[$codeKey])[0]
Write-Output "Approval request $approvalCode created. Waiting for a second administrator."
# Step 3: notify your approvers here (ticket, chat, email). Intune sends nothing on its own.
# Then poll the request by ID until it leaves needsApproval. The service expires it after 3 days.
$requestUri = "https://graph.microsoft.com/beta/deviceManagement/operationApprovalRequests/$approvalCode"
do {
Start-Sleep -Seconds $PollIntervalSeconds
$request = Invoke-MgGraphRequest -Method GET -Uri $requestUri
Write-Output ("{0:u} status={1} expires={2}" -f (Get-Date), $request.status, $request.expirationDateTime)
} while ($request.status -eq "needsApproval")
if ($request.status -ne "approved") {
throw "Request $approvalCode ended as '$($request.status)'. Approver notes: $($request.approvalJustification)"
}
# Step 5: replay the identical request with the approval code. This is the API form of 'Complete'.
$created = Invoke-MgGraphRequest -Method POST -Uri $uri -Body $body -ContentType "application/json" `
-Headers @{ "x-msft-approval-code" = $approvalCode }
Write-Output "Script created with id $($created.id). Approved by $($request.approver.user.displayName)."La mitad del aprobador se ejecuta de forma interactiva, con la sesión iniciada como miembro del grupo de aprobadores. Lista lo que está esperando, muestra quién lo pidió y por qué, y aprueba una solicitud después de que el aprobador haya leído el cambio en el centro de administración.
# Approve-IntuneMaaRequests.ps1 - delegated session for a human approver
Connect-MgGraph -Scopes "DeviceManagementRBAC.Read.All" -NoWelcome
$all = Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/deviceManagement/operationApprovalRequests"
$pending = @($all.value | Where-Object { $_.status -eq "needsApproval" })
foreach ($r in $pending) {
$who = if ($r.requestor.application.displayName) { $r.requestor.application.displayName } else { $r.requestor.user.displayName }
Write-Output "$($r.id) from $who types=$($r.requiredOperationApprovalPolicyTypes -join ',') expires $($r.expirationDateTime)"
Write-Output " justification: $($r.requestJustification)"
}
$id = Read-Host "Request ID to approve"
$decision = @{
justification = "Approved per CHG0012345 after reviewing the script content in the admin center"
approvalSource = "adminConsole"
} | ConvertTo-Json
Invoke-MgGraphRequest -Method POST -Body $decision -ContentType "application/json" `
-Uri "https://graph.microsoft.com/beta/deviceManagement/operationApprovalRequests/$id/approve"Una vez que existe el objeto de script, asígnelo y fuerce una sincronización de directivas de Intune en un dispositivo de prueba para ver cómo aterriza. La asignación también es una modificación de un recurso protegido, así que espere otro ciclo de 412 cuando añada el grupo.
Si traslada a este patrón un runbook nocturno de Azure Automation que publica actualizaciones de aplicaciones Win32, espere dos lecciones en la primera semana. El runbook necesita un trabajo de reanudación separado, indexado por el código de aprobación, para no mantener un sandbox abierto durante horas, y los aprobadores querrán que la justificación empiece por el número de ticket de cambio en lugar de describir el cambio, porque el ticket es lo que de verdad abren.
Orientación operativa
SLA, expiración y notificaciones
Fije un SLA interno de aprobación bien dentro de la expiración de 3 días. El mío es de cuatro horas laborables para aplicaciones y scripts y de una hora para acciones de dispositivo y cambios de RBAC, con un aprobador de guardia designado en el sistema de tickets. Como Intune no envía notificaciones, el notificador vive en el script que envía, respaldado por un trabajo programado que llama a retrieveMyRequests o al punto de conexión de lista y escala todo lo que siga en needsApproval con menos de 24 horas hasta expirationDateTime. Recuerde también la ventana de visibilidad de 30 días: después, la solicitud desaparece de la consola, así que exporte todo lo que vaya a necesitar como evidencia.
Auditoría e informes
El procedimiento de Graph confirma que los eventos de MAA, “incluidos aprobar, bloquear, pasar, añadir exclusión y quitar exclusión”, se registran en el registro de auditoría existente de Intune. En el centro de administración está en Tenant administration > Audit logs, filtrado con Add filters > Category y Activity; Export escribe un CSV, y el mismo panel enruta los registros a Azure Monitor para una retención mayor que la que muestra la consola. Verlos requiere el rol Intune Administrator o un rol de Intune con Audit data > Read, según la documentación del registro de auditoría. De forma programática, GET https://graph.microsoft.com/v1.0/deviceManagement/auditEvents devuelve dos años de eventos; el bloque actor de cada evento lleva applicationId, servicePrincipalName y userPrincipalName, que es como se separan en un informe las aprobaciones impulsadas por automatización de las humanas.
Errores comunes
| Síntoma | Causa probable | Solución |
|---|---|---|
HTTP 400 con un mensaje de que x-msft-approval-justification es obligatorio | Recurso protegido, falta el encabezado | Añada el encabezado Base64 y reenvíe |
HTTP 412 Precondition Failed, código BadRequest, encabezado x-msft-approval-code presente | Esperado: se creó la solicitud de aprobación | Guarde el código, sondee, notifique, reenvíe |
| HTTP 403 Forbidden | Falta permiso de Graph o RBAC de Intune para el solicitante; el anuncio de Microsoft de junio de 2026 también describió los bloqueos de MAA como 403 | Compruebe los permisos de la aplicación y la asignación de rol, después las exclusiones |
“Ya hay una solicitud pendiente para este objeto” o entityLocked: true | Otra solicitud para el mismo objeto está abierta | Espere, o pida a su solicitante que la cancele |
Estado expired | Nadie actuó en 3 días | Reenvíe con el encabezado de justificación; obtendrá un código nuevo |
| El aprobador no ve o no puede aprobar solicitudes | Grupo no asignado a un rol de Intune, no es grupo de seguridad, pertenencia anidada o falta el permiso Read del recurso | Corrija el grupo según la lista de requisitos previos |
| Aprobar la propia solicitud falla | No permitido por diseño | Aprueba otro administrador |
| Cambios de RBAC bloqueados tras habilitar una directiva Role | El interbloqueo de Role | Elimine la directiva Role, espere de 3 a 5 minutos, corrija RBAC, vuelva a crearla |
| El reenvío con el código de aprobación falla | La solicitud difiere de la original o pasó la ventana | Microsoft dice que se reenvíe la misma solicitud; repítala sin cambios y con prontitud |
Qué hacer al respecto
- Abra Tenant administration > Multi Admin Approval > Access policies y enumere las directivas activas. Si no hay ninguna, la aplicación a la API todavía no le afecta, y este es el momento de diseñarla deliberadamente en lugar de heredarla.
- Inventaríe cada entidad de servicio con permisos de escritura en Intune en Entra ID > Enterprise apps, y asigne cada una a los tipos protegidos que toca (aplicaciones, scripts, acciones de dispositivo, RBAC, cumplimiento, configuración, categorías de dispositivo).
- Arregle primero los grupos de aprobadores: solo grupos de seguridad, miembros directos, al menos dos por grupo, cada grupo asignado directamente a un rol de Intune que lleve los permisos Read del recurso.
- Cree una directiva de acceso por tipo de perfil. Deje el tipo Role para cuando los demás estén verificados, para evitar el interbloqueo.
- Actualice cada script y runbook que modifique un tipo protegido: envíe
x-msft-approval-justification(Base64), trate el HTTP 412 conx-msft-approval-codecomo éxito, persista el método, la URL, el cuerpo y el código, sondeeoperationApprovalRequests/{id}, notifique a los aprobadores y repita conx-msft-approval-code. - Decida las exclusiones deliberadamente: solo para herramientas de proveedores que no puede cambiar, una directiva cada una, credenciales de certificado, una directiva de acceso condicional para identidades de carga de trabajo y una revisión trimestral de la lista.
- Ponga por escrito el SLA de aprobación, deje a un aprobador de guardia y entregue a los aprobadores el PowerShell delegado anterior o el panel Admin tasks.
- Enrute el registro de auditoría de Intune a Azure Monitor y construya un informe que separe los eventos de aprobar, bloquear y pasar de MAA por
actor.applicationIdfrente aactor.userPrincipalName. - Pruebe el flujo completo una vez: cree un script a través del ciclo de 412, asígnelo, fuerce una sincronización en un dispositivo de prueba y confirme que las entradas de auditoría se leen como esperan sus auditores.
- Fije su código a las URL beta y siga la serie Intune What’s New para el paso a v1.0 y para nuevos tipos protegidos; la enumeración ya insinúa hacia dónde va Microsoft.
¿Necesita otro par de manos? Big Hat Group ofrece consultoría de Microsoft Intune a organizaciones de Estados Unidos y Canadá, desde una revisión de estado de dos semanas hasta una migración completa. Reserve una llamada de descubrimiento para hablar de su entorno.
Fuentes
- Use Multi Admin Approval in Intune - Microsoft Intune
- Use Multi Admin Approval with the Microsoft Graph API - Microsoft Intune
- What’s new in Microsoft Intune (semanas del 27 de abril y del 22 de junio de 2026)
- What’s new in Microsoft Intune archive (entradas de agosto de 2023, agosto de 2024, agosto y septiembre de 2025, marzo de 2026)
- Create a custom role in Intune - Microsoft Intune
- Centrally manage Admin Tasks - Microsoft Intune
- Audit changes and events in Microsoft Intune - Microsoft Intune
- operationApprovalPolicy resource type - Microsoft Graph beta
- Create operationApprovalPolicy - Microsoft Graph beta
- List operationApprovalPolicies - Microsoft Graph beta
- operationApprovalRequest resource type - Microsoft Graph beta
- List operationApprovalRequests - Microsoft Graph beta
- Get operationApprovalRequest - Microsoft Graph beta
- approve action - Microsoft Graph beta
- reject action - Microsoft Graph beta
- cancelMyRequest action - Microsoft Graph beta
- retrieveMyRequests function - Microsoft Graph beta
- retrieveRequestStatus action - Microsoft Graph beta
- operationApprovalRequestEntityStatus resource type - Microsoft Graph beta
- Create deviceManagementScript - Microsoft Graph beta
- List auditEvents - Microsoft Graph v1.0
- Connect-MgGraph (Microsoft.Graph.Authentication)
- Invoke-MgGraphRequest (Microsoft.Graph.Authentication)
- Microsoft Entra Conditional Access for workload identities