PowerShell Ticketing Integration

Secret Server can integrate with your ticketing system via PowerShell. This integration includes validating ticket numbers, their status, and adding comments. In our example we are connecting to a ServiceNow instance.

Configurable Settings

View Ticket URL Template

You can configure the view ticket URL if you have a web based ticketing system to allow easy access to link to your ticketing system from Secret Server.

Ticket Number Validation Pattern (Regex)

Before making a call to the PowerShell script you can have Secret Server validate the number matches a pattern. For example, your incident numbers might all be prefixed with "INC" and you want to ensure they enter this prefix. See Ticket System Integration).

Ticket Number Validation Error Message

The error message to display to the user when their entered ticket number fails the validation pattern Regex.

The PowerShell RunAs Credentials

In Secret Sever a domain credential is required to execute the PowerShell script. This is a required field.

System Credentials

The system credentials are specific to your ticketing system. You can use any secret using the username and password extended mapping as your system credential. You can add other arguments in the secret's fields and reference them in your script.

Validating Ticket Status

Overview

To validate tickets you will need to create a PowerShell script to retrieve and validate the ticket. The integration will use arguments to pass custom values to your script. By default we will map certain fields to the first set of arguments. The ticket number will be collected by user input and assigned to the first parameter. When you have your ticketing system credentials mapped to a secret and assigned to the "System Credentials" field in the ticketing system setup, Secret Server inserts UserName and Password as the second and third parameters.

Therefore, for the sample script below, the Ticket Status Script Arguments text box should be only contain$url (which is also retrieved from the System Credentials secret), as $ticket, $user and $password are supplied automatically by the system.

Sample Script

Copy
$ticket = $args[0]
$user = $args[1]
$password = $args[2]
$url = $args[3]
$validStatus = "2"
$fields = "state"
$p = $password | ConvertTo-SecureString -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PsCredential($user,$p)
$getStatusMethod = "$url/api/now/table/incident?sysparm_limit=10&sysparm_query=number=$ticket&sysparm_display_value=&sysparm_fields=$fields"
$response = Invoke-RestMethod $getStatusMethod -Method Get -ContentType 'application/json' -Credential $credentials
if($response.result.state -ne $validStatus)
{
  throw "Invalid State"
}

Adding Comments to Tickets

To add a comment to tickets, create another script to do so. Example:

Copy
$ticket = $args[0]
$comment = $args[1]
$user = $args[2]
$password = $args[3]
$url = $args[4]
$p = $password | ConvertTo-SecureString -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PsCredential($user,$p)
$restEndpoint = "$url/api/now/table/incident?sysparm_limit=10&sysparm_query=number=$ticket&sysparm_display_value=&sysparm_fields=sys_id"
$response = Invoke-RestMethod $restEndpoint -Method Get -ContentType 'application/json' -Credential $credentials
$id = $response.result.sys_id
$updateObject = @{'work_notes'=$comment}
$body = $updateObject | ConvertTo-Json
$addComment = "$url/api/now/table/incident/$id"
$response = Invoke-RestMethod $addComment -Method Put -ContentType 'application/json' -Credential $credentials -Body $body

Adding Comments to a General Audit Log

In addition to adding comments to specific tickets, you may want general audit entries made in your ticket system. The arguments are passed in the following order.

Copy

$comment = $args[1]
$user = $args[2]
$password = $args[3]
## custom script here

Using $TEMPLATEARGS

$TEMPLATEARGS is used to pass dynamic arguments from the secret template to the ticketing system during integration. It is used to facilitate the transfer of specific field values required for ticket validation.

When setting up the template-specific arguments in the Secret Server UI, you should list the slug names without the $ symbol. For example, if you have a field with the slug machine, you would enter machine in the Ticket System Parameters field.

When referencing these arguments in the PowerShell script, you use them as variables, which requires the $ symbol. For example, $templateArgs in the script is used to capture the value passed from the Secret Server.

Example:

Copy
Ticket System Parameters: computername secretname
Ticket Integration Arguments: TEMPLATEARGS USERNAME SECRETSERVERDISPLAYNAME

Setting Up Ticket System Parameters

Define the parameters on the secret template that need to be passed to the ticket system.

Ensure slug names match exactly between the template and the ticket integration. Slug names are case-sensitive.

Example Configuration:

  • Template:

    • Field Name: Machine

    • Slug: machine

  • Ticket System Parameters: machine secretname

Example PowerShell Script:

Copy
# --- CONFIGURATION ---
$BasePath = "C:\temp\ServiceNow"
$LogDir = Join-Path $BasePath "Logs"
$SSPayloadPath = Join-Path $BasePath "SS_TicketValidation_Input.json"
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
$LogFile = Join-Path $LogDir "TicketValidation_$timestamp.log"

$ValidationUrl = "https://yourinstance.service-now.com/api/validatechange"

# --- FIELD MAPPINGS ---
$ValidationFields = @{
"System Value" = "changeContainsCI"
"Change Status" = "isChangeinImplement"
"User" = "isMember"
"Secret Value" = "matchRequestedCredentials"
"Change Time Window" = "withinImplementationWindow"
}

# --- ARGUMENTS ---
if ($args.Count -lt 6) {
throw "Ticket Validation Failed: Missing arguments. Expected 6 total."
}

$ticket = $args[0].Trim()
$SNUser = $args[1].Trim()
$SNPass = $args[2].Trim()
$templateArgs = $args[3].Trim() # This is where TEMPLATEARGS is used
$username = $args[4].Trim()
$requestedBy = $args[5].Trim()

# --- LOGGING FUNCTION ---
function Write-Log {
param ([string]$Message, [string]$Level = "INFO")
$ts = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$entry = "[$ts][$Level] $Message"
Add-Content -Path $LogFile -Value $entry
}

# --- BUILD PAYLOAD ---
$payload = @{
change_number = $ticket
cmdb_ci = $templateArgs # Using TEMPLATEARGS to pass the computer name or other values
credentials_requested = $username
userid = $requestedBy
}

$payloadJson = $payload | ConvertTo-Json -Depth 3

# --- SEND POST TO SERVICENOW ---
try {
$response = Invoke-RestMethod -Uri $ValidationUrl -Method Post -Body $payloadJson
Write-Log "Received SN response: $(ConvertTo-Json $response -Depth 5)" "DEBUG"
} catch {
Write-Log "SN request failed - $_" "ERROR"
throw "Ticket Validation Failed: Unable to contact ServiceNow."
}

# --- VALIDATION LOGIC ---
$failures = @()

foreach ($label in $ValidationFields.Keys) {
$field = $ValidationFields[$label]
$value = $response.result.$field

if (-not $value) {
$reason = $FailureReasons[$label]
$failures += "$label - $reason"
Write-Log "Validation failed: $label => $reason" "ERROR"
} else {
Write-Log "Validation passed: $label ($field)" "DEBUG"
}
}

if ($failures.Count -gt 0) {
$errorMessage = "Ticket Validation Failed: $($failures -join '; ')"
Write-Log $errorMessage "ERROR"
throw $errorMessage
}

Write-Log "Ticket Validation Passed"
$templateArgs variable is used to capture the value passed from the secret template using $TEMPLATEARGS. It is intended to pass values like the computer name or other relevant fields from the secret template to the ticket system.

Approval vs. Comment Issue

Known Issue: When using approval workflows, $TEMPLATEARGS may not process correctly, resulting in the output of $TEMPLATEARGS instead of the expected values.

Workaround: Ensure comments are turned on for the arguments to output correctly.