Authoring RPS Runbooks
Last updated on January 13, 2021.
Last Reviewed and Approved on PENDING REVIEW
RPS is the Rapid Provisioning System. Runbooks are PowerShell scripts and workflows that RPS will execute with Task Management Service (TMS).
RPS Runbooks are PowerShell runbooks designed to run within the context of RPS. In general, RPS runbooks provide concise, reusable functionality, and use the Rps-Api PowerShell module to access and update the RPS Configuration Management Database (CMDB) data.
The terms "Runbook", "Workflow," and "Task Item" are all used interchangeably within RPS to refer to an RPS runbook. The assignment of a single runbook to a Computer or Target for execution is called a Task Assignment, which is executed as one job in TMS. The Task Assignment is the smallest unit of work in RPS, and its status is tracked in the RPS CMDB.
Glossary
The following are common terms used within RPS, Runbooks, and Task Automation.
Term | Definition |
---|---|
CMDB | RPS [Configuration Management] Database. |
Map Assignment | The assignment of a task map to a target and its descendants. The result is a set of Task Assignments that together make up a complex orchestration. |
RPS | Rapid Provisioning System. |
Rps-Api | PowerShell Module used to access and manipulate RPS configuration and task data. |
Runbook | PowerShell script which runs a simple task, usually run in TMS. |
Step | Identify a single step within a Task Map. |
Target Item | A device which is the target of a Task Item or Task Map. |
Task Assignment | Assignment of a Task Item to a target. Corresponds to a single job in TMS. |
Task Item | Identifies a task (runbook). |
TMS | Task Management Service - hosts & runs runbooks, used by RPS. |
Task Map | Identifies a set of steps, what order they should be performed in, and what target items those steps apply to. |
Task Assignment States
The following table defines the Task Assignment states used by RPS. Within PowerShell, the available states can be accessed via the $Rps.TaskStates
variable.
Term | Definition |
---|---|
Assigned | Task Assignment is created. When TMS creates a job, Sync builds a new Task Assignment. |
Canceled | Task Assignment was stopped, either from TMS or manually, and processing of Orchestration may stop. |
Completed | Task Assignment is complete, and processing of other Task Assignments in the Orchestration will continue. |
ErrorContinue | Task Assignment encountered an error, but processing of Orchestration will continue. |
ErrorStop | Task Assignment failed and processing of Orchestration should stop. |
None | Internal system default; the task state has not been set. |
NotReady | Task Assignment is new or is waiting on other jobs to complete, and not ready to be executed. |
PendingUserAction | Task Assignment requires user approval before Orchestration can continue. See User Approvals section. |
Ready | Task Assignment is ready to be started, and will be started by TMS. |
Removed | Task Assignment contains a target that is being deleted. |
Retry | Task Assignment should be retried due to a failure. See Retry section. |
Running | Task Assignment was started as a job in TMS (or Direct) and is currently executing. |
Hosting Runbooks in TMS vs. Direct Execution
A full instance of RPS (RPS Node) includes the CMDB as a SQL database and an instance of TMS to host and execute RPS runbooks.
With RPS, some of the functionality that TMS uses is exposed directly via the Rps-Api module, so that Task Assignments and Task Map Assignments (Orchestrations) can be executed directly in PowerShell. This is useful for an initial RPS Install process, where TMS may not be available. It also helps for developing, testing, and troubleshooting runbooks. See documentation around the Invoke-RpsTaskAssignment
and Invoke-RpsTaskMapAssignment
cmdlets for more information.
RPS Runbook Guidance
The following are the three primary guidelines for authoring RPS Runbooks:
Runbooks are PowerShell scripts saved as
.ps1
files in the\Runbooks
folder by default, using the Verb-Noun naming convention.Note
The Runbooks folder location is user changeable. The current Runbook folder location can be determined with the following PowerShell snippet:
Get-RpsStorageValue -Key "DefaultRunbookFolder"
- Runbooks contain a single mandatory parameter,
[guid] $TaskAssignmentId
, to identify the Task Assignment. - Runbooks use the Rps-Api to access and update CMDB data, log important information, and update Task Assignment State.
Example Runbook
The following example is a simplified version of the Wait-Random.ps1
runbook, which can be used for guidance as well as sample task execution.
<# ... #>
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.Guid]
$TaskAssignmentId
)
#Requires -Modules Rps-Api
# Load Task Assignment and Target Item
$taskAssignment = Get-RpsTaskAssignment -Id $TaskAssignmentId
$workflowName = $taskAssignment.TaskItem.WorkflowName
if (-not $taskAssignment)
{
Write-RpsLogItem @LogError -MessageTemplate $LoggingEvents.TaskAssignmentNotFound -Properties ($TaskAssignmentId, $workflowName)
throw "Task Assignment not loaded properly."
}
$targetItem = $taskAssignment.TargetItem
Write-RpsLogItem @LogInformation -MessageTemplate $LoggingEvents.StartingRunbook -Properties $workflowName, $TaskAssignmentId
Update-RpsTaskAssignment -TaskAssignment $taskAssignment -TaskState $Rps.TaskStates.Running -StatusMessage "$workflowName is running on $($targetItem.Name)"
# Generate a random sleep time from 1-5 sec
$wait = Get-Random -Min 1 -Max 5
$waitMessage = 'Assignment: {TaskAssignmentId} on {TargetItem} waiting for {Wait} sec'
$logProps = @($TaskAssignmentId, $targetItem.Name, $wait)
Write-RpsLogItem -Level Information -Component Master -MessageTemplate $waitMessage -Properties $logProps
# Sleep
Start-Sleep -s $wait
Update-RpsTaskAssignment -TaskAssignment $taskAssignment -TaskState $Rps.TaskStates.Completed -StatusMessage "Completed"
Updating Task Assignment State from a Runbook
To reduce boilerplate code, RPS will manage the Task Assignment's state as follows:
- When a Task Assignment is started (via TMS or Direct), its
TaskState
is automatically set to Running. - When a Task Assignment is completed (via TMS or Direct), and its
TaskState
is Running, theTaskState
is automatically set to Completed. - When a Task Assignment fails (via TMS or Direct), and its
TaskState
is Running, theTaskState
is automatically set to ErrorStop.
In the example runbook, notice that the TaskState
is never updated to Running or Completed.
To set the state manually, for error handling or a custom workflow, use the Update-RpsTaskAssignment
cmdlet and the common Task States listed above.
Example: Manually set State
This example manually sets the State to ErrorContinue if an error occurs in the try
block:
try
{
# do work here
}
catch
{
# catch error but allow orchestration to continue
# additional logging or error handling here
Update-RpsTaskAssignment -TaskAssignment $taskAssignment -TaskState $Rps.TaskStates.ErrorContinue -Message 'An error occurred in non-critical process.'
}
Logging from a Runbook
RPS supports structured logging via the Write-RpsLogItem
cmdlet. See the Rps-Api documentation for full description and examples.
For RPS Runbooks, it's important to understand how to associate information to the Task Assignment for diagnostics or telemetry.
To associate log data with an executing Task Assignment, you must supply a formatted message template with named replacement tokens and the Task Assignment's Id.
Example: Logging Information to the Task Assignment
This example, from the Wait-Random
runbook, shows how to properly log information to a Task Assignment from a runbook. Notice the template is a string with replacement tokens and the properties are simply an object array to associate to the tokens in the template.
# Generate a random sleep time from 1-5 sec
$wait = Get-Random -Min 1 -Max 5
$waitMessage = 'Assignment: {TaskAssignmentId} on {TargetItem} waiting for {Wait} sec'
$logProps = @($TaskAssignmentId, $target.Name, $wait)
Write-RpsLogItem -Level Information -MessageTemplate $waitMessage -Properties $logProps
Advanced Runbook Guidance
- Establishing a secure connection to a remote computer
- Scheduled/Recurring Task Assignments
- Retrying Task Assignments
- Require User Approval
- Additional Parameters
Connect to Target Computer
Many Runbooks will need to connect to the Target (Computer) to perform their duty. To connect, you must get the appropriate credential and then establish a secure connection.
In RPS Runbooks, use the Get-RpsCredential
to load the right credential for the target. Then use New-SecureSession
from Rps-Api to make the connection.
#Requires -Modules Rps-Api
# Load assignment and target
$assignment = Get-RpsTaskAssignment -Id $TaskAssignmentId
$target = $assignment.TargetItem
try
{
# Retrieve LocalAdmin credentials for target computer
$localAdmin = Get-RpsCredential -TargetItem $target -Role 'LocalAdmin'
# Establish connection to target
$session = New-SecureSession -IPAddress $target.IPAddress -Type PsSession -Credential $localAdmin -OSType $target.OSType
# Do work on target
}
finally
{
if ($session)
{
# Clean up connection
Remove-PSSession -Session $session
}
}
Scheduled / Recurring Task Assignments
RPS supports scheduling of Task Assignments and Map Assignments. See the RPS Tasking Guide for examples of scheduling new Map Assignments and Task Assignments.
To have a Task Assignment repeat or recur, manually adjust the StartDate
and set TaskState
to Ready and RPS will run the Task Assignment again.
Caution
To prevent TMS from inadvertently completing a recurring task, make sure to clear the PhyrJobId when resetting the state.
Example: Set Task Assignment to Recur every 15 minutes
Use the following code in a runbook to have the Task Assignment recur:
Tip
To set a limit on execution counts, add a custom property to the TaskAssignment and logic to update it after each run.
$taskAssignment.StartDate = (Get-Date).AddMinutes(15)
$taskAssignment.TaskState = $Rps.TaskStates.Ready
$taskAssignment.PhyrJobGuid = $null
Update-RpsTaskAssignment $taskAssignment
Retry Failed Task Assignments
RPS considers the Retry state similar to Ready. The only difference is that Retry indicates that the Task Assignment failed and is executing again, instead of running for the first time.
Starting with RPS v2.3.2 there is limited support for automatic retries, which was added to support some RPS Install features. To use an automatic retry, set a RetryCount
property on the Task Assignment. If the Task Assignment fails, RPS will automatically retry it and decrement the RetryCount
until all retries have been attempted.
This behavior can be simulated in runbooks and may be promoted to a built-in feature in RPS and TMS in a future release. This would also include a RetryCount
option in the UI or PowerShell when designing a Task Map.
Example: Setting RetryCount property on Task Assignment
# Remove -TaskMap parameter to get array of all assignments of $taskItem to $targetItem
$taskAssignment = Get-RpsTaskAssignment -TaskItem $taskItem -TargetItem $targetItem -TaskMap $taskMap
$taskAssignment.RetryCount = 5
Update-RpsTaskAssignment -TaskAssignment $taskAssignment
Example: Use RetryCount to limit failures
Place the following sample code into the error handling section of a runbook to implement a limited # of retries. This will only retry a TaskAssignment that already has the RetryCount
set.
$retryCount = [Rps.Api.Utils.Extensions]::GetProperty($TaskAssignment, 'RetryCount', 0)
if ($retryCount -gt 0)
{
$TaskAssignment.RetryCount = $retryCount - 1
Update-RpsTaskAssignment -TaskAssignment $TaskAssignment -TaskState $Rps.TaskStates.Retry -StatusMessage 'Retry from Invoke-RpsTaskAssignment'
}
else
{
throw "Error on $($computer.Name) in $runbookName. Error: $($TaskAssignment.StatusMessage)"
}
Require User Approval
Some Tasks may require manual user approval to continue or stop processing. This approval step requires setting the Task Assignment’s state to PendingUserAction and setting a prompt for the operator. The operator then approves or denies the action using RPS Web or PowerShell. If approved, the Task’s State will be set to Completed. If denied, the state is set to Canceled.
Example: Update Task Assignment for User Approval
Setting the required approval using the New-RpsTaskAssignmentUserAction cmdlet will create a prompt for the user in RPS Web.
New-RpsTaskAssignmentUserAction -TaskAssignment $taskAssignment `
-UserActionPrompt 'Approve Domain Join?' `
-UserActionApproveLabel 'Approve' `
-UserActionDenyLabel 'Deny'
Additional Parameters
Most runbooks will need more information than just the provided TaskAssignmentID. These runbooks can use ItemMapping attributes such as ResourceItemMapping. When the runbook is executed by TMS these parameters will be resolved and the correct values will be passed in for each parameter. See How to Configure RPS-Mapped Parameters for more information about ItemMapping attributes.
Example: Multiple Parameters in a Runbook
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[System.Guid]
$TaskAssignmentId,
[Parameter(Mandatory = $true)]
[ResourceItemMapping(EntityType = [ResourceTypes]::Credential, Role = 'DomainAdmin')]
[pscredential]
$DomainAdminCredential,
[Parameter(Mandatory = $true)]
[ResourceItemMapping(EntityType = [ResourceTypes]::SoftwareLicense, Role = 'OfficeActivation')]
[Hashtable]
$OfficeLicense
)
#Requires -Modules Rps-Api
Legacy Runbooks (Workflows) Guidance
Prior to RPS v2.1, all RPS Runbooks were authored as PowerShell workflows instead of pure PowerShell scripts. Some RPS Runbooks are still Workflows, and they require special guidance.
PSDisableSerializationPreference
PowerShell Workflows, and by inheritance TMS Runbooks, serialize objects without methods. This can limit the usability of some RPS objects' method calls. To use these methods, the PSDisableSerializationPreference needs to be set to true.
$PSDisableSerializationPreference = $true
Workflow Naming
As a matter of consistency and support for the DSC resource managing RPS, the Workflow name must match the script name.
Registering Runbooks in RPS
Runbooks in the /Runbooks
folder are automatically imported into RPS during install, via the /Setup/Configuration/Import-RpsTasks.ps1
script. Once a full RPS Node is operational and TMS is running, any new or modified scripts in the runbooks folder will be automatically registered and imported into RPS and TMS, using DSC as the folder monitor.
Note
Runbooks are automatically available to TMS once they are in the Runbook Folder and a corresponding TaskItem is created.
Example:
# Create TaskItem for runbook Wait-TargetReady.ps1
New-RpsTaskItem -WorkflowName "Wait-TargetReady"