# Interacción con runbooks

## Información general

RealmJoin le permite usar Azure Automation Runbooks para automatizar las operaciones diarias en su entorno. Consulte [Runbooks](https://docs.realmjoin.com/es/automatizacion/runbooks) para más información.

La API de RealmJoin le permite iniciar runbooks desde su aplicación para consultar la ejecución exitosa de ejecuciones activadas previamente. Consulte [la descripción Swagger de RealmJoin](https://customer-api.realmjoin.com/swagger/index.html) para ver qué operaciones son compatibles actualmente.

Las siguientes secciones explican cómo usar la API de RealmJoin para iniciar y seguir trabajos de runbook. Se asume que ya tiene [conectada una cuenta de Azure Automation](https://docs.realmjoin.com/es/automatizacion/connecting-azure-automation) a RealmJoin Portal. Además, asegúrese de [autenticar ](https://docs.realmjoin.com/es/dev-reference/realmjoin-api/authentication)cada solicitud contra la API de RealmJoin utilizando un encabezado HTTP Authorization adecuado.

## ¿Cómo maneja Azure Automation los runbooks?

Azure Automation tiene un enfoque de procesamiento por lotes con respecto a los runbooks. Cuando activa la ejecución de un runbook, se crea un trabajo para este runbook y se pone en cola para su ejecución.

Por lo general, un runbook no se iniciará de inmediato. Además, pueden existir varios trabajos para el mismo runbook al mismo tiempo en distintos estados de ejecución.

Cada trabajo tiene un conjunto de parámetros (entradas) que se pasan al script del runbook. Esto puede ser, por ejemplo, dos variables como `$username` y `$newEmailAddress` si se supone que el runbook debe agregar un alias de correo electrónico al buzón de un usuario.

Cada trabajo tiene un estado que representa su estado actual de ejecución; consulte [Microsoft Docs](https://docs.microsoft.com/en-us/azure/automation/automation-runbook-execution#job-statuses). Nos centraremos en `Queued`, `Running`, `Completed` y `Failed` en este documento. Tenga en cuenta que esto es una simplificación con el propósito de facilitar la comprensión.

## Iniciar un trabajo de Runbook

La API de RealmJoin ofrece dos endpoints para activar runbooks.

`run` ejecutará un runbook de forma sincrónica y solo devolverá/finalizará cuando el runbook realmente se haya completado o haya fallado. Este endpoint devuelve directamente el estado de éxito y la salida del trabajo de runbook asociado.

`start` tomará los mismos parámetros que `run` pero funciona de forma asincrónica. Devolverá tan pronto como un trabajo de runbook esté en cola. Devolverá el `jobID` para permitir un seguimiento fácil del nuevo trabajo.

### Nomenclatura de runbooks

Los runbooks se direccionan por su nombre en Azure Automation. En resumen:

* ¿Está sincronizado desde el repositorio GitHub de RealmJoin? Agregue `prefijo rjgit-`como prefijo
* Ya sea `org_`, `device_`, `group_`, `user_` como ámbito (exactamente uno de ellos)
* Una categoría, como `general_`o `security_`&#x20;
* El nombre del runbook, separado por `_` como `add-xyz-exception`

El resultado en este caso sería: `rjgit-org_security_add-xyz-exception`

&#x20;Consulta [Convenciones de nomenclatura](https://docs.realmjoin.com/es/automatizacion/runbooks/naming-conventions) para más detalles.

### Ejemplo

Supongamos la siguiente situación:

* Tiene sus credenciales de la API de RealmJoin y las ha codificado en `dC0xMjM0MTIzNDpteVMzY3JldCE=` (Base64)
* Desea iniciar el runbook `rjgit-user_security_revoke-or-restore-access` para bloquear el inicio de sesión de un usuario específico
* Los parámetros del runbook (PowerShell) son:
  * `$UserName = "someone@contoso.com"`
  * `$Revoke = $true`

Usaremos el `run` endpoint para saber inmediatamente si el trabajo se completó correctamente.

Construyamos los **solicitar**:

Encabezados:

```http
Authorization: Basic dC0xMjM0MTIzNDpteVMzY3JldCE=
Content-Type: application/json
```

Solicitud / URI:

```http
POST https://customer-api.realmjoin.com/runbook/rjgit-user_security_revoke-or-restore-access/run
```

Cuerpo (en notación JSON):

```json
{ 
   "UserName": "someone@contoso.com", 
   "Revoke": true 
}
```

La solicitud tardará un poco, ya que espera a que se ejecute el trabajo. Asegúrese de ajustar el tiempo de espera de sus clientes HTTP en consecuencia. De lo contrario, intente usar el `start` endpoint, que devolverá el resultado inmediatamente.

La respuesta contendrá el `jobID`, el `status` (`Failed` o `Completed`) y todos los flujos de salida del runbook.

**Respuesta**:

Estado HTTP: `200` (Correcto)

Cuerpo (en notación JSON):

```json
{
    "jobID": "1234545e-7a24-436a-90c9-6056b512345",
    "status": "Completed",
    "streams": [
        {
            "time": "2021-12-15T14:47:27.7756185+00:00",
            "summary": "RealmJoin.RunbookHelper: Ejecutándose en la cuenta de Azure Automation",
            "streamType": "Verbose",
            "streamText": null,
            "value": null
        },
        {
            "time": "2021-12-15T14:47:27.96063+00:00",
            "summary": "getAutomationConnectionOrFromLocalCertificate: Obteniendo la conexión de automatización 'AzureRunAsConnection'",
            "streamType": "Verbose",
            "streamText": null,
            "value": null
        },
        {
            "time": "2021-12-15T14:47:31.560861+00:00",
            "summary": "Connect-RjRbAzureAD: Conectando con el módulo AzureAD: ...",
            "streamType": "Verbose",
            "streamText": null,
            "value": null
        },
        {
            "time": "2021-12-15T14:47:33.8860333+00:00",
            "summary": "## El acceso de usuario para someone@contoso.com ha sido revocado.",
            "streamType": "Output",
            "streamText": null,
            "value": null
        }
    ]
}
```

Los flujos de salida se separan en distintos canales (`streamTypes`): `Salida`, `Verbose`, `Error`. Esto permite filtrar errores o reducir la salida solo a la información relevante mostrando únicamente `Salida`.

Puede obtener estos flujos después de que un runbook haya terminado usando el `/runbook/jobs/{jobID}/output/streams` endpoint. (ver abajo)

## Consulta del estado y la salida de un trabajo

Si ya se ha creado un trabajo, puede usar la API de RealmJoin para consultar su estado y salida.

### Consulta del estado del trabajo

Usa `/runbook/jobs/{jobID}/status` para consultar el estado actual.

Consulta [Autenticación ](https://docs.realmjoin.com/es/dev-reference/realmjoin-api/authentication)sobre cómo crear un encabezado de autorización; lo siguiente es solo un ejemplo.

Suponga que el `jobID` es `1234545e-7a24-436a-90c9-6056b512345`

**`Solicitud`**

Encabezados:

```http
Authorization: Basic dC0xMjM0MTIzNDpteVMzY3JldCE=
Content-Type: application/json
```

Solicitud / URI:

```html
GET https://customer-api.realmjoin.com/runbook/jobs/1234545e-7a24-436a-90c9-6056b512345/status
```

Esta solicitud no tiene cuerpo.

**Respuesta**

Estado HTTP 200 (OK)

Cuerpo (texto sin formato)

```
Completed
```

Otros estados posibles incluyen `New`, `Failed`, `Running`. Consulte [estados posibles del Runbook](https://docs.microsoft.com/en-us/azure/automation/automation-runbook-execution#job-statuses).

### Lectura de la salida del trabajo

Usa `/runbook/jobs/{jobID}/output/text` para obtener una representación simple en texto sin formato de la salida de un runbook. Esto no incluirá el `Verbose` y `Error` stream. Consulte [lectura de flujos](#reading-specific-streams) para leer otros flujos. [Excepciones](#reading-exceptions) se manejan por separado.

Consulta [Autenticación ](https://docs.realmjoin.com/es/dev-reference/realmjoin-api/authentication)sobre cómo crear un encabezado de autorización; lo siguiente es solo un ejemplo.

Suponga que el `jobID` es `1234545e-7a24-436a-90c9-6056b512345`

**Solicitud**

Encabezados:

```http
Authorization: Basic dC0xMjM0MTIzNDpteVMzY3JldCE=
Content-Type: application/json
```

Solicitud / URI:

```html
GET https://customer-api.realmjoin.com/runbook/jobs/1234545e-7a24-436a-90c9-6056b512345/output/text
```

Esta solicitud no tiene cuerpo.

**Respuesta**

Estado HTTP 200 (OK)

Cuerpo (texto sin formato)

```
## Se ha creado el grupo de distribución 'Sales Team'.
```

### Lectura de flujos específicos

Usa `/runbook/jobs/{jobID}/output/streams` para obtener una representación JSON completa de la salida de un runbook. De esta manera, puede acceder al `Salida`, `Verbose` y `Error` stream. [Excepciones](#reading-exceptions) se manejan por separado.

Consulta [Autenticación ](https://docs.realmjoin.com/es/dev-reference/realmjoin-api/authentication)sobre cómo crear un encabezado de autorización; lo siguiente es solo un ejemplo.

Suponga que el `jobID` es `1234545e-7a24-436a-90c9-6056b512345`

**Solicitud (todos los flujos)**

Encabezados:

```http
Authorization: Basic dC0xMjM0MTIzNDpteVMzY3JldCE=
Content-Type: application/json
```

Solicitud / URI:

```html
GET https://customer-api.realmjoin.com/runbook/jobs/1234545e-7a24-436a-90c9-6056b512345/output/streams
```

Esta solicitud no tiene cuerpo.

**Respuesta**

Estado HTTP 200 (OK)

Cuerpo (JSON, matriz de mensajes)

```json
[
    {
        "time": "2021-12-20T08:37:46.8572747+00:00",
        "summary": "Cargando módulo desde la ruta 'C:\\Modules\\User\\RealmJoin.RunbookHelper\\RealmJoin.RunbookHelper.psd1'.",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:46.9272241+00:00",
        "summary": "Cargando módulo desde la ruta 'C:\\Modules\\User\\RealmJoin.RunbookHelper\\RealmJoin.RunbookHelper.psm1'.",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:47.1522235+00:00",
        "summary": "RealmJoin.RunbookHelper: Ejecutándose en la cuenta de Azure Automation",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:47.3122219+00:00",
        "summary": "Salida normal",
        "streamType": "Output",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:47.8422225+00:00",
        "summary": "Mensaje Verbose o Debug",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:47.7672223+00:00",
        "summary": "Mensaje de error no interrumpible",
        "streamType": "Error",
        "streamText": null,
        "value": null
    }
]
```

Véase abajo para leer mensajes de error interrumpibles y [excepciones](#reading-exceptions)

Para recibir solo un único flujo, por ejemplo Verbose, puede añadir un filtro a la solicitud agregando `?streamTypes=Verbose`. También puede filtrar por `Salida` y `Error`.

**Solicitud (filtrar por un único flujo)**

Encabezados:

```http
Authorization: Basic dC0xMjM0MTIzNDpteVMzY3JldCE=
Content-Type: application/json
```

Solicitud / URI:

```html
GET https://customer-api.realmjoin.com/runbook/jobs/1234545e-7a24-436a-90c9-6056b512345/output/streams?streamTypes=Verbose
```

Esta solicitud no tiene cuerpo.

**Respuesta**

Estado HTTP 200 (OK)

Cuerpo (JSON, matriz de mensajes)

```json
[
    {
        "time": "2021-12-20T08:37:46.8572747+00:00",
        "summary": "Cargando módulo desde la ruta 'C:\\Modules\\User\\RealmJoin.RunbookHelper\\RealmJoin.RunbookHelper.psd1'.",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:46.9272241+00:00",
        "summary": "Cargando módulo desde la ruta 'C:\\Modules\\User\\RealmJoin.RunbookHelper\\RealmJoin.RunbookHelper.psm1'.",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:47.1522235+00:00",
        "summary": "RealmJoin.RunbookHelper: Ejecutándose en la cuenta de Azure Automation",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    },
    {
        "time": "2021-12-20T08:37:47.8422225+00:00",
        "summary": "Mensaje Verbose o Debug",
        "streamType": "Verbose",
        "streamText": null,
        "value": null
    }
]
```

### Lectura de excepciones

Usa `/runbook/jobs/{jobID}/exception/text` para obtener una representación simple en texto sin formato del mensaje de excepción de un runbook (si está presente). Esto no incluirá los `Salida`, `Verbose` y `Error` streams. Consulte [lectura de flujos](#reading-specific-streams) para leer otros flujos.

Las excepciones se escriben cuando ocurren errores interrumpibles en la ejecución del script de PowerShell asociado con el runbook. Este endpoint solo leerá el mensaje en texto sin formato y no incluye detalles técnicos, como en qué línea de código se detuvo el script.

En nuestro ejemplo, un error interrumpible fue causado por `throw "Exception"`.

Consulta [Autenticación ](https://docs.realmjoin.com/es/dev-reference/realmjoin-api/authentication)sobre cómo crear un encabezado de autorización; lo siguiente es solo un ejemplo.

Suponga que el `jobID` es `1234545e-7a24-436a-90c9-6056b512345`

**Solicitud**

Encabezados:

```http
Authorization: Basic dC0xMjM0MTIzNDpteVMzY3JldCE=
Content-Type: application/json
```

Solicitud / URI:

```html
GET https://customer-api.realmjoin.com/runbook/jobs/1234545e-7a24-436a-90c9-6056b512345/exception/text
```

Esta solicitud no tiene cuerpo.

**Respuesta**

Estado HTTP 200 (OK)

Cuerpo (texto sin formato)

```
Excepción (Exception)
```
