Runbook Customization
Adapt RealmJoin's generic runbooks to your environments' needs.
Last updated
Adapt RealmJoin's generic runbooks to your environments' needs.
Last updated
The RealmJoin runbook implementation offers customizing capabilities to a runbook's author or an environments' administrator, so that they can:
Host customer/tenant specific parameters and templates
Offer UI elements like user-pickers or dropdown selections
Present human readable explanations of parameters
Hide unneeded UI elements
The customizations can be included in the runbook itself and/or stored in the customer's RealmJoin Portal instance. By default, we will try to offer sensible defaults in the runbooks offered on GitHub.
Some runbooks will come with examples of how to configure customer specific templates like specifying office locations for the user on-boarding.
The customizing can be defined (in descending order of priority)
Block of JSON in RealmJoin Portal settings, overriding default runbook behavior
Block of JSON in the header of a runbook
Additionally (with least priority)
per parameter in the runbook header
per parameter in the runbooks param block (using the RJRb Helper Module)
Some functionality (like templates) is only available in JSON format. Some functionality (like creating a user picker) is only available by specifying a data type in the param block. You can combine multiple types of customizations for best results.
The RealmJoin Portal parses a runbook's PowerShell param block to determine which input fields to render. Where possible, it will also validate the inputs according to the .NET type given for a variable.
The following data types are currently understood:
[bool]
, [boolean]
- will present a binary toggle
[string]
- will present a textbox to type any alphanumeric input
[int]
- will present a textbox, only allowing numeric inputs
[DateTime]
, [DateTimeOffset]
- Will present a date/time picker
You can apply standard PowerShell modifiers to parameters. RealmJoin Portal, in particullar, will understand if you specify [Parameter(Mandatory = $true)]
to indicate a mandatory parameter and enforce these parameters being filled.
Where possible, RealmJoin Portal will also read and present given default values in the UI.
Be aware, default values from the runbook can be overridden by customizations. Additionally, parameters can be completely hidden by customizations.
To be able to customize parameters, please make sure to include RealmJoin's Runbook Helper PS Module in your runbook:
#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.6.0" }
You can then include [ValidateScript( { Use-RJInterface ... } )]
statements in the parameter definitions. For example the following will create a user picker, allowing to choose an Entra ID user and will pass its object id as string to the runbook.
Let's take this piece by piece. [ValidateScript...]
is a modifier to the next parameter defined in the param-block. In this case the variable $AssignedUserId
.
Use-RJInterface
is part of our RealmJoin Runbook Helper PowerShell Module. It allows you to specify what kind of input you expect using -Type
and -Entity
, if that is not already fully defined by the type of variable.
-DisplayName
allows you to pass a human readable prompt / description for this parameter to RealmJoin Portal.
In the example above, the source of information is MS Graph, as described by -Type Graph
. For MS Graph, use -Entity
to specify which kind of resource you're expecting. Available entities are User
, Group
, Device
. This will produce a picker for either users, groups or devices in the given Entra ID.
The picker includes a quick search, to easily pin down the required resource.
Currently, no multiselect is possible using a picker.
By default, a MS Graph picker will return the object's ID. If you require e.g. the user principal name instead, make sure to include "name" as suffix in your variable's name. So, basically, to get a user's id, name the parameter $userid
. If you want a UPN, name it $username
.
If you are using a MS Graph based picker, you can also specify -Filter
and use an ODATA-Filter to limit the objects offered in the picker.
The following example will list only groups from Entra ID starting with "LIC_".
You can prepare filters and reuse them across multiple scripts using the central datastore. In this case just reference the filter by name using -Filter "ref:LicenseGroup"
, where ref:
indicates to look for a stored filter.
This specific example ref:LicenseGroup
is available by default without further configuration.
The Portal can parse a runbook's comment based help section, if present.
Here is an example:
.SYNOPSIS
- Give a very brief description of your runbook's function. This will be displayed in the list of available runbooks.
.DESCRIPTION
- Give a description of your runbook's function. Can contain slightly more detail, as this will be displayed inside the runbooks execution / parameter dialogue.
.PARAMETER
- Needs to be followed by a parameter's name. Allows you to give a detailed explanation of the expected input for the parameter in question.
.INPUTS
- Can contain a block of JSON-based Runbook Customization.
.NOTES
- Is not parsed / rendered. Please use this space to write down which permissions and requirements exist for your runbook.
.EXAMPLE
- Is not parsed / rendered. Can contain an example of a JSON-based Customization to use in the RealmJoin Datastore in your tenant. These can be examples of how to create templates e.g. for different workflows or user classes.
Each Azure tenant can host a "Runbook Customizations" datastore, found at https://portal.realmjoin.com/settings/runbooks-customizations .
The format is JSON with comments, allowing trailing commas. Currently, there are three relevant sections, Settings
, Templates
, Runbooks
.
Runbooks
is parsed by the portal when starting a runbook. If a section named like the current Azure Automation Runbook exists, its contents will be used to customize the frontend displayed to the user.
Assume the following simple demonstration runbook, called rjgit-device_demo-runbook-customizing
.
If not customized, it will be presented like this in the frontend:
Thoughts:
As this runbook is started from a device's context in portal, the $DeviceId
is redundant information for a user. I already know which device I am working on.
What happens if I enable or disable the "Extra Workflow"? Do I need to think about "Extra Workflow Time" if I disable "Extra Workflow"?
Let us improve on that. The following example JSON in the central datastore will modify the UI for the runbook.
You can use the same notation / features in your runbook header.
Each parameter has its own section in ParameterList
. Modifiers allow to change the behaviour of that parameter.
The result will look like this:
Choosing the additional workflow will present (unhide) more parameters:
This shows less clutter in comparison to before applying the customization. At the same time more information about the alternatives of "Extra Workflow" is available to the user. Also, a user now will only worry about "Extra Workflow Time" if it is relevant.
Changing the visibility of that field was done using a "Customization"
block inside one of the "Select"
options. You can currently have at most one such "Customization"
block active at a time.
As you can see, the parameter $DeviceId
is completely hidden. This is done by setting the "Hide": true
for this parameter.
Parameters can have a DisplayName
. We offered a human friendly DisplayName
to replace $ExtraWorkflowTime
in the UI. See other modifiers for more.
You can insert "unnamed" parameters (missing the Name
statement) like the "Execute Extra Workflow" section, if you want to offer UI elements without directly returning a value. This is normally only used in conjunction with Select
.
We used Select
, to display a list of Options
in a dropdown. Each option can Display
text, or trigger a Customization
, like setting Hide
or a Default
value on other parameters. In our example, we used it to (un)hide $ExtraWorkflowTime
and override $ExtraWorkflow
's value.
$ExtraWorkflowTime
is thus only shown when relevant and the binary switch $ExtraWorkflow
is now replaced with meaningful alternatives from a user's perspective.
In case of a Select
for a named parameter, each option should have a "ParameterValue": "..."
to pass to the runbook. You can place a "ShowValue: false"
inside the Select
block to only show the dropdown and not a field for the resulting parameters value.
Named parameter example:
The Default
/ DefaultValue
statement in the parameter also specifies the initial state of the dropdown. In case of an unnamed parameter, use the DisplayName
of the desired option, otherwise give a default return value, like "true" or "false" or some string.
If you only have named parameters, you can use the slightly shorter Parameters
format instead of ParameterList
.
For an example see SelectSimple
If the full power of a Select
is not needed and you just want to offer a list of possible values in a dropdown (without applying additional customizing), you can use SelectSimple
.
SelectSimple
is only usable for named parameters.
Example:
The biggest difference (other than being much shorter) to our example before is that $ExtraWorkflowTime
is always visible.
Each parameter can have one or more of the following modifiers:
"DisplayName": "text"
- Display "text" as name for the parameter in the UI
"Hide": true / false
- Hide this parameter
"Mandatory": true / false
- Require this parameter to be filled
"ReadOnly": true / false
- Protect this parameter from beeing changed from its default value
"DefaultValue": "..."
- Set a default value for this parameter. (You can also use Default
instead.)
"GraphFilter": "startswith(DisplayName, 'LIC_')"
- see Graph Filtering
"AllowEdit": true / false
- Protect this parameter from manual editing. (combine this with templates)
Settings
allows you to store configuration data like Azure Storage Account names in a central place, while still keeping them separate from your runbooks.
You can access individual values from a runbooks param-Block using Use-RJInterface
.
Let us take this example param-block of a runbook:
Portal will try to prefill each parameter with values from the central datastore - if present. This also works if the parameter has been hidden in the UI.
A possible JSON in the datastore for this runbook would be:
The missing Container
element will simply not be prefilled in the UI.
Templates
use JSON-references to pull in data - for example a lengthy list of office locations - when using a Select
statement.
This allows to keep a customization neutral/reusable/separated from actual data.
Let us take the example of onboarding new users. You might have have multiple given options for departments or office locations, where assigning an office location also mandates a certain street address, country, state etc.
The following example of a runbook customization uses the $ref
inside the Runbooks
section to reference/import a subtree from the Templates
section. Look out for the $id
/$values
keywords. Be aware that $id
/$values
have to defined before referencing them using $ref
. That is why Templates
is defined ahead of Runbooks
in this example.
In this example we tell the portal to grab the subtree with the $id
called LocationOptions
and include its $values
, replacing the $ref
statement. So, the portal will render a Select
as described in the Runbooks
section but include the actual options from Templates
.
A template can contain any statement that is supported in the referencing location. In this example, we use a Customization
statement to modify other parameters like StreetAddress
.
So, we can have a runbook specific customziation in Runbooks
reusable accross multiple environments, while keeping actual data separate.
This will create the following UI:
You can prepare ODATA Graph-Filters to be used in multiple runbooks. Store these in a section called GraphFilters
.
The following example filters for a certain prefix in the DisplayName
of a group, to only show licensing related groups in a group picker.
See Graph filtering on how to use this from a runbook.