Scheduled SailPoint IdentityIQ Workflow Execution Using PowerShell

Problem Statement

In certain scenarios, there might be a need to -

  • Extend existing PS (PowerShell) Scripts to leverage and pass several inputs to SailPoint IIQ WFs (Workflows), handle the response, and (if required) run it periodically.
    These might be scripts related to existing operations which need to gather data from SailPoint IIQ or trigger a provisioning operation to perform further processing.

  • Call a SailPoint IIQ WF through a PS Script and run it periodically.
    Similar to the above scenario, these might be new scripts which need to gather data from SailPoint IIQ or trigger a provisioning operation to perform further processing.

  • Test the IIQ WF using PowerShell in the absence of tools like Postman.
    In a highly controlled Windows environment wherein third-party tool download is not allowed, PowerShell can be used to trigger API calls.

Solution

The following steps can be used to solve these scenarios -

Create an API client

Using an admin account in IIQ , create an API client using Global Settings → API Authentication. E.g.

Create/Extend a PowerShell script to launch an IIQ WF

The example script below performs the following actions:

  • Makes an OAuth 2.0 connection with an IIQ instance.
  • Converts the inputs required by the workflow in JSON format
  • Launches the workflow by calling the LaunchesWorkflow API endpoint for IIQ and passing all the inputs.
  • Stores the workflow output in a variable which can be used for further processing.
#replace your clientID and secret
$clientID = 'xxxxxxxxxxxxxxxxxxx'
$secret = 'xxxxxxxxxxxxxxxxxx'
$credential = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($clientID + ":" + $secret))


$splat = @{
Method = 'POST'
#replace hostname and port
uri = 'https://<iiq hostname or VIP>:<port>/identityiq/oauth2/token'
ContentType = 'application/x-www-form-urlencoded'
Body = 'grant_type=client_credentials'
Headers = @{Authorization = $credential}
UseBasicParsing = $true
}


$result = Invoke-WebRequest @splat
$resultJSON = ConvertFrom-Json $result.Content
$tokenBearer = $resultJSON.token_type
$token = $resultJSON.access_token
$headers = @{ Authorization = "Bearer $token"}


$jsonBase1 = @{}
$list = New-Object System.Collections.ArrayList
$list = "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow","urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult"
$jsonBase1.Add("schemas", $list)


#Inputs to be passed. Replace the inputs with the inputs your WF expects
$requestNo = @{"key"="requestNo";"value"="123456"}
$requestDescription = @{"key"="requestDescription";"value"="Test Demo"}
$sunsetTime = @{"key"="sunsetTime";"value"="24"}
$workstation = @{"key"="workstation";"value"="XYZ123"}
$sAMAccountName = @{"key"="sAMAccountName";"value"="pathaka"}


$list2 = New-Object System.Collections.ArrayList
$list2 = $requestNo, $requestDescription, $sunsetTime, $workstation, $sAMAccountName
#replace the WorkflowName with the name of your workflow
$launchWorkflow = @{"workflowName"="test_Aditya";"input"=$list2}


$jsonBase1.Add("urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow", $launchWorkflow)
$jsonPayLoad = $jsonBase1 | ConvertTo-Json -Depth 10


$result2 = ''
#replace hostname and port
$uri2 = "https://<iiq hostname or VIP>:<port>/identityiq/scim/v2/LaunchedWorkflows"
$result2 = Invoke-RestMethod -Headers $headers -Uri $uri2 -Body $jsonPayLoad -Method Post
$result2.id
$result2.messages
$result2.attributes

The same PowerShell script can be amended to call any IIQ API endpoint with required tweaks to inputs based on the API endpoint.

The workflow at the receiving end in IdentityIQ should be able to accept the incoming inputs (here requestNo, requestDescription, sunsetTime, workstation, sAMAccountName - For this example these attributes are used to drive sunset provisioning in IdentityIQ for workstation AD group corresponding to a sAMAccountName) from the powershell script and send an appropriate output ( here tcResult and tcResultMsg represent the task result in IIQ and the task result message). Here is a template of the workflow at receiving end-

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Workflow PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Workflow explicitTransitions="true" libraries="IdentityRequest,Identity" name="test_Aditya" type="">
  <Variable input="true" name="requestNo"/>
  <Variable input="true" name="requestDescription"/>
  <Variable input="true" name="sunsetTime"/>
   <Variable input="true" name="workstation"/>
  <Variable input="true" name="sAMAccountName"/>
 <Variable name="tcResultMsg" output="true"/>
  <Variable name="tcResult" output="true"/>
<Step icon="Start" name="Start" posX="10" posY="0">
    <Script>
      <Source>
       // Do something based on incoming value and send output. Here tcResult and tcResultMsg represent the task result in IIQ and the task result message which are workflow outputs that need to be sent back to calling PowerShell script
</Source>
    </Script>
    <Transition to="Stop"/>
  </Step>
    <Step icon="Stop" name="Stop" posX="20" posY="0"/>
</Workflow>

In this scenario, the $result2 variable in the PowerShell script will store the tcResult and tcResultMsg coming from the IIQ Workflow and if required can be used to drive further processing in powershell script or complete the script.

Schedule the PowerShell script

This step is not required if you are only testing the IIQ WF using PowerShell in the absence of tools like Postman.

Use schtasks to create a scheduled task on Windows server to periodically run this PowerShell script.

The following command creates a task named “Run_Test_Script” that will run the example PowerShell script daily at 10:15 AM.

C:\windows\system32>schtasks.exe /create /tn "Run_Test_Script" /tr "powershell.exe -file 'c:\Test_WorkFlow_run.ps1'" /sc daily /st 10:15

Additional options such as /ru and /rp can be configured to run as specific user (ru) and password (rp).

This query can be used to view the created task.

C:\windows\system32>schtasks.exe /query /tn "Run_Test_Script"

Further details on scheduled tasks can be found at schtasks commands | Microsoft Learn

1 Like

I didn’t get the reason for doing this. Can you please elaborate what you want to achieve by this.
Food for thought.
Can’t we launch the workflow from Rule and have a rule runner task and schedule the task?

Maybe you missed problem statement part of the blog?