> 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/pt/automacao/runbooks/runbook-customization.md).

# Personalização de Runbooks

## Visão geral

A implementação do runbook do RealmJoin oferece recursos de personalização ao autor de um runbook ou ao administrador de um ambiente, para que possam:

* Hospedar parâmetros e modelos específicos do cliente/Tenant
* Oferecer elementos de interface, como seletores de usuários ou seleções em lista suspensa
* Apresentar explicações legíveis por humanos dos parâmetros
* Ocultar elementos de interface desnecessários

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

As personalizações podem ser incluídas no próprio runbook e/ou armazenadas na instância do RealmJoin Portal do cliente. Por padrão, tentaremos oferecer predefinições sensatas nos runbooks oferecidos em [GitHub](https://github.com/realmjoin/realmjoin-runbooks).

Alguns runbooks virão com exemplos de como configurar modelos específicos do cliente, como especificar localizações de escritório para a integração de usuários.

### Formatar

A personalização pode ser definida (em ordem decrescente de prioridade)

* Bloco de JSON em [configurações do RealmJoin Portal](https://portal.realmjoin.com/settings/runbooks-customizations), substituindo o comportamento padrão do runbook
* Bloco de JSON no cabeçalho de um runbook

Além disso (com a menor prioridade)

* por parâmetro no cabeçalho do runbook
* por parâmetro no bloco param do runbook (usando o módulo RJRb Helper)

Algumas funcionalidades (como modelos) só estão disponíveis no formato JSON. Algumas funcionalidades (como criar um seletor de usuário) só estão disponíveis ao especificar um tipo de dados no bloco param. Você pode combinar vários tipos de personalização para obter melhores resultados.

## Bloco Param do Runbook

O RealmJoin Portal analisa o bloco param de PowerShell de um runbook para determinar quais campos de entrada renderizar. Quando possível, também validará as entradas de acordo com o tipo .NET fornecido para uma variável.

Os seguintes tipos de dados são atualmente reconhecidos:

* `[bool]`, `[boolean]` - apresentará um alternador binário
* `[string]` - apresentará uma caixa de texto para digitar qualquer entrada alfanumérica
* `[int]` - apresentará uma caixa de texto, permitindo apenas entradas numéricas
* `[DateTime]`, `[DateTimeOffset]` - apresentará um seletor de data/hora

Você pode aplicar modificadores padrão do PowerShell aos parâmetros. O RealmJoin Portal, em particular, entenderá se você especificar `[Parameter(Mandatory = $true)]` para indicar um parâmetro obrigatório e exigir que esses parâmetros sejam preenchidos.

Quando possível, o RealmJoin Portal também lerá e apresentará os valores padrão fornecidos na interface.

Esteja ciente de que os valores padrão do runbook podem ser substituídos por personalizações. Além disso, os parâmetros podem ser completamente ocultados por personalizações.

### Personalizando Parâmetros

Para poder personalizar parâmetros, certifique-se de incluir o módulo PS Runbook Helper do RealmJoin no seu runbook:

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

Você pode então incluir `[ValidateScript( { Use-RJInterface ... } )]` instruções nas definições dos parâmetros. Por exemplo, o seguinte criará um seletor de usuário, permitindo escolher um usuário do Entra ID e passará seu ID de objeto como string para o runbook.

```powershell
param(
    [ValidateScript( { Use-RJInterface -DisplayName "Atribuir dispositivo a este usuário (opcional)" -Type Graph -Entity User } )]
    [string] $AssignedUserId = ""
)
```

Vamos analisar isso passo a passo. `[ValidateScript...]` é um modificador para o próximo parâmetro definido no bloco param. Neste caso, a variável `$AssignedUserId`.

`Use-RJInterface` faz parte do nosso [RealmJoin Runbook Helper](https://github.com/realmjoin/RealmJoin.RunbookHelper) módulo PowerShell. Ele permite especificar que tipo de entrada você espera usando `-Type` e `-Entity`, se isso ainda não estiver totalmente definido pelo tipo da variável.

`-DisplayName` permite transmitir ao RealmJoin Portal um prompt / descrição legível por humanos para este parâmetro.

#### Recursos do Graph

No exemplo acima, a fonte de informação é o MS Graph, como descrito por `-Type Graph`. Para o MS Graph, use `-Entity` para especificar que tipo de recurso você está esperando. As entidades disponíveis são `Usuário`, `Grupo`, `Dispositivo`. Isso produzirá um seletor para usuários, grupos ou dispositivos no Entra ID fornecido.

O seletor inclui uma pesquisa rápida, para localizar facilmente o recurso necessário.

![Exemplo de seletor](/files/fd8e7a08510ba33d9ad8bc27ed96b9401be94849)

Atualmente, não é possível selecionar vários itens usando um seletor.

Por padrão, um seletor do MS Graph retornará o ID do objeto. Se você precisar, por exemplo, do nome principal do usuário em vez disso, certifique-se de incluir "name" como sufixo no nome da sua variável. Então, basicamente, para obter o ID de um usuário, nomeie o parâmetro `$userid`. Se quiser um UPN, nomeie-o `$username`.

#### Filtragem do Graph

Se estiver usando um seletor baseado no MS Graph, você também pode especificar `-Filter` e usar um [filtro ODATA](https://docs.microsoft.com/en-us/graph/query-parameters?context=graph%2Fapi%2F1.0\&view=graph-rest-1.0#filter-parameter) para limitar os objetos oferecidos no seletor.

O exemplo a seguir listará apenas grupos do Entra ID que começam com "LIC\_".

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

Você pode preparar filtros e reutilizá-los em vários scripts usando o [armazenamento central](#graph-filters). Nesse caso, basta referenciar o filtro pelo nome usando `-Filter "ref:LicenseGroup"`, onde `ref:` indica procurar um filtro armazenado.

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

Este exemplo específico `ref:LicenseGroup` está disponível por padrão, sem necessidade de configuração adicional.

![filtro ODATA](/files/af67c2f470082ec3fe983dfbd473ab0da74f6b0f)

## Cabeçalho do runbook

O Portal pode analisar a [ajuda baseada em comentários](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help?view=powershell-5.1) do runbook, se presente.

Aqui está um exemplo:

```powershell
<#
  .SYNOPSIS
  (Des)atribuir uma licença a um usuário por meio da associação a grupos.

  .DESCRIPTION
  (Des)atribuir uma licença a um usuário por meio da associação a grupos. Descrição mais detalhada...

  .PARAMETER DefaultGroups
  Lista de grupos separada por vírgulas para atribuir, por ex. "DL Sales,LIC Internal Product"

  .NOTES
  Permissões:
  MS Graph (API):
  - User.Read.All
  - GroupMember.ReadWrite.All 
  - Group.ReadWrite.All

  .INPUTS
  RunbookCustomization: {
        "Parameters": {
            "UserName": {
                "Hide": true
            },
            "Remove": {
                "DisplayName": "Atribuir ou remover licença",
                "SelectSimple": {
                    "Assign License to User": false,
                    "Remove License from User": true
                }
            }
        }
    }
#>
```

`.SYNOPSIS` - Dê uma descrição muito breve da função do seu runbook. Isso será exibido na lista de runbooks disponíveis.

`.DESCRIPTION` - Dê uma descrição da função do seu runbook. Pode conter um pouco mais de detalhes, pois isso será exibido dentro da caixa de diálogo de execução/parâmetros do runbook.

`.PARAMETER` - Precisa ser seguido pelo nome de um parâmetro. Permite fornecer uma explicação detalhada da entrada esperada para o parâmetro em questão.

`.INPUTS` - Pode conter um bloco de personalização de runbook baseado em JSON.

`.NOTES` - Não é analisado/renderizado. Use este espaço para anotar quais permissões e requisitos existem para o seu runbook.

`.EXAMPLE` - Não é analisado/renderizado. Pode conter um exemplo de personalização baseada em JSON para usar no armazenamento do RealmJoin no seu Tenant. Estes podem ser exemplos de como criar modelos, por exemplo, para diferentes fluxos de trabalho ou classes de usuários.

## Personalização Baseada em JSON

### Armazenamento central

Cada Tenant do Azure pode hospedar um armazenamento "Runbook Customizations", encontrado em <https://portal.realmjoin.com/settings/runbooks-customizations> .

O formato é JSON com comentários, permitindo vírgulas à direita. Atualmente, há três seções relevantes, `Definições`, `Modelos`, `Runbooks`.

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

### seção Runbooks

`Runbooks` é analisada pelo portal ao iniciar um runbook. Se existir uma seção com o mesmo nome do Azure Automation Runbook atual, seu conteúdo será usado para personalizar o front-end exibido ao usuário.

Considere o seguinte runbook de demonstração simples, chamado `rjgit-device_demo-runbook-customizing`.

```powershell
<#
  .SYNOPSIS
  Demonstrar a personalização de runbooks

  .DESCRIPTION
  Demonstrar a personalização de runbooks, como lista suspensa/seleção
#>

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

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

"## Fazendo coisas com o dispositivo '$DeviceID'"

# Fluxo de trabalho complicado altamente opcional
if ($ExtraWorkflow) {
    "## Executando meditação..."
    Start-Sleep -Seconds $ExtraWorkflowTime
}
```

Se não for personalizado, ele será apresentado assim no front-end:

![Demonstração - antes](/files/1bbf7a0209bf21af95d610cb26d298976c221f5c)

Pensamentos:

* Como este runbook é iniciado a partir do contexto de um dispositivo no portal, o `$DeviceId` é uma informação redundante para o usuário. Já sei em qual dispositivo estou trabalhando.
* O que acontece se eu ativar ou desativar o "Extra Workflow"? Preciso pensar no "Extra Workflow Time" se desativar o "Extra Workflow"?

Vamos melhorar isso. O seguinte JSON de exemplo no armazenamento central modificará a interface do usuário para o runbook.

```json
{
    "Runbooks": {
        "rjgit-device_demo-runbook-customizing": {
            "ParameterList": [
                {
                    "Name": "DeviceId",
                    "Hide": true
                }, 
                {
                    "Name": "ExtraWorkflow",
                    "Hide": true
                },
                {
                    "Name": "ExtraWorkflowTime",
                    "DisplayName": "Quanto tempo meditar?",
                },
                {
                    "DisplayName": "Executar fluxo de trabalho extra",
                    "DisplayBefore": "ExtraWorkflowTime",
                    "Select": {
                        "Options": [
                            {
                                "Display": "Executar meditação (opcional)",
                                "Customization": {
                                    "Default": {
                                        "ExtraWorkflow": true
                                    }
                                }
                            },
                            {
                                "Display": "Ignorar atenção ao dispositivo",
                                "Customization": {
                                    "Default": {
                                        "ExtraWorkflow": false
                                    },
                                    "Hide": [
                                        "ExtraWorkflowTime"
                                    ]
                                }
                            }
                        ],
                        
                    },
                    "Default": "Skip Device Mindfulness"
                }
            ]
        }
    }
}
```

Você pode usar a mesma notação / os mesmos recursos no seu [cabeçalho do runbook](#runbook-header).

#### ParameterList

Cada parâmetro tem sua própria seção em `ParameterList`. [Modificadores](#modifiers) permitem alterar o comportamento desse parâmetro.

O resultado ficará assim:

![Demonstração - após ocultar](/files/13056fe34a28a7dd86d5a404c992058d0fcfbf5a)

Escolher o fluxo adicional apresentará (reexibirá) mais parâmetros:

![Demonstração - após reexibição](/files/0fade93442f6dcac041b2e83099d5de301ceabd5)

Isso mostra menos desordem em comparação com antes de aplicar a personalização. Ao mesmo tempo, mais informações sobre as alternativas de "Extra Workflow" ficam disponíveis para o usuário. Além disso, o usuário agora só se preocupará com "Extra Workflow Time" se isso for relevante.

A alteração da visibilidade desse campo foi feita usando um `"Customization"` bloco dentro de uma das `"Select"` opções. Atualmente, você pode ter no máximo um desses `"Customization"` bloco ativo por vez.

Como você pode ver, o parâmetro `$DeviceId` está completamente oculto. Isso é feito definindo o `"Hide": true` para este parâmetro.

Os parâmetros podem ter um `DisplayName`. Oferecemos um `DisplayName` legível por humanos para substituir `$ExtraWorkflowTime` na interface. Veja outros [modificadores](#modifiers) para mais detalhes.

Você pode inserir parâmetros "sem nome" (faltando o `Nome` instrução) como a seção "Execute Extra Workflow", se quiser oferecer elementos de interface sem retornar diretamente um valor. Isso normalmente é usado apenas em conjunto com `Selecione`.

#### Selecione

Usamos `Selecione`, para exibir uma lista de `Options` em uma lista suspensa. Cada opção pode `Exibição` texto, ou acionar um `Personalização`, como definir `Hide` ou um `Predefinição` valor em outros parâmetros. Em nosso exemplo, usamos isso para ocultar/exibir `$ExtraWorkflowTime` e substituir `$ExtraWorkflow`do seu valor.

`$ExtraWorkflowTime` é, portanto, exibido apenas quando relevante, e o alternador binário `$ExtraWorkflow` agora é substituído por alternativas significativas do ponto de vista do usuário.

No caso de um `Selecione` para um parâmetro nomeado, cada opção deve ter um `"ParameterValue": "..."` para passar para o runbook. Você pode colocar um `"ShowValue: false"` dentro do `Selecione` bloco para mostrar apenas a lista suspensa e não um campo para o valor resultante do parâmetro.

Exemplo de parâmetro nomeado:

```json
{
    "Name": "ExtraWorkflow",
    "DefaultValue": true,
    "DisplayName": "Executar fluxo de trabalho extra",
    "DisplayBefore": "ExtraWorkflowTime",
    "Select": {
        "Options": [
            {
                "Display": "Executar meditação (opcional)",
                "ParameterValue": true
            },
            {
                "Display": "Ignorar atenção ao dispositivo",
                "ParameterValue": false,
                "Customization": {
                    "Hide": [
                        "ExtraWorkflowTime"
                    ]
                }
            }
        ],
        "ShowValue": false
    }
}
```

O `Predefinição` / `DefaultValue` a instrução no parâmetro também especifica o estado inicial da lista suspensa. No caso de um parâmetro sem nome, use o `DisplayName` da opção desejada; caso contrário, forneça um valor de retorno padrão, como "true" ou "false" ou alguma string.

#### Parâmetros

Se você tiver apenas parâmetros nomeados, poderá usar o formato um pouco mais curto `Parâmetros` em vez de `ParameterList`.

Para um exemplo, veja SelectSimple

#### SelectSimple

Se todo o poder de um `Selecione` não for necessário e você quiser apenas oferecer uma lista de valores possíveis em uma lista suspensa (sem aplicar personalização adicional), você pode usar `SelectSimple`.

`SelectSimple` só pode ser usado para parâmetros nomeados.

Exemplo:

```json
{
    "Runbooks": {
        "rjgit-device_demo-runbook-customizing": {
            "Parameters": {
                "DeviceId": {
                    "Hide": true
                }, 
                "ExtraWorkflow": {
                    "Name": "ExtraWorkflow",
                    "DisplayName": "Executar fluxo de trabalho extra",
                    "Default": false,
                    "SelectSimple": {
                        "Executar meditação (opcional)": true,
                        "Ignorar atenção ao dispositivo": false
                    }
                },
                "ExtraWorkflowTime": {
                    "DisplayName": "Quanto tempo meditar?"
                }
            }
        }
    }
}
```

A maior diferença em relação ao nosso exemplo anterior (além de ser muito mais curto) é que `$ExtraWorkflowTime` está sempre visível.

#### Modificadores

Cada parâmetro pode ter um ou mais dos seguintes modificadores:

* `"DisplayName": "text"` - Exibe "text" como nome do parâmetro na interface
* `"Hide": true / false` - Oculta este parâmetro
* `"Mandatory": true / false` - Exige que este parâmetro seja preenchido
* `"ReadOnly": true / false` - Protege este parâmetro contra alterações em relação ao seu valor padrão
* `"DefaultValue": "..."` - Define um valor padrão para este parâmetro. (Você também pode usar `Predefinição` em vez disso.)
* `"GraphFilter": "startswith(DisplayName, 'LIC_')"` - veja [Filtragem do Graph](#graph-filtering)
* `"AllowEdit": true / false` - Protege este parâmetro contra edição manual. (combine isso com modelos)

### Definições

`Definições` permite armazenar dados de configuração, como nomes de Storage Account do Azure, em um local central, mantendo-os separados dos seus runbooks.

Você pode acessar valores individuais do bloco param de um runbook usando `Use-RJInterface`.

Vamos pegar este exemplo de bloco param de um 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
)
```

O Portal tentará preencher previamente cada parâmetro com valores do armazenamento central - se houver. Isso também funciona se o parâmetro tiver sido ocultado na interface.

Um possível JSON no armazenamento para este runbook seria:

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

O elemento `Container` ausente simplesmente não será preenchido previamente na interface.

### Modelos

`Modelos` use referências JSON para importar dados - por exemplo, uma longa lista de localizações de escritório - ao usar uma `Selecione` instrução.

Isso permite manter uma personalização neutra/reutilizável/separada dos dados reais.

Vamos considerar o exemplo de integração de novos usuários. Você pode ter várias opções disponíveis para departamentos ou localizações de escritório, em que atribuir uma localização de escritório também exige um determinado endereço, país, estado etc.

O seguinte exemplo de personalização de runbook usa a `$ref` dentro do `Runbooks` seção para referenciar/importar uma subárvore da `Modelos` seção. Fique atento às `$id`/`$values` palavras-chave. Esteja ciente de que `$id`/`$values` precisam ser definidos antes de serem referenciados usando `$ref`. É por isso que `Modelos` é definido antes de `Runbooks` neste exemplo.

Neste exemplo, dizemos ao portal para obter a subárvore com o `$id` chamada `LocationOptions` e incluir os seus `$values`, substituindo a `$ref` instrução. Assim, o portal renderizará um `Selecione` conforme descrito na `Runbooks` seção, mas incluir as opções reais de `Modelos`.

Um template pode conter qualquer instrução que seja suportada no local de referência. Neste exemplo, usamos uma `Personalização` instrução para modificar outros parâmetros, como `StreetAddress`.

Assim, podemos ter uma customização específica de runbook em `Runbooks` reutilizável em vários ambientes, mantendo os dados reais separados.

```json
{
    "Templates": {
        "Options": [
            {
                "$id": "LocationOptions",
                "$values": [
                    {
                        "Display": "DE-OF",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Kaiserstraße 39",
                                "PostalCode": "63065",
                                "City": "Offenbach",
                                "Country": "Germany"
                            }
                        }
                    },
                    {
                        "Display": "DE-DEG",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Lateinschulgassse 24-26",
                                "PostalCode": "94469",
                                "City": "Deggendorf",
                                "Country": "Germany"
                            }
                        }
                    },
                    {
                        "Display": "DE-HH",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Hans-Henny-Jahnn-Weg 53",
                                "PostalCode": "22085",
                                "City": "Hamburg",
                                "Country": "Germany"
                            }
                        }
                    },
                    {
                        "Display": "FI-HS",
                        "Customization": {
                            "Default": {
                                "StreetAddress": "Somewhere 42",
                                "PostalCode": "12345",
                                "City": "Helsinki",
                                "Country": "Finland"
                            }
                        }
                    }
                ]
            },
            {
                "$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": "Localização do Office",
                    "DisplayAfter": "CompanyName",
                    "Select": {
                        "Options": {
                            "$ref": "LocationOptions"
                        }
                    }
                },
                {
                    "Name": "CompanyName",
                    "Select": {
                        "Options": {
                            "$ref": "CompanyOptions"
                        },
                        "AllowEdit": false
                    }
                }
            ],
            "ReadOnly": [
                "StreetAddress",
                "PostalCode",
                "City",
                "Country"
            ]
        }
    }
}
```

Isto criará a seguinte interface de utilizador:

![Demonstração - ref-location](/files/717595c867fde31c038d5dfdaae7050099a19769)

![Demonstração - ref-address](/files/e4bdfb7b2cfc908c189034499e2393bf9c868b7d)

### Filtros de Graph

Pode preparar [Filtros de Graph ODATA](https://docs.microsoft.com/en-us/graph/query-parameters?context=graph%2Fapi%2F1.0\&view=graph-rest-1.0#filter-parameter) para serem usados em vários runbooks. Armazene-os numa seção chamada `GraphFilters`.

O exemplo a seguir filtra por um determinado prefixo no `DisplayName` nome de um grupo, para mostrar apenas grupos relacionados a licenciamento num seletor de grupos.

```json
"GraphFilters": {
    "LicenseGroup": "startswith(DisplayName, 'LIC_')" // também contido no código RJ como padrão
  }
```

Ver [Filtragem de Graph](#graph-filtering) sobre como usar isto num 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/pt/automacao/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.
