External Applications with ActiveRoles Scripts

Aug. 18th 2014

External Applications with ActiveRoles Scripts

TPAM Example

ActiveRoles Server is one of my favorite Active Directory management and automation applications.  Not only does it provide management isolation and roles based security, but combined with Workflows, scripting, and Administration Policies, ActiveRoles server capabilities cover a very wide range of scenarios.

In one of my previous articles Bulk Import with ActiveRoles, we learned that an ActiveRoles script module could access a CSV located on an ARS server.  Did you know that ARS can also interact with other external systems and applications as well?  As long as the application has a CLI or the system is accessible through the command line, more than likely, functions will be able to be integrated into a ARS Workflow or Administration Policies.

Writing scripts to access or utilize these systems is a simple matter to utilize the PowerShell Invoke-Expression cmdlet to allow PowerShell to execute a non-PowerShell executable.  For example:

$Command = “netsh interface show interface”

$Results = Invoke-Expression $Command

With the example above, the command to be executed is assigned to a variable named $Command, and then the Invoke-Expression cmdlet is run using the command variable.  The output of this command is saved into another variable named $Results.  The reason for performing the command this way is so the output may be evaluated for error codes, completion status, or even to use the output for further commands, processing, or population into attributes within Active Directory.

I have been asked on more than one occasion if Dell TPAM can be integrated with ARS.  While there is no direct or ‘official’ integration between these two products, TPAM does have a CLI interface that may be accessed to perform functions within the system.  This interface is only accessible by using SSH, and as we all know that Windows does not come with a SSH client.  The most prevalent go to SSH client is Putty, but the TPAM CLI requires the use of an authentication key and putty is a bit cumbersome when it comes to using keys and command line.  For using ARS with TPAM, I have configured and used SSH in CYGWIN on ARS.

For this example, I will assume that you, the reader, has some experience with TPAM and ARS.

First, download and install CYGWIN from the official website and install it.  During the install on the packages selection page, search for SSH.  Once the filter applies, expand Net and select openssh and libssh2_1 to install CYGWIN base and openssh.

Now, a TPAM CLI user needs to be configured and the key needs to be saved and placed on the ARS server for use with the CYGWIN openssh.

On the ARS server, if an attempt were made to use openssh to connect to TPAM using this key, openssh would complain that the key is not private.  The error message would be similar to the one below, possibly with the exception of the path of the key.

 

 

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Permissions 0660 for ‘~/.ssh/id_rsa’ are too open.

It is required that your private key files are NOT accessible by others.

This private key will be ignored.

bad permissions: ignore key: ~/.ssh/id_rsa

In order to correct this error, the following commands will need to be ran from within the CYGWIN shell interface.  Just navigate to where the key is saved and replace id_rsa with the name of the key that needs to be changed.

chgrp Users id_rsa

chmod 600 id_rsa

Now that the permissions have been corrected, connect to TPAM with the CLI user id and key manually one time to save the TPAM system in the authorized hosts on the ARS system.  This will prevent any pauses or failures of the ARS script due to a needed response for the SSH client.

A command that can be used to initiate SSH and save the authorized hosts is:

ssh -i .\id_rsa cli_user@tpam.domain.com list user

This TPAM system has now been saved as an authorized host on the ARS system and the ARS script may be created for whatever purpose that is deemed necessary, for example resetting a password on an account in TPAM.

A suggested setting in the script is to define a Cygwin environment variable to prevent openssh from throwing a dos warning since PowerShell will be executing SSH outside of the Cygwin shell.  The format of the command is as follows and it should be placed before executing SSH.

$env:CYGWIN = “nodosfilewarning”

The following script is a password reset example that will need to be placed in an onPreModify script module that is executed by an Administration Policy or a workflow.

$UserID = $DirObj.get(“sAMAccountName”)

$Password = $Request.Get(“edsaPassword”)

$command1 = “UpdateAccount –AccountName $UserID –SystemName HostName –Password $Password”

$command2 = “ssh -i c:\keys\id_rsa cli_user@tpam.domain.com $command1 2>&1”

$results = Invoke-Expression $command2

An explanation of the above script is that first, we grab the sAMAccountName of the account having the password reset and store this into a variable.

Second, within ARS, when a password is changed, the password is temporarily stored in a virtual attribute and this attribute is cleared after the password has been committed.  Since we are executing this onPreModify, we can intercept the data in this field and store it for use in the rest of the script.  For this example, the password data is stored in a variable called $Password.

Next the command for connecting to TPAM.  For readability, the command has been broken into two pieces.  $command1 is the actual TPAM command, which tells TPAM to update the account we stored in $UserID on the system HostID with the password stored in $Password.  Just for clarification, this changes the password on the system/account object within TPAM.  $command2 is the actual ssh command that ARS will use to contact TPAM, which also includes a reference to $command1 to build the full command string.

The last operation is to execute the command with Invoke-Expression and store the results in a variable called $results.

Moving forward, this script could be expanded to write information in the event viewer, just replace the $variable with the item you want to appear in the event log.

$EventLog.ReportEvent($Constants.EDS_EVENTLOG_WARNING_TYPE, [string] $variable)

Another option is to place some event handling logic in the script that will read through the $results and evaluate the data for a success or failure notification.

This was just an example of what can be accomplished using the flexibility within ActiveRoles Server, a short primer if you will.  Hopefully you can use some of the concepts and ideas here to come up with your own use cases and solutions when it comes to using external systems and command line applications with ActiveRoles Server.

Author: Russ Burden, Technical Architect, LeadThem Consulting

Posted by LeadThem Consulting | in ARS | Comments Off on External Applications with ActiveRoles Scripts

ARS Bound List Boxes

Aug. 18th 2014

ARS Bound List Boxes

                Bound list boxes in the ARS web interface have always been a challenge.  There are ARS Add-Ons available to facilitate bound list boxes within the ARS Web Interface up and including ARS 6.8.  Did you know that bound list box functionality is now included with ARS 6.9?  This has always been a sought after feature within ARS, and now that it is built into the product, we will go over how to utilize bound list boxes, but first, what are bound list boxes?

Bound list boxes are essentially multiple drop down list boxes on a web interface that are dependent.  What this means is, list box one contains a list of items, list box two is bound to list box one.  Whenever a selection is made from list box one has been selected, the available choices in list box two changes based upon the selection in list box one.

Now for the example.  A global organization has sites in multiple cities, but not all departments are in all cities. We have a web interface form that we want to allow the admin to select a city, and the selection of the city changes the available departments.

There are multiple parts to this solution to make the bound list box perform what we want it to do.

We need to have the list of cities and the departments that fall into each city.  For this example, we will use the following:

New York

Human Resources

Finance

Help Desk

London

Human Resources

Help Desk

Network Support

Tokyo

Human Resources

Research & Development

Instructional Development

Beijing

Human Resources

Manufacturing

Software Development

 

All of these items have to be stored somewhere, so the cities will be stored in a property and validation rule within an administration template.  That brings us to the second item needed, an Administration Template.  This template will be linked to all OUs that require use of the bound list box.  The template will contain the aforementioned property and validation rule and a script module that contains the code that allows the list box to function.

The script module required will be utilizing the function onGetEffectivePolicy.  This function allows us to inject code at page load time and affect how the page reacts to selections and we can even inject custom error messages/responses.

Building the solution:

First, let’s create the administration policy.

  1. Connect to the ARS MMC with a user that has permissions to create Administration Policies and Script Modules
  2. Expand Configuration->Policies->Administration
  3. Right click on the container you want to create your new policy within, move down to New, and click Provisioning Policy
  4. Enter a name for the Policy and click Next, in this example I named my policy Bound List Box.
  5. Select Property Generation and Validation, click Next
  6. Click Select and locate City (l) and click ok to select this attribute. Click Next
  7. Check City must be specified and City must be <value> (generates Default Value)
  8. In the bottom pane, click on <click to add value>
  9. Enter the first city name and click OK
  10. Click <click to add value> and add each of the other city names
  11. Click Next
  12. Click Next to accept the policy name
  13. Click Add and enter an OU to attach this policy to.
  14. Click Next
  15. Click Finish

Let test this policy to ensure we will see these cities.

  1. Connect to the ARS Admin Web Interface.
  2. Navigate to the OU in which you attached the Admin Policy
  3. Click on one of the users located in that OU to view its properties
  4. Click on the Address Tab
  5. The City field should be a drop down with the city names we just entered into the Admin Policy

1

Now that we have the drop down for the City created and working, let’s work on the Script Module that will connect the data in the Department field to what is selected in the City field.

First let’s create a script module

  1. in the ARS MMC, expand Configuration->Script Modules
  2. Right click on a container where the module will be created, move to new, and click Script Module
  3. Name the Script Module, I named this BLB – CityDepartment for the example
  4. Leave the language PowerShell
  5. Click Next
  6. Select Policy Script and Click Next
  7. Check onGetEffectivePolicy and click Next
  8. Click Finish

Now that the module has been created, let’s break down the code needed for this module:

$listNYC = @(‘Human Resources’,’Finance’,’Help Desk’)$listLON = @(‘Human Resources’,’Help Desk’,’Network Support’)

$listTOK = @(‘Human Resources’,’Research & Development’,’Instructional Development’)

$listBEJ = @(‘Human Resources’,’Manufacturing’,’Software Development’)

$listDefault = @(‘Select a City’,’to change this dropdown’)

 

This first section builds each list that the Department drop down will display when the city has been selected.  Each variable is named for the city and contains an array of the departments assigned to that city.

NOTE:  The $listDefault is required, if a default set of values are not defined for the drop down, the web form field will not appear as a drop down and will not cycle when the city is selected.

function onGetEffectivePolicy($Request){

if($Request.Class -eq “user”)

{

 

The next code snipped creates the function for onGetEffectivePolicy and then verifies that the class of object that exists in the request is user.  Any other classes will not execute any code in the script other than verifying the class.

         $Request.SetEffectivePolicyInfo(‘department’, $Constants.EDS_EPI_UI_RELOAD_EPI_BY_RULE, ‘l’)

 

This next line tells the page to reload the ‘department’ field when the City field (‘l’ attribute) is changed.

       $UserCity = GetCurrentValue -Request $Request -AttributeName ‘l’

 

Now, we must get the current value of the City drop down.  This line calls the function GetCurrentValue.

function GetCurrentValue($Request, [string]$AttributeName){

trap {continue}

$value = $Request.Get($AttributeName)

if($value -eq $null)

{

$DirObj.GetInfoEx(@($AttributeName),0) | Out-Null

$value = $DirObj.Get($AttributeName)

}

$value

}

 

The function get current value is used to acquire the current value of the department attribute from the request.  If the request does not contain a value for the department attribute, it attempts to get the value from the actual directory object.

       switch($UserCity){

‘New York’          {$possibleValues = $listNYC}

‘London’                        {$possibleValues = $listLON}

‘Tokyo’              {$possibleValues = $listTOK}

‘Bejing’              {$possibleValues = $listBEJ}

default              {$possibleValues = $listDefault}

}

 

 

This section uses the value attained from the request to switch the values for the $possibleValues attribute.  This variable becomes populated with the city specific department data depending on the city found during the GetCurrentValue function execution.

         $Request.SetEffectivePolicyInfo(‘department’, $Constants.EDS_EPI_UI_POSSIBLE_VALUES, [string[]]$possibleValues)}

}

Lastly, this line places the $possibleValues variable into the department field in the Web Interface form.  Since this is a multi-valued array, the department field on the form is represented as a drop down list in the Web Interface.

Putting it all together, the entire script module appears as follows:

$listNYC = @(‘Human Resources’,’Finance’,’Help Desk’)$listLON = @(‘Human Resources’,’Help Desk’,’Network Support’)

$listTOK = @(‘Human Resources’,’Research & Development’,’Instructional Development’)

$listBEJ = @(‘Human Resources’,’Manufacturing’,’Software Development’)

$listDefault = @(‘Select a City’,’to change this dropdown’)

 

function onGetEffectivePolicy($Request)

{

if($Request.Class -eq “user”)

{

$Request.SetEffectivePolicyInfo(‘department’, $Constants.EDS_EPI_UI_RELOAD_EPI_BY_RULE, ‘l’)

$UserCity = GetCurrentValue -Request $Request -AttributeName ‘l’

switch($UserCity)

{

‘New York’   {$possibleValues = $listNYC}

‘London’     {$possibleValues = $listLON}

‘Tokyo’       {$possibleValues = $listTOK}

‘Bejing’     {$possibleValues = $listBEJ}

default       {$possibleValues = $listDefault}

}

$Request.SetEffectivePolicyInfo(‘department’, $Constants.EDS_EPI_UI_POSSIBLE_VALUES, [string[]]$possibleValues)

}

}

 

function GetCurrentValue($Request, [string]$AttributeName)

{

trap {continue}

$value = $Request.Get($AttributeName)

if($value -eq $null)

{

$DirObj.GetInfoEx(@($AttributeName),0) | Out-Null

$value = $DirObj.Get($AttributeName)

}

$value

}

 

Now, we need to add the script module to the Admin Policy so that this script takes effect when the form has been loaded.

  1. In the MMC, expand Configuration->Policies->Administrative
  2. Double click or Right click and select properties on the Admin Policy that was created earlier in this example.
  3. Click on the policies tab, and click Add
  4. Click next
  5. Select Script Execution and click Next
  6. Select the script module created in the previous steps and click Next
  7. Click Next
  8. Click Finish
  9. Click Ok to exit the Admin Policy dialog

Lastly, we either need to create a web form or modify an existing form.  For this example, we will modify the existing user create form.

  1. Login to the Admin portal as an ARS Admin user, http://<server>/ARServerAdmin
  2. Click on Directory Management
  3. Click on the domain the managed OU exists within
  4. Navigate and click on the OU the Admin Policy was applied to
  5. Select New User from the drop down menu at the top of the page
  6. Click on Customize this form and the bottom right of the page
  7. Hover over Add Entry, and click on Select
  8. Check City and Department and click save
  9. Click save
  10. Click Reload
  11. Click Exit

Now, all we have to do is test the web form.

After clicking exit from the previous steps, the Web Interface should return to the New User form and as you can see, New York is selected as the default for City and if the drop down for department is clicked, Human Resources, Finance, and Help Desk are present.

2

Selecting Tokyo from the list, Human Resources, Research & Development, and Instructional Development appear in the Department list.

3

When Beijing is selected, the departments Human Resources, Manufacturing, and Software Development are viable departments for that city.

4

Lastly, Selecting London from the list shows Human Resources, Help Desk, and Network Support as selectable options.

5

Now, we can see that the drop down works as expected, the creation of a new account is needed to see that the values are set.  I used the new user form to create a new user completely and once created, I opened up the properties of that user to verify the values that were set.

Selecting the Address Tab shows Tokyo for the City.

6

And clicking on the Organization Tab shows Research & Development assigned as the users Department

7

There are many other uses for Bound List Boxes, just use the fundamentals from this article to apply this functionality to your scenarios.

 

Author: Russ Burden, Technical Architect, LeadThem Consulting

Posted by LeadThem Consulting | in ARS | Comments Off on ARS Bound List Boxes

ActiveRoles – Using Previous Attribute Values

Mar. 1st 2014

ActiveRoles – Using Previous Attribute Values

                Sometimes we come across complex situations when dealing with scripting or workflows that require knowing not only the requested change but also the previous or old value of an attribute.  This can be used to determine the previous state of an object and some decision can be made based upon that value.

Unfortunately, within ActiveRoles Server, the previous value of an attribute is not available within the $Request array, but that doesn’t mean we cannot retrieve it for use.  The basis behind what we are talking about is, creating a script module with two sections to perform these actions.

onPreModify:

This function will retrieve the previous value of the attribute in question and store it within the request for later use (within the same request).

onPostModify:

The basis behind this function is to retrieve the original value from the request and perform some action on it.

In our example script module below, we are utilizing an ActiveRoles virtual attribute named vEmployeeStatus that has been used to store the employee status.  This status can be a word, an acronym, or just a plain letter as in ‘A’ for Active and ‘T’ for Terminated.

function   onPreModify($Request){if ($Request.Class -ne “User”)   { return; }# Use Parameters of the Request   object to pass the original value to onPostMOdify event handler.try

{

$DirObj.GetInfoEx(“vEmployeeStatus”,0)

$strEmployeeStatus_orig =   $DirObj.Get(“vEmployeeStatus”)

}

catch {}

if ($strEmployeeStatus_orig -eq   $null)

{

$strEmployeeStatus_orig =   “”

}

$Request.Parameter(“vEmployeeStatus”,$strEmployeeStatus_orig)

 

}

 

function   onPostModify($Request)

{

if ($Request.Class -ne “user”)   { return; }

$strUserDN =   $DirObj.Get(“distinguishedName”)

$strEmployeeStatus_new =   $Request.Get(“vEmployeeStatus”)

try

{

$strEmployeeStatus_orig =   $Request.Parameter(“vEmployeeStatus”)

}

catch {}

$EventLog.ReportEvent($Constants.EDS_EVENTLOG_WARNING_TYPE,   “Original Status: $strEmployeeStatus_orig”)

$EventLog.ReportEvent($Constants.EDS_EVENTLOG_WARNING_TYPE,   “New Status: $strEmployeeStatus_new”)

 

$strEmployeeStatus_orig

}

 

 

Breaking down the script module further, let’s look at each function:

onPreModify:

1)      First we check to make sure the request is for a ‘User’ object type

2)      Next we attempt to get the current employee status from the object

3)      Now a validation is taken to see if the current status is Null, if it is, we set the original employee status to blank

4)      Lastly, the employee status is written into the request for later retrieval.

onPostModify:

1)      First we check to make sure the request is for a ‘User’ object type

2)      Next we get the new employee status and assign it a variable

3)      The old employee status is retrieved and assigned to a variable

4)      Two event log entries are created to show the old and new values

5)      Last, the old employee status value is output from the script for the workflow to read.

If this script were needed in a policy, the onPostModify could be modified to actually take some action or change an object.

Now, let’s take the example script into ActiveRoles Server and use it in a workflow example.

To begin, open the ActiveRoles MMC and create a new virtual attribute.

1)      Expand Configuration->Server Configuration

2)      Right Click on Virtual Attributes and select New->Virtual Attribute

3)      Click Next on the Welcome page

4)      Enter the Common Name and LDAP Display Name for the attribute.  Again, in our example, we are using vEmployeeStatus.  The description is also recommended for a note on what this attribute’s purpose is.

 

5)      We need to create a Directory String that is not multi valued.  Click Next.

6)      Select User class as people are the only objects that should have an employee status. Click Next.

7)      We do want to store this attribute in the database.  Click Next.

8)      Click Finish.

 

9)      Now, we must reconnect the MMC to the ARS services to make the new virtual attribute available to our console.  Right click on the Quest One ActiveRoles node and click Reconnect.

The next piece is to create a new script module. Let’s name it Script-EmployeeStatus.

1)      Expand Configuration->Script Modules

2)      Right Click on the container you want to create the Script Module inside and select New->Script Module

3)      In the New Object dialog, enter a name for the script, the language should be PowerShell, and enter a description if desired.  Click Next