Custom scripts created by the user can be uploaded to the object store and then be applied as part of the runbook execution process. This can allow novel operations to be performed that may fall outside the scope of capabilities offered by the system.

    • Runbook scripts are saved in the Protected Domain's object store for safe keeping making them immediately available to the MSA at the recovery site.
    • Use of runbook scripts is entirely optional and not necessary unless specific, customized operation is required.
    • Runbook scripts are executed from the Management Server.
    • Runbook scripts can be written using PowerShell or Python3 language.
    • Three custom JetStream DR environment variables are provided to allow referencing other scripts/files or VM instance UUIDs.

Environment Variable

Description

JETDR_VM

The UUID of a protected VM configured by the post-script.

JETDR_VMS

A comma-separated list of the UUIDs of the protected VMs in a recovery group that has been configured with a pre-script or post-script.

JETDR_SCRIPT_PATH

The path to all runbook script(s)/file(s) for the Protected Domain.

How to Apply Runbook Scripts

Do this to add a script to a failover runbook.

    1. Navigate to: Protected Domains > Settings > Failover Runbook Settings. 
      • Click the Scripts button.

Figure 127: Click the Scripts button.

    1. Click the Upload button then select and upload a script file.

Note: Scripts should be written and formatted as PowerShell or Python3.

Figure 128: Upload a script file.

    1. The script will be saved to the Domain's object store from where runbooks can access it.

Figure 129: Script is saved to the object store of the Domain.

    1. During the runbook configuration process, select the uploaded script from the object store (per above step).

Figure 130: Select the script to use when configuring the runbook.


    1. Runbook scripts will be executed at the appropriate time during runbook operation (i.e., pre-script or post-script).

Runbook Script Example

The following example demonstrates the use of pre- and post- scripts to automate the assignment of VM tags as well as the use of the environment variable JETDR_SCRIPT_PATH to reference a separate .csv file containing the tag values.

Pre-script (assign_vm_tag.ps1)

#!/usr/bin/pwsh -c


Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $true -Confirm:$false


Set-PowerCLIConfiguration -InvalidCertificateAction:Ignore -Confirm:$false


$vcenter = "<vcenter_hostname/fqdn>"

$vcenter_user = "<vcenter_username>"

$vcenter_password = '<vcenter_password>'


# Connect to your vCenter server

Connect-VIServer -Server $vcenter -User $vcenter_user -Password $vcenter_password


# Define your tag and the path to your VM name list file

$TagName = "Test-Tag"

$VMNameList = @("fs171-rhel-10", "js-uks-alma9-12", "js-uks-alma9-6") # Replace with your actual VM names


# Get the tag object

$Tag = Get-Tag -Name $TagName


# Loop through all VM names and assign the tag

foreach ($VMName in $VMNameList) {

    $VM = Get-VM -Name $VMName

    if ($VM) {

        New-TagAssignment -Tag $Tag -Entity $VM

        Write-Host "Tag $TagName assigned to VM $VMName"

    } else {

        Write-Host "VM $VMName not found!"

    }

}


Post-script (assign_vm_tags_from_csv.ps1)

#!/usr/bin/pwsh -c


Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $true -Confirm:$false


Set-PowerCLIConfiguration -InvalidCertificateAction:Ignore -Confirm:$false


$vcenter = "<vcenter_hostname/fqdn>"

$vcenter_user = "<vcenter_username>"

$vcenter_password = '<vcenter_password>'


$CsvPath = Join-Path $PSScriptRoot "vm_tags.csv"

if ($args.Count -ge 1 -and $args[0]) {

    $CsvPath = $args[0]

}


if (-not (Test-Path -Path $CsvPath)) {

    Write-Host "CSV file not found: $CsvPath"

    exit 1

}


Connect-VIServer -Server $vcenter -User $vcenter_user -Password $vcenter_password


$rows = Import-Csv -Path $CsvPath

$tagCache = @{}


foreach ($row in $rows) {

    $VMName = "$($row.VMName)".Trim()

    $tagField = "$($row.TagName)".Trim()

    if (-not $VMName -or -not $tagField) {

        Write-Host "Skipping row with a missing VM name or tag."

        continue

    }


    $VM = Get-VM -Name $VMName -ErrorAction SilentlyContinue

    if (-not $VM) {

        Write-Host "VM $VMName not found!"

        continue

    }


    $tagNames = $tagField -split ';' | ForEach-Object { $_.Trim() } | Where-Object { $_ }

    foreach ($TagName in $tagNames) {

        if (-not $tagCache.ContainsKey($TagName)) {

            $tagCache[$TagName] = Get-Tag -Name $TagName -ErrorAction SilentlyContinue

        }

        $Tag = $tagCache[$TagName]

        if (-not $Tag) {

            Write-Host "Tag $TagName not found!"

            continue

        }


        $existing = Get-TagAssignment -Entity $VM -Tag $Tag -ErrorAction SilentlyContinue

        if ($existing) {

            Write-Host "Tag $TagName already assigned to VM $VMName"

            continue

        }


        New-TagAssignment -Tag $Tag -Entity $VM | Out-Null

        Write-Host "Tag $TagName assigned to VM $VMName"

    }

}


Disconnect-VIServer -Server $vcenter -Confirm:$false



CSV Table (vm_tags.csv)

1

VMName

TagName

2

fs171-rhel-10

Test-Tag

3

js-uks-alma9-12

Test-Tag

4

js-uks-alma9-6

Test-Tag



Upload files to the Object Store1

Figure 131: Upload scripts and associated files to the object store.

Note:

1. The presence of files referenced by a pre-script or post-script is not checked by the system. The user must ensure all referenced files are available in the object store.



Configure the Runbook
Select the pre- and post- scripts to use from the object store. In this particular example, the post-script references the file vm_tags_.csv so the environment variable JETDR_SCRIPT_PATH is specified as a post-script parameter.

Figure 132: Scripts and parameters can be applied when the runbook is configured.