> For the complete documentation index, see [llms.txt](https://docs.realmjoin.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.realmjoin.com/es/automatizacion/runbooks/runbook-customization.md).

# Personalización del runbook

## Descripción general

La implementación de runbook de RealmJoin ofrece capacidades de personalización al autor de un runbook o al administrador de un entorno, de modo que puedan:

* Alojar parámetros y plantillas específicos del cliente/Tenant
* Ofrecer elementos de interfaz como selectores de usuarios o selecciones desplegables
* Presentar explicaciones de parámetros legibles por humanos
* Ocultar elementos de interfaz innecesarios

<figure><img src="/files/e9ed789c21b952ae92e1dd16bec579aa8a523734" alt=""><figcaption></figcaption></figure>

Las personalizaciones pueden incluirse en el propio runbook y/o almacenarse en la instancia de RealmJoin Portal del cliente. De forma predeterminada, intentaremos ofrecer valores predeterminados razonables en los runbooks ofrecidos en [GitHub](https://github.com/realmjoin/realmjoin-runbooks).

Algunos runbooks vendrán con ejemplos de cómo configurar plantillas específicas del cliente, como especificar ubicaciones de Office para la incorporación de usuarios.

### Formato

La personalización puede definirse (en orden descendente de prioridad)

* Bloque de JSON en [configuración de RealmJoin Portal](https://portal.realmjoin.com/settings/runbooks-customizations), anulando el comportamiento predeterminado del runbook
* Bloque de JSON en el encabezado de un runbook

Además (con la menor prioridad)

* por parámetro en el encabezado del runbook
* por parámetro en el bloque param del runbook (usando el módulo RJRb Helper)

Algunas funcionalidades (como las plantillas) solo están disponibles en formato JSON. Otras funcionalidades (como crear un selector de usuario) solo están disponibles al especificar un tipo de datos en el bloque param. Puede combinar varios tipos de personalización para obtener mejores resultados.

## Bloque Param del runbook

RealmJoin Portal analiza el bloque param de PowerShell de un runbook para determinar qué campos de entrada representar. Cuando es posible, también validará las entradas según el tipo .NET dado para una variable.

Actualmente se entienden los siguientes tipos de datos:

* `[bool]`, `[boolean]` - presentará un interruptor binario
* `[string]` - presentará un cuadro de texto para escribir cualquier entrada alfanumérica
* `[int]` - presentará un cuadro de texto, permitiendo solo entradas numéricas
* `[DateTime]`, `[DateTimeOffset]` - Presentará un selector de fecha y hora

Puede aplicar modificadores estándar de PowerShell a los parámetros. RealmJoin Portal, en particular, entenderá si especifica `[Parameter(Mandatory = $true)]` para indicar un parámetro obligatorio y exigir que estos parámetros se rellenen.

Cuando sea posible, RealmJoin Portal también leerá y mostrará los valores predeterminados dados en la interfaz.

Tenga en cuenta que los valores predeterminados del runbook pueden ser anulados por personalizaciones. Además, los parámetros pueden ocultarse por completo mediante personalizaciones.

### Personalización de parámetros

Para poder personalizar parámetros, asegúrese de incluir el módulo PS Runbook Helper de RealmJoin en su runbook:

`#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.6.0" }`

Luego puede incluir `[ValidateScript( { Use-RJInterface ... } )]` instrucciones en las definiciones de parámetros. Por ejemplo, lo siguiente creará un selector de usuario, permitiendo elegir un usuario de Entra ID y pasará su id de objeto como cadena al runbook.

```powershell
param(
    [ValidateScript( { Use-RJInterface -DisplayName "Assign device to this user (optional)" -Type Graph -Entity User } )]
    [string] $AssignedUserId = ""
)
```

Veámoslo paso a paso. `[ValidateScript...]` es un modificador para el siguiente parámetro definido en el bloque param. En este caso, la variable `$AssignedUserId`.

`Use-RJInterface` forma parte de nuestro [RealmJoin Runbook Helper](https://github.com/realmjoin/RealmJoin.RunbookHelper) módulo de PowerShell. Le permite especificar qué tipo de entrada espera usando `-Type` y `-Entity`, si eso no está ya completamente definido por el tipo de variable.

`-DisplayName` le permite pasar una solicitud / descripción legible por humanos para este parámetro a RealmJoin Portal.

#### Recursos de Graph

En el ejemplo anterior, la fuente de información es MS Graph, como se describe mediante `-Type Graph`. Para MS Graph, use `-Entity` para especificar qué tipo de recurso espera. Las entidades disponibles son `usuarios`, `Grupo`, `Dispositivo`. Esto producirá un selector para usuarios, grupos o dispositivos en el Entra ID dado.

El selector incluye una búsqueda rápida para localizar fácilmente el recurso requerido.

![Ejemplo de selector](/files/7506db651a8786f2e44b8a08814b5a6cf31d732f)

Actualmente, no es posible la multiselección usando un selector.

De forma predeterminada, un selector de MS Graph devolverá el ID del objeto. Si necesita, por ejemplo, el nombre principal de usuario en su lugar, asegúrese de incluir "name" como sufijo en el nombre de su variable. Así que, básicamente, para obtener el id de un usuario, nombre el parámetro `$userid`. Si quiere un UPN, asígnele el nombre `$username`.

#### Filtrado de Graph

Si está usando un selector basado en MS Graph, también puede especificar `-Filter` y usar un [ODATA-Filter](https://docs.microsoft.com/en-us/graph/query-parameters?context=graph%2Fapi%2F1.0\&view=graph-rest-1.0#filter-parameter) para limitar los objetos ofrecidos en el selector.

El siguiente ejemplo mostrará solo grupos de Entra ID que comiencen con "LIC\_".

```powershell
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript( { Use-RJInterface -Type Graph -Entity Group -Filter "startswith(DisplayName, 'LIC_')" -DisplayName "Grupo de licencia" } )]
    [String] $GroupID_License
)
```

Puede preparar filtros y reutilizarlos en varios scripts usando el [almacén de datos central](#graph-filters). En este caso, solo haga referencia al filtro por nombre usando `-Filter "ref:LicenseGroup"`, donde `ref:` indica que se busque un filtro almacenado.

```powershell
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript( { Use-RJInterface -Type Graph -Entity Group -Filter "ref:LicenseGroup" } )]
    [String] $GroupID_License
)
```

Este ejemplo concreto `ref:LicenseGroup` está disponible de forma predeterminada sin configuración adicional.

![filtro ODATA](/files/71860a6593755dc4e0baf0c416860ba260ad0fd7)

## Encabezado del runbook

El Portal puede analizar el [ayuda basada en comentarios](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help?view=powershell-5.1) sección, si está presente.

Aquí hay un ejemplo:

```powershell
<#
  .SYNOPSIS
  (Des)asignar una licencia a un usuario mediante la pertenencia a un grupo.

  .DESCRIPTION
  (Des)asignar una licencia a un usuario mediante la pertenencia a un grupo. Descripción más detallada...

  .PARAMETER DefaultGroups
  Lista de grupos separados por comas para asignar. p. ej. "DL Sales,LIC Internal Product"

  .NOTES
  Permisos:
  MS Graph (API):
  - User.Read.All
  - GroupMember.ReadWrite.All 
  - Group.ReadWrite.All

  .INPUTS
  RunbookCustomization: {
        "Parameters": {
            "UserName": {
                "Hide": true
            },
            "Remove": {
                "DisplayName": "Asignar o quitar licencia",
                "SelectSimple": {
                    "Assign License to User": false,
                    "Remove License from User": true
                }
            }
        }
    }
#>
```

`.SYNOPSIS` - Proporcione una descripción muy breve de la función de su runbook. Esto se mostrará en la lista de runbooks disponibles.

`.DESCRIPTION` - Proporcione una descripción de la función de su runbook. Puede contener algo más de detalle, ya que esto se mostrará dentro del diálogo de ejecución / parámetros del runbook.

`.PARAMETER` - Debe ir seguido del nombre de un parámetro. Le permite dar una explicación detallada de la entrada esperada para el parámetro en cuestión.

`.INPUTS` - Puede contener un bloque de personalización de runbook basado en JSON.

`.NOTES` - No se analiza / representa. Utilice este espacio para anotar qué permisos y requisitos existen para su runbook.

`.EXAMPLE` - No se analiza / representa. Puede contener un ejemplo de una personalización basada en JSON para usar en el almacén de datos de RealmJoin en su Tenant. Estos pueden ser ejemplos de cómo crear plantillas, por ejemplo, para diferentes flujos de trabajo o clases de usuario.

## Personalización basada en JSON

### Almacén de datos central

Cada Tenant de Azure puede alojar un almacén de datos de "Runbook Customizations", que se encuentra en <https://portal.realmjoin.com/settings/runbooks-customizations> .

El formato es JSON con comentarios, permitiendo comas finales. Actualmente, hay tres secciones relevantes, `bloque Settings`, `Plantillas`, `Runbooks`.

```json
{
    "Settings": {
    },
    "Templates": {
    },
    "Runbooks": {
    }
}
```

### sección de runbooks

`Runbooks` es analizada por el portal al iniciar un runbook. Si existe una sección con el nombre del actual Azure Automation Runbook, su contenido se usará para personalizar el frontend mostrado al usuario.

Suponga el siguiente runbook de demostración simple, llamado `rjgit-device_demo-runbook-customizing`.

```powershell
<#
  .SYNOPSIS
  Demostración de personalización de runbook

  .DESCRIPTION
  Demostración de personalización de runbook, como desplegable/selección
#>

#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.6.0" }

param(
    [string] $DeviceId,
    [bool] $ExtraWorkflow = $true,
    [int] $ExtraWorkflowTime = 15
)

"## Haciendo cosas al dispositivo '$DeviceID'"

# Flujo de trabajo complicado altamente opcional
if ($ExtraWorkflow) {
    "## Ejecutando meditación..."
    Start-Sleep -Seconds $ExtraWorkflowTime
}
```

Si no se personaliza, se presentará así en el frontend:

![Demo - antes](/files/a152cea1c1573e4e73c2b56f219bb12b81bf19f7)

Reflexiones:

* Como este runbook se inicia desde el contexto de un dispositivo en el portal, el `$DeviceId` es información redundante para un usuario. Ya sé en qué dispositivo estoy trabajando.
* ¿Qué ocurre si activo o desactivo el "Extra Workflow"? ¿Tengo que preocuparme por "Extra Workflow Time" si desactivo "Extra Workflow"?

Mejoremos eso. El siguiente JSON de ejemplo en el almacén de datos central modificará la interfaz de usuario del runbook.

```json
{
    "Runbooks": {
        "rjgit-device_demo-runbook-customizing": {
            "ParameterList": [
                {
                    "Name": "DeviceId",
                    "Hide": true
                }, 
                {
                    "Name": "ExtraWorkflow",
                    "Hide": true
                },
                {
                    "Name": "ExtraWorkflowTime",
                    "DisplayName": "¿Cuánto tiempo meditar?",
                },
                {
                    "DisplayName": "Ejecutar flujo de trabajo adicional",
                    "DisplayBefore": "ExtraWorkflowTime",
                    "Select": {
                        "Options": [
                            {
                                "Display": "Ejecutar meditación (opcional)",
                                "Customization": {
                                    "Default": {
                                        "ExtraWorkflow": true
                                    }
                                }
                            },
                            {
                                "Display": "Omitir la atención plena del dispositivo",
                                "Customization": {
                                    "Default": {
                                        "ExtraWorkflow": false
                                    },
                                    "Hide": [
                                        "ExtraWorkflowTime"
                                    ]
                                }
                            }
                        ],
                        
                    },
                    "Default": "Omitir la atención plena del dispositivo"
                }
            ]
        }
    }
}
```

Puede usar la misma notación / características en su [encabezado del runbook](#runbook-header).

#### ParameterList

Cada parámetro tiene su propia sección en `ParameterList`. [Modificadores](#modifiers) permiten cambiar el comportamiento de ese parámetro.

El resultado se verá así:

![Demo - después de ocultar](/files/d53c9da577ab8b250d952d5785fc7612552ba3f5)

Elegir el flujo de trabajo adicional mostrará (desocultará) más parámetros:

![Demo - después de desocultar](/files/50e8d01f4c2d67ce7c4644a2e9fff8d6e3286d5d)

Esto muestra menos desorden en comparación con antes de aplicar la personalización. Al mismo tiempo, el usuario dispone de más información sobre las alternativas de "Extra Workflow". Además, un usuario ahora solo se preocupará por "Extra Workflow Time" si es relevante.

El cambio de visibilidad de ese campo se realizó usando un `"Customization"` bloque dentro de una de las `"Select"` opciones. Actualmente solo puede haber como máximo un bloque de ese tipo `"Customization"` activo a la vez.

Como puede ver, el parámetro `$DeviceId` está completamente oculto. Esto se hace estableciendo el `"Hide": true` para este parámetro.

Los parámetros pueden tener un `DisplayName`. Ofrecimos una `DisplayName` amigable para humanos para reemplazar `$ExtraWorkflowTime` en la interfaz de usuario. Vea otros [modificadores](#modifiers) para más información.

Puede insertar parámetros "sin nombre" (a los que les falta la `Nombre` declaración) como la sección "Execute Extra Workflow", si desea ofrecer elementos de interfaz sin devolver directamente un valor. Esto normalmente solo se usa junto con `Seleccione`.

#### Seleccione

Usamos `Seleccione`, para mostrar una lista de `Options` en un menú desplegable. Cada opción puede `Visualización` texto, o activar un `Personalización`, como establecer `Ocultar` o un `Predeterminado` valor en otros parámetros. En nuestro ejemplo, lo usamos para (des)ocultar `$ExtraWorkflowTime` y reemplazar `$ExtraWorkflow`su valor.

`$ExtraWorkflowTime` se muestra, por tanto, solo cuando es relevante y el interruptor binario `$ExtraWorkflow` ahora se reemplaza con alternativas significativas desde la perspectiva del usuario.

En caso de `Seleccione` para un parámetro con nombre, cada opción debería tener un `"ParameterValue": "..."` para pasar al runbook. Puede colocar un `"ShowValue: false"` dentro del `Seleccione` bloque para mostrar solo el menú desplegable y no un campo para el valor resultante del parámetro.

Ejemplo de parámetro con nombre:

```json
{
    "Name": "ExtraWorkflow",
    "DefaultValue": true,
    "DisplayName": "Ejecutar flujo de trabajo adicional",
    "DisplayBefore": "ExtraWorkflowTime",
    "Select": {
        "Options": [
            {
                "Display": "Ejecutar meditación (opcional)",
                "ParameterValue": true
            },
            {
                "Display": "Omitir la atención plena del dispositivo",
                "ParameterValue": false,
                "Customization": {
                    "Hide": [
                        "ExtraWorkflowTime"
                    ]
                }
            }
        ],
        "ShowValue": false
    }
}
```

La `Predeterminado` / `DefaultValue` declaración en el parámetro también especifica el estado inicial del menú desplegable. En caso de un parámetro sin nombre, use el `DisplayName` de la opción deseada; de lo contrario, proporcione un valor de retorno predeterminado, como "true" o "false" o alguna cadena.

#### Parámetros

Si solo tiene parámetros con nombre, puede usar el `Parámetros` formato ligeramente más corto en lugar de `ParameterList`.

Para un ejemplo, vea SelectSimple

#### SelectSimple

Si no se necesita toda la potencia de un `Seleccione` no es necesaria y solo desea ofrecer una lista de valores posibles en un menú desplegable (sin aplicar personalización adicional), puede usar `SelectSimple`.

`SelectSimple` solo se puede usar para parámetros con nombre.

Ejemplo:

```json
{
    "Runbooks": {
        "rjgit-device_demo-runbook-customizing": {
            "Parameters": {
                "DeviceId": {
                    "Hide": true
                }, 
                "ExtraWorkflow": {
                    "Name": "ExtraWorkflow",
                    "DisplayName": "Ejecutar flujo de trabajo adicional",
                    "Default": false,
                    "SelectSimple": {
                        "Ejecutar meditación (opcional)": true,
                        "Omitir la atención plena del dispositivo": false
                    }
                },
                "ExtraWorkflowTime": {
                    "DisplayName": "¿Cuánto tiempo meditar?"
                }
            }
        }
    }
}
```

La mayor diferencia (además de ser mucho más corto) con respecto a nuestro ejemplo anterior es que `$ExtraWorkflowTime` siempre está visible.

#### Modificadores

Cada parámetro puede tener uno o más de los siguientes modificadores:

* `"DisplayName": "text"` - Muestra "text" como nombre del parámetro en la interfaz
* `"Hide": true / false` - Oculta este parámetro
* `"Mandatory": true / false` - Exige que este parámetro se rellene
* `"ReadOnly": true / false` - Protege este parámetro para que no se cambie desde su valor predeterminado
* `"DefaultValue": "..."` - Establece un valor predeterminado para este parámetro. (También puede usar `Predeterminado` en su lugar.)
* `"GraphFilter": "startswith(DisplayName, 'LIC_')"` - vea [Filtrado de Graph](#graph-filtering)
* `"AllowEdit": true / false` - Protege este parámetro de la edición manual. (combínelo con plantillas)

### bloque Settings

`bloque Settings` le permite almacenar datos de configuración como nombres de Storage Account de Azure en un lugar central, manteniéndolos al mismo tiempo separados de sus runbooks.

Puede acceder a valores individuales desde el bloque param de un runbook usando `Use-RJInterface`.

Tomemos este ejemplo de bloque param de un runbook:

```powershell
param(
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.Container" } )]
    [string] $ContainerName,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.ResourceGroup" } )]
    [string] $ResourceGroupName,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.StorageAccount.Name" } )]
    [string] $StorageAccountName,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.StorageAccount.Location" } )]
    [string] $StorageAccountLocation,
    [ValidateScript( { Use-RJInterface -Type Setting -Attribute "CaPoliciesExport.StorageAccount.Sku" } )]
    [string] $StorageAccountSku
)
```

Portal intentará rellenar previamente cada parámetro con valores del almacén de datos central, si están presentes. Esto también funciona si el parámetro se ha ocultado en la interfaz.

Un posible JSON en el almacén de datos para este runbook sería:

```json
{
    "Settings": {
        "CaPoliciesExport": {
            "ResourceGroup": "rj-runbooks-01",
            "StorageAccount": {
                "Name": "rjrbexports01",
                "Location": "West Europe",
                "Sku": "Standard_LRS"
            }
        }
    }
}
```

El elemento faltante `Container` simplemente no se rellenará previamente en la interfaz.

### Plantillas

`Plantillas` use JSON-references to pull in data - for example a lengthy list of Office locations - when using a `Seleccione` declaración.

Esto permite mantener una personalización neutral/reutilizable/separada de los datos reales.

Tomemos el ejemplo de la incorporación de nuevos usuarios. Podría tener múltiples opciones dadas para departamentos o ubicaciones de Office, donde asignar una ubicación de Office también exige una determinada dirección, país, estado, etc.

El siguiente ejemplo de personalización de runbook usa la `$ref` dentro del `Runbooks` sección para referenciar/importar un subárbol desde la `Plantillas` sección. Busque las palabras clave `$id`/`$values` . Tenga en cuenta que `$id`/`$values` deben definirse antes de referenciarlas usando `$ref`. Por eso `Plantillas` se define antes que `Runbooks` en este ejemplo.

En este ejemplo le decimos al portal que obtenga el subárbol con el `$id` llamado `LocationOptions` e incluir sus `$values`, reemplazando la `$ref` declaración. Así, el portal representará un `Seleccione` como se describe en la `Runbooks` sección, pero incluirá las opciones reales de `Plantillas`.

Una plantilla puede contener cualquier declaración compatible en la ubicación que la referencia. En este ejemplo, usamos una `Personalización` declaración para modificar otros parámetros como `Dirección`.

Así, podemos tener una personalización específica del runbook en `Runbooks` reutilizable en varios entornos, manteniendo los datos reales separados.

```json
{
    "Templates": {
        "Options": [
            {
                "$id": "LocationOptions",
                "$values": [
                    {
                        "Display": "DE-OF",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Kaiserstraße 39",
                                "PostalCode": "63065",
                                "City": "Offenbach",
                                "Country": "Alemania"
                            }
                        }
                    },
                    {
                        "Display": "DE-DEG",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Lateinschulgassse 24-26",
                                "PostalCode": "94469",
                                "City": "Deggendorf",
                                "Country": "Alemania"
                            }
                        }
                    },
                    {
                        "Display": "DE-HH",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Hans-Henny-Jahnn-Weg 53",
                                "PostalCode": "22085",
                                "City": "Hamburg",
                                "Country": "Alemania"
                            }
                        }
                    },
                    {
                        "Display": "FI-HS",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Algún lugar 42",
                                "PostalCode": "12345",
                                "City": "Helsinki",
                                "Country": "Finlandia"
                            }
                        }
                    }
                ]
            },
            {
                "$id": "CompanyOptions",
                "$values": [
                    {
                        "Id": "gkg",
                        "Display": "glueckkanja",
                        "Value": "glueckkanja AG"
                    },
                    {
                        "Id": "pp",
                        "Display": "PRIMEPULSE",
                        "Value": "PRIMEPULSE SE"
                    }
                ]
            }
        ]
    },
    "Runbooks": {
        "rjgit-org_general_add-user": {
            "ParameterList": [
                {
                    "DisplayName": "Ubicación de Office",
                    "DisplayAfter": "CompanyName",
                    "Select": {
                        "Options": {
                            "$ref": "LocationOptions"
                        }
                    }
                },
                {
                    "Name": "CompanyName",
                    "Select": {
                        "Options": {
                            "$ref": "CompanyOptions"
                        },
                        "AllowEdit": false
                    }
                }
            ],
            "ReadOnly": [
                "StreetAddress",
                "PostalCode",
                "City",
                "Country"
            ]
        }
    }
}
```

Esto creará la siguiente interfaz de usuario:

![Demostración - ref-location](/files/8fd5633b5691ba44c5de017dc084f34e0297d6bb)

![Demostración - ref-address](/files/ed7d68520e7e34ea8adb01165b6f8e78a690e080)

### Filtros de Graph

Puedes preparar [Filtros ODATA de Graph](https://docs.microsoft.com/en-us/graph/query-parameters?context=graph%2Fapi%2F1.0\&view=graph-rest-1.0#filter-parameter) para usarlos en varios runbooks. Guárdalos en una sección llamada `GraphFilters`.

El siguiente ejemplo filtra un determinado prefijo en el `DisplayName` de un grupo, para mostrar solo grupos relacionados con licencias en un selector de grupos.

```json
"GraphFilters": {
    "LicenseGroup": "startswith(DisplayName, 'LIC_')" // también incluido en el código RJ como valor predeterminado
  }
```

Vea [Filtrado de Graph](#graph-filtering) sobre cómo usar esto desde un runbook.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.realmjoin.com/es/automatizacion/runbooks/runbook-customization.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
