Best practices
Don't change the default declaration of event handlers in Active Roles script policies. It can save a lot of time when troubleshooting. Use the Add Event Handlers button from the toolbar of the Active Roles Console when script editing to add a correct handler declaration to your script.
Always use the Option Explicit statement as first statement in your VBScript script. This forces the script host to validate all variables are declared before first use. It can also save a lot of time. This is not necessary when working with PowerShell.
When a script policy is applied to a scope (Organizational Unit, Domain or Container), it is triggered for EVERY related request that sent to the Active Roles for any object in the scope. Thus:
- Always check for the target's object class to confirm that the in-process object is relevant for the intended purpose of the script. This will prevent unexpected behavior when your script is triggered for other target object classes. For this, you can use the IsObjectClassRequested function from the suggested script library.
- Always check for requested attributes when processing Get requests. It will prevent wasteful runs of your script and can significantly increase performance. For this, you can use the IsAttributeRequested method of the Request object.
- Always check for modified attributes when processing Create, Modify, and CheckPropertyValues requests if your script serves specific attributes modification only. It will prevent unexpected behavior when script is triggered for modification of other attributes. For this, you can use the IsAttributeModified function from the suggested script library.
When reading virtual attributes values from any Active Roles object, use the GetInfoEx method before using the Get method. Otherwise, you can't get any values from virtual attributes.
Your script may throw an exception and stop running when it tries to read a value from an attribute or Active Roles input control that actually doesn't have any values. This behavior is by-design in ADSI. To overcome this in VBScript, use pair of On Error Resume Next and On Error Goto 0 statements. Or you can use the GetAttribute, GetAttributeEx, or GetInControl functions from the suggested script library.
Instead of binding with GetObject to the Active Roles object being processed in request, use the built-in DirObj object. Please refer to the Active Roles SDK for details about the DirObj object.
When processing Modify or CheckPropertyValues requests use Request object to get new attribute values set by client. Previous values of the same attributes you can get from the DirObj object.
When processing Modify requests and updating other attributes of the same target object, avoid infinite loops. If you update some attribute of the target object with a separate request, you might end up with infinite loop: script policy is triggered, it makes modification, this modifications triggers the same script policy again, and again, and again... You can identify this situation by error event in the EDM Server event log with the following message: Recursion is too deep; nested policy execution limit has been exceeded. Instead of updating same object with separate request, use the Request.Put method on the pre-modify stage to update attribute values of the target AD object.
If your script policy doesn't work as expected, but you don't get any error messages on the UI, check the EDM Server event log on server where the ARS service is running. There you can find all the error messages that ARS has reported.
At the end of this document you can find source code libraries both for VBScript and PowerShell.
And if you believe you did everything right but it still doesn't work, ask the ARS gurus on the https://www.oneidentity.com/community/active-roles/f/forum
Library
IsObjectClassRequested
Function IsObjectClassRequested (ByVal strClassName, ByRef Request)
This function determines if the request was issued for the specified object class. It can be useful to force the script policy event handler to be triggered for the specified object class only.
Parameters
- strClassName - string with object class name. It can be in any cases, for example "User", "GROUP", "computer"
- Request - the Request object. Please see ARS SDK for details about this object
Return value
- True - When operation target object type equals to strClassName
- False - When operation target object type does not equal to strClassName
Remarks
This function is applicable to any event handlers
Example
Sub onPreModify(Request)
If (Not IsObjectClassRequested("contact", Request)) Then Exit Sub
'... your code
End Sub
IsAttributeModified
Function IsAttributeModified (ByVal strAttributeName, ByRef Request)
This function determines if modification for the specified attribute is requested. It can be useful to force the script policy event handler to be triggered for the specified attribute modification only.
Parameters
- strAttributeName - string with attribute name. It can be in any cases, for example "edsvaMyAttribute", "EDSVAMYATTRIBUTE"
- Request - the Request object. Please see ARS SDK for details about this object
Return value
- True - When specified by strAttributeName attribute is modified with this request
- False - When specified by strAttributeName attribute is not modified with this request
Remarks
This function is applicable to onPreCreate, onPostCreate, onPreModify, onPostModify, and onCheckPropertyValues event handlers.
VBS Example
Sub onPreModify(Request)
If (Not IsAttributeModified("edsvaMyAttribute", Request)) Then Exit Sub
'... your code
End Sub
PS Example
function onPreModify($Request)
{
if ((IsAttributeModified "edsvaMyAttribute" $Request) -eq $false) { return }
#... your code
}
GetAttribute
Function GetAttribute (ByVal strAttributeName, ByRef Request)
This function returns a value of the specified attribute of the specified object. It can be useful to prevent an error rising when the attribute has no value.
Parameters
- strAttributeName - string with attribute name. It can be in any cases, for example "edsvaMyAttribute", "EDSVAMYATTRIBUTE"
- Request - the Request object. Please see ARS SDK for details about this object
Return value
- Integer, string, boolean value, or array of values - When specified by strAttributeName attribute has any values
- Empty value - specified by strAttributeName attribute has no value
Remarks
This function is applicable to onPreGet, onPostGet, onPreCreate, onPostCreate, onPreModify, onPostModify, and onCheckPropertyValues event handlers.
Example
Sub onPostModify(Request)
'... your code
strValue = GetAttribute("edsvaMyAttribute", Request)
'... your code
End Sub
GetAttributeEx
Function GetAttributeEx (ByVal strAttributeName, ByRef Request)
This function returns an array of values of the specified attribute of the specified object. It can be useful to prevent an error rising when the attribute has no value.
Parameters
- strAttributeName - string with attribute name. It can be in any cases, for example "edsvaMyAttribute", "EDSVAMYATTRIBUTE"
- Request - the Request object. Please see ARS SDK for details about this object
Return value
- Array of integer, string, or boolean values - When specified by strAttributeName attribute has any values
- Empty value - When specified by strAttributeName attribute has no value
Remarks
This function is applicable to onPreGet, onPostGet, onPreCreate, onPostCreate, onPreModify, onPostModify, and onCheckPropertyValues event handlers.
Example
Sub onPostModify(Request)
'... your code
arrayValue = GetAttributeEx("edsvaMyAttribute", Request)
'... your code
End Sub
GetInControl
Function GetInControl (ByVal strControlName, ByRef Request)
This function returns a value of the specified input control of the Request object. It can be useful to prevent an error rising when the input control has no value.
Parameters
- strControlName - string with input control name. It can be in any cases, for example "myControl", "MYCONTROL"
- Request - the Request object. Please see ARS SDK for details about this object
Return value
- Integer, string, boolean value, or array of values - When specified by strControlName ARS input control has any values
- Empty value - When specified by strControlName ARS input control has no value
Remarks
This function is applicable to onPreGet, onPostGet, onPreModify, onPostModify, and onCheckPropertyValues event handlers.
Example
Sub onPostModify(Request)
'... your code
strValue = GetInAttribute("MyControl", Request)
'... your code
End Sub
IsAttributeGenerationRequested
Function IsAttributeGenerationRequested (ByVal strAttributeName, ByRef Request)
This function determines if a server-side generation for the specified attribute is requested.
Parameters
- strAttributeName - string with attribute name. It can be in any cases, for example "edsvaMyAttribute", "EDSVAMYATTRIBUTE"
- Request - the Request object
Return value
- True - When a server-side generation for specified by strAttributeName attribute is requested
- False - When a server-side generation for specified by strAttributeName attribute is not requested
Remarks
This function is applicable to onGetEffectivePolicy event handler only.
Example
Sub onGetEffectivePolicy(Request)
If (Not IsAttributeGenerationRequested("edsvaMyAttribute", Request)) Then Exit Sub
'... your code
End Sub
DoARSSearch
Function DoARSSearch (ByVal strStartingNodeDN, ByVal strLdapQuery, ByVal strAttributeList, ByVal strDepth)
This function performs a search operation in desired ARS scope for AD objects by the specified query, and returns an ADO-rowset with the search results.
Parameters
- strStartingNodeDN - DN string of starting node, for example "OU=Sales,DC=foo,DC=com"
- strLdapQuery - string with LDAP-query, for example "(givenName=*)"
- strAttributeList - comma-separated string with attributes list, for example "givenName,sn,sAMAccountName"
- strScope - search scope, possible values are "subTree", "oneLevel", "base". Please refer to MSDN for details about search scope
Return value
- COM-object - ADO rowset with results
Remarks
This function is applicable to any event handlers as well as can be used in an external script.
Example
Set objRS = DoARSSearch("OU=Sales,DC=foo,DC=com", "(givenName=*)", "givenName,sn,sAMAccountName", "subTree")
Do While Not objRS.Eof
strFirstName = objRS("givenName")
strlastName = objRS("sn")
objRS.MoveNext
Loop
Library Source Code
VBScript Version
Click to obtain source code for VBScript Best Practices Library,
Click to view VBScript samples
PowerShell Version
Click to obtain source code for PowerShell Best Practices Library.
Click to view PowerShell samples.