Azure Automation — Produccion

UserOffboarding
Runbook

Baja de usuario completamente automatizada desde una lista de SharePoint. Deshabilita la cuenta en Active Directory, revoca sesiones en Microsoft 365, elimina grupos y licencias, convierte el buzon en compartido, y da de baja la licencia de GitHub Copilot.

👤 Autor: JM Fernandez + Claude (Anthropic)
📅 Fecha: Marzo 2026
☁️ Plataforma: Azure Automation + Hybrid Worker
Azure Automation Hybrid Runbook Worker Active Directory Microsoft 365 GitHub Copilot Jira Integration
10
Acciones automatizadas
3
Sistemas integrados
4
Parametros de entrada
18
Campos en el JSON output
~80
Bajas al ano
~40h
Ahorro anual estimado

Flujo de ejecucion

El proceso arranca desde Power Automate (disparado por una lista de SharePoint) y delega en Azure Automation, que ejecuta los scripts en el servidor on-premises via Hybrid Worker.

📄
SharePoint
Trigger
Nueva entrada en la lista de SharePoint creada por RRHH
Power Automate
Orquestador
Lanza job + recoge output + Teams
☁️
Azure Automation
Runbook
UserOffboarding.ps1 (wrapper)
💻
Hybrid Worker
On-premises
Servidor con acceso a AD y M365
📄
Scripts
PowerShell 7.2
offboarding.ps1 + remove_license.ps1
📋
Jira Comment
Resultado
Tabla de acciones + log publicado en el ticket
Runbook wrapperoffboarding.ps1 + remove_license.ps1 JSON unificado
RetornoJSON compacto Power Automate Tarjeta adaptable Teams + Jira
Config centralizadaconfig.psd1 contiene credenciales AzureAD, Jira, GitHub
Non-destructivoGitHub: no falla si el usuario no tiene cuenta o no tiene licencia Copilot

Entradas del Runbook

Parametros que recibe UserOffboarding.ps1 desde Power Automate al crear el job de Azure Automation.

Parametro Tipo Requerido Descripcion
UPN String Si User Principal Name del usuario a dar de baja (p.ej. [email protected])
EnableAutoReply String Si Activar respuesta automatica en el buzon. Valores: True / False
MensajeAutoReply String No Cuerpo del mensaje de respuesta automatica. Solo se usa si EnableAutoReply es True
JiraTicket String No Clave del ticket de Jira (p.ej. SIS-1234). Si se proporciona, el runbook publica un comentario con el resumen de acciones
Nota sobre JiraTicket: Este parametro es gestionado por el wrapper UserOffboarding.ps1 y no se pasa al script interno offboarding.ps1. Permite desacoplar la logica de Jira del script de baja.

10 acciones en orden

El script offboarding.ps1 ejecuta estas acciones de forma secuencial. Cada resultado se refleja en el JSON de salida.

Baja de GitHub Copilot

El wrapper ejecuta adicionalmente remove_license.ps1 para dar de baja la licencia de GitHub Copilot del usuario. El resultado se incluye en el JSON de salida.

Busqueda por SAML/GraphQL

El script consulta la GitHub Enterprise API via GraphQL para obtener la lista de usuarios con SAML vinculado. Busca el UPN del usuario en el campo samlNameId de forma paginada hasta encontrar la coincidencia.

Equipo idealista_copilot

Si el usuario tiene cuenta de GitHub y pertenece al equipo idealista_copilot en la enterprise idgithub, se le elimina del equipo, revocando su acceso a la licencia de Copilot.

Non-destructivo por diseno

Si el usuario no tiene cuenta de GitHub vinculada, el script devuelve Found: false sin generar error. Si tiene cuenta pero no licencia Copilot, devuelve CopilotLicense.Found: false. Nunca afecta al campo success de la baja.

Token en config.psd1

El token de GitHub Enterprise se centraliza en config.psd1 bajo la clave GitHub.Token. El wrapper lo lee y lo pasa como parametro -GitHubToken al script.

Flujo tipico: SAML lookup encuentra usuario @jdoe → es miembro del equipo idealista_copilot → eliminado del equipo → copilotRemoved: true en el JSON de salida y comentario en Jira.

Comentario automatico en el ticket

Si se pasa el parametro JiraTicket, el wrapper publica un comentario formateado en Jira con el resumen de todas las acciones realizadas.

Baja de usuario — [email protected]

Estado: ✓ COMPLETADO  |  o bien: ✗ COMPLETADO CON AVISOS


AccionResultado
AD Deshabilitado(/)
Contrasena reseteada(/)
Grupos AD eliminados12
Movido a Prebajas(/)
M365 Sign-in bloqueado(/)
Sesiones revocadas(/)
Grupos M365 eliminados8
Buzon compartido(/)
Licencias eliminadas(/)
GitHub Copilot@jdoe — (/)
Log del proceso
[INFO] Iniciando baja para [email protected]
[INFO] Usuario hibrido (AD + cloud)
[OK] Cuenta AD deshabilitada
[OK] Contrasena reseteada
[OK] 12 grupos AD eliminados
[OK] Movido a OU Prebajas
[OK] Sign-in bloqueado en M365
[OK] Sesiones activas revocadas
[OK] 8 grupos M365 eliminados
[OK] Buzon convertido a compartido
[OK] Licencias eliminadas
[OK] GitHub: @jdoe - licencia Copilot eliminada
Logica de estado: El campo success se pone a false solo si el proceso principal de baja (AD + M365) ha tenido errores. Los campos de GitHub (githubFound, copilotRemoved) son informativos y nunca marcan la baja como fallida.

Schema de respuesta

JSON compacto que devuelve el runbook y que Power Automate parsea para construir la tarjeta adaptable en Teams y decidir si abrir un ticket de incidencia.

// Respuesta del runbook UserOffboarding { "success": true, // false si hubo errores en AD o M365 "upn": "[email protected]", "timestamp": "2026-03-26T10:30:00Z", "isCloudOnly": false, // true = sin cuenta AD local // Active Directory (null si isCloudOnly = true) "adDisabled": true, "adPasswordReset": true, "adGroupsRemoved": 12, // numero de grupos eliminados "movedToPrebajas": true, // Microsoft 365 / Entra ID "m365SignInBlocked": true, "m365SessionsRevoked": true, "m365GroupsRemoved": 8, // numero de grupos M365 eliminados "mailboxShared": true, "autoReplySet": true, "licensesRemoved": true, // GitHub Copilot "githubFound": true, // false = sin cuenta GitHub vinculada "githubUsername": "jdoe", "copilotFound": true, // false = no tenia licencia Copilot "copilotRemoved": true, // Jira "jiraCommentPosted": true, // false si no se paso JiraTicket // Log completo "log": ["[INFO] Iniciando baja...", "[OK] ..."] }

Uso en Power Automate

CampoUso en Power Automate
success Condicion para crear ticket de incidencia en Jira si es false
upn Titulo de la tarjeta adaptable en Teams
adGroupsRemoved, m365GroupsRemoved Mostrados como numeros en la tarjeta adaptable
githubFound, copilotRemoved Seccion GitHub en la tarjeta adaptable; iconos segun estado
jiraCommentPosted Confirmacion de que el ticket de Jira fue actualizado

Archivos involucrados

Todos los scripts estan en el repositorio jmfernandez (Bitbucket) y se sincronizan al servidor via git pull.

☁️

hybrid-worker/runbooks/UserOffboarding.ps1

Wrapper de Azure Automation. Declara parametros, llama a offboarding.ps1 y remove_license.ps1, ensambla el JSON de salida y publica el comentario en Jira si procede.

📄

hybrid-worker/OnOffBoarding/offboarding.ps1

Logica principal de baja: AD + M365. Recibe UPN y EnableAutoReply. Devuelve JSON con resultado detallado de las 10 acciones.

🌎

hybrid-worker/OnOffBoarding/remove_license.ps1

Script de baja de GitHub Copilot. Busca el usuario por SAML en la Enterprise de GitHub y lo elimina del equipo idealista_copilot.

🔒

hybrid-worker/OnOffBoarding/config.psd1

Credenciales centralizadas: AzureAD (cert), Exchange Online, Jira (API token), GitHub Enterprise (token). No incluido en el repositorio publico.

📦

hybrid-worker/modules/JiraComments.psm1

Modulo compartido con el runbook de altas. Publica comentarios en Jira via REST API con autenticacion por API token.