Writing a Script
IQService divides scripts in the following categories:
This guide provides the following sample before scripts:
Scripts with Object Oriented Support
Scripting languages with Object Oriented capabilities (for example, PowerShell) are popular because of their simplistic nature and easy to use. These scripts can form objects of any type by referring any library/assembly implemented in any language and call its methods.
Native scripts implemented in these languages have easier and more powerful access to request and result objects. IQService comes with a class library named Utils.dll which bundles all required classes to access the request and result objects. The inputs provided to the script would be in the form of process environment variables. The following table describes the environment variables created by IQService:
Name |
Type |
Before Script |
After Script |
---|---|---|---|
Application |
System.Collections.Hashtable |
Read Only |
Read Only |
Request |
SailPoint.Utils.objects.AccountRequest |
Read/Write |
Read Only |
Result |
SailPoint.Utils.objects.ServiceResult |
Not Available |
Read/Write |
The data in the environment variables is in XML. The script creates respective objects using Utils.dll. Once the object is modified, the script should convert it to XML by calling toxml() method of the object and write the xml to a file at the path that is passed as the only argument to the script. The script returns non-zero value in case of error and writes the error message in the file at the path that is passed as the argument to the script. This failure is communicated to IdentityIQ as part of result.
Sample PowerShell Before Scripts
-
The following is a sample PowerShell before script that modifies the value of an attribute and adds one new attribute to the request:
Copy# Refer to SailPoint class library Requires PowerShell v2 installed on the system.
Add-type -path utils.dll
# Read the environment variables
$sReader = New-Object System.IO.StringReader([System.String]$env:Request);
# Form the xml reader object
$xmlReader = [System.xml.XmlTextReader]([SailPoint.Utils.xml.XmlUtil]::getReader($sReader));
# Create SailPoint Request object
$requestObject = New-Object SailPoint.Utils.objects.AccountRequest($xmlReader);
# Loop through the attributes from the request for each ($attribute in $requestObject.AttributeRequests){
if($attribute.Name -eq "description"){
$attribute.value = "my description"; #change value of the attribute
}
}
# Add a new attribute to request
$attributeObject = New-Object SailPoint.Utils.objects.AttributeRequest;
$attributeObject.Name = "otherMobile";
$otherMobileValues = New-Object System.Collections.ArrayList;
$otherMobileValues.Add("222-292-2929");
$otherMobileValues.Add("333-292-2929");
$attributeObject.Value= $otherMobileValues;
$attributeObject.Operation = "Set";
$requestObject.AttributeRequests.Add($attributeObject);
# Write the request xml to file at the path passed as argument
$requestObject.toxml()|out-file $args[0]; -
The following before script demonstrates how to read
AccountRequest
metadata (additional attributes passed with Account request/objectRequest object).The before/after script requires additional information to determine execution flow of the script that cannot be passed as
AttributeRequest
obejct because the out-of-the-box connector is not able to provision those attributes. Therefore attributes that are only used in scripts, must be sent as a metadata (Attributes) ofAccountRequest
instead ofAttributeRequests
.The following example of the
AccountRequest
xml displays how to pass this metadata in the request. In the following example thecountry
,city
, andjobTitlepassing
attributes are passed as metadata:Copy<ProvisioningPlan nativeIdentity="TESTDOMAIN\User100" targetIntegration="AD">
<AccountRequest application="AD" nativeIdentity="CN=User100,CN=Users,DC=TESTDOMAIN,DC=LOCAL" op="Enable">
<Attributes>
<Map>
<entry key="flow" value="AccountsRequest"/>
<entry key="interface" value="LCM"/>
<entry key="operation" value="Enable"/>
<entry key="provisioningPolicies">
<value>
<List>
<String>ChangePassword</String>
</List>
</value>
</entry>
<entry key="country" value="US" />
<entry key="city" value="Austin"/>
<entry key="jobTitle" value="Sr Manager" />
</Map>
</Attributes>
<AttributeRequest name="displayName" op="Add" value="SailorX"/>
</AccountRequest>
</ProvisioningPlan> -
The following
connectorBeforeModify
script demonstrates how to readAccountRequest
arguments:Add-type -path "C:\Program Files\SailPoint\IQService\utils.dll"
Copy# Read the environment variables
$sReader = New-Object System.IO.StringReader([System.String]$env:Request);
# Form the xml reader object
$xmlReader = [System.xml.XmlTextReader]([SailPoint.Utils.xml.XmlUtil]::getReader($sReader));
# Create SailPoint Request object
$requestObject = New-Object SailPoint.Utils.objects.AccountRequest($xmlReader);
# Read NativeIdentity of the AccountRequest
$nativeIdentity = $($requestObject.NativeIdentity)
# Get all attributes from the request
$attributesMap = $requestObject.Attributes
# Retrieve values from attributesMap
$city = $attributesMap["city"]
$country = $attributesMap["country"]
$jobTitle = $attributesMap["jobTitle"]
# Create AttributeRequest and assign group membership to user based on the location and job title of the user
$memberOfList = @("OU=Enabled Users,DC=TESTDOMAIN,DC=LOCAL")
if( $city -eq "Austin" -And $jobTitle -eq "Sr Manager") {
$memberOfList.Add("CN=AustinManagers,OU=Managers,DC=TESTDOMAIN,DC=LOCAL")
}
if( $country -eq "US") {
$memberOfList.Add("CN=USEmployees,OU=Employees,DC=TESTDOMAIN,DC=LOCAL")
}
if( $memberOfList.Count -gt 0) {
$attributeObject = New-Object SailPoint.Utils.objects.AttributeRequest;
$attributeObject.Name = "memberOf";
$attributeObject.Value= $memberOfList;
$attributeObject.Operation = "Add";
$requestObject.AttributeRequests.Add($attributeObject);
}
# Write the request xml to file at the path passed as argument
$requestObject.toxml()|out-file $args[0];
Sample PowerShell After Scripts
-
The following is a sample PowerShell after script that ensures that the request was processed successfully and creates home directory at the path specified in the request:
Copy# Refer to SailPoint class library. Requires PowerShell v2 installed on the system.
Add-type -path E:\SVN\trunk\src\WinRPCGateway\IQService\bin\Debug\utils.dll
# Read the environment variables
$sReader = New-Object System.IO.StringReader([System.String]$env:Request);
$sResult = New-Object System.IO.StringReader([System.String]$env:Result);
# Form the xml reader objects
$xmlReader = [ System.xml.XmlTextReader]([sailpoint.utils.xml.XmlUtil]::getReader($sReader));
$xmlReader_Result = [ System.xml.XmlTextReader]([sailpoint.utils.xml.XmlUtil]::getReader($sResult));
# Create SailPoint objects
$requestObject = New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader);
$resultObject = New-Object Sailpoint.Utils.objects.ServiceResult($xmlReader_Result);
#Check if the request was processed successfully
if($resultObject.Errors.count -eq 0){
#Get Home directory path
foreach ($attribute in $requestObject.AttributeRequests){
#Create Home directory
if($attribute.Name -eq "TS_TerminalServicesHomeDirectory"){
new-item $attribute.Value -itemtype directory;
}
}
} -
The following after script displays how to access any application configuration attribute in the script.
The following example reads application attributes with name
Office365Username
andpassword
and uses them to connect to Exchange Online and sets Mailbox properties:Copy# Refer to SailPoint class library.
Add-type -path C:\Program files\IQService\bin\Debug\utils.dll
# Read the environment variables
$sReader = New-Object System.IO.StringReader([System.String]$env:Request);
$sResult = New-Object System.IO.StringReader([System.String]$env:Result);
# Form the xml reader objects
$xmlReader = [ System.xml.XmlTextReader]([sailpoint.utils.xml.XmlUtil]::getReader($sReader));
$xmlReader_Result = [ System.xml.XmlTextReader]([sailpoint.utils.xml.XmlUtil]::getReader($sResult));
# Create SailPoint objects
$requestObject = New-Object Sailpoint.Utils.objects.AccountRequest($xmlReader);
$resultObject = New-Object Sailpoint.Utils.objects.ServiceResult($xmlReader_Result);
# Retrive nativeIdentity from request object
$nativeIdentity = $requestObject.NativeIdentity
# Get xmlFactory object to retive application configuration
$xmlFactory = [sailpoint.Utils.xml.XmlFactory]::Instance;
# Read the environment variables
$sReader1 = $env:Application
# Retrive application configuration object
$appObject = $xmlFactory.parseXml($sReader1)
#Retrive application configuration entries named Office365username and password value from AzureAD application config
$office365AdminUsername = $appObject.Office365username
#Retrive password attribute value
$o365Password = $appObject.password
#create Credential object
$secpasswd = ConvertTo-SecureString $o365Password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ($office365AdminUsername, $secpasswd)
#Connect to Office365
Import-Module msonline
Connect-MsolService -Credential $cred
#Connect Exchange-Online
$msoExchangeURL = "https://ps.outlook.com/powershell/"
$session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $msoExchangeURL -Credential $cred -Authentication Basic -AllowRedirection
Import-PSSession $session
# Set mailbox properties
Set-MailBox -identity $nativeIdentity -UseDatabaseQuotaDefaults $false -IssueWarningQuota "200MB" -ProhibitSendQuota "250MB" -ProhibitSendReceiveQuota "280MB"
Scripts without Object Oriented Support
Non Object Oriented scripts do not support referring to the class library or a way of parsing XML. To have easy access to each attribute along with their operation and values, IQService creates process environment variables for each of the application and request attributes with names in the form SP_<OPERATION>_<NAME>
for requests and SP_APP_<NAME>
for applications. For native identity, the environment variable would be SP_NativeIdentity
. These types of scripts have limited access to descriptive results and get only SUCCESS or FAIL in the Result
environment variable. Therefore the after scripts implemented using these scripting languages cannot modify any attribute/result. The before scripts can add, modify, or remove any attribute from the request. The script needs to write the newly added or modified attribute to the file at the path passed as an argument to the script in the form SP_<OPERATION>_<NAME>=<VALUE>
. For removing the attribute from the request, write /~<ATTRIBUTE_NAME>
to the file. Value for the multivalued attribute is delimited by /#/.
The following is a sample batch after script that ensures that the request was processed successfully and creates home directory at the path specified in the request:
IF %Result% ==SUCCESS md %SP_Set_TS_TerminalServicesHomeDirectory%