Tuesday, December 13, 2011

Provisioning Dynamically


I was having an extended email conversation with some peers about some issues they were experiencing with Pending Value Objects in SAP NetWeaver Identity Management. Now for sure, I’ve never been a fan, but I monitored the conversation because you never know when you might learn something. For a while, my most interesting comment was that “Pending values are something I’m still “pending” on.” And I figured that would be about it.

After a bit, I decided to re-read the original question, thinking there’s got to be an easier way to handle the issue, which involved designing a mechanism to determine which repository a user should be provisioned to, based on the migration status of a specific system, and then of course, do the provisioning.

I then remembered that I had created a “dynamic” provisioning mechanism some time ago for a client that might help. Since I like to share my knowledge far and wide, I will describe the solution.

The way I originally prototyped the process was to create the new user in IDM and then have the next task in the workflow create the user in Active Directory using the appropriate repository, which would be based on Business Unit (Each BU had different starting points and exchange servers so a single IDM Repository was not going to cut it) that the user belonged to. I used an Action Task with a “To Custom” pass that contained a script that looked something like this:

// Main function: DYNAMIC_CREATE_USER

function DYNAMIC_CREATE_USER (Par){
// Description: Initiates a provisioning task for a given entry in the identity store.
// Syntax:AuditRef=uProvision(Int MSKey, Int TaskID, Int RefAudit, Int Repository, String // UserID, Int Delay[, Int Standalone);
// Parameters: MSKey The entry's ID (MSKey).
// TaskID-The ID of the task to be initiated.
// RefAudit-Reference audit, if available. If the function is called from a provisioning // job, the audit reference of this task can be submitted to the task initiated by // uProvision and inserted in the audit log. Use 0 if no reference audit is available.
// Repository-Repository ID. 0 means no repository.
// UserID General user ID or message that will be inserted in the field USERID in the audit log.
// Typically this can be a distinguished name or Active Directory login name.
// DelayDelay in seconds until the task should be initiated.
// Standalone - Optional. Normally, when a task is started with uProvision and RefAudit is // given, the task will be an event task of the original task. This parameter specifies // whether the task should be an event task or not.
// Possible values:
// 0: The task is started as an event task. (Default)
// 1: The task is started "standalone" (not as an event task).
// AuditRef Audit reference or error message prefixed with !ERROR:.
// Example MyAudit=uProvision(2,5,0,0,"",50);
// Run task 5 on MSKey 2 and wait for 50 seconds before the task is initiated.

var RepName = "";
var Repository = 0;

RepName = Par.get('BUSINESSUNIT');

uErrMsg (1,"Repository Name - " + RepName);

if (RepName == "Corporate ")
 {
 Repository = 10;
 }
else if (RepName == "Widgets")
 {
 Repository = 9;
 }
else if (RepName == "Gadgets")
 {
 Repository = 11;
 }
else if (RepName == "Thingys")
 {
 Repository = 12;
 }
else
 {
 // Use the Default repository
 Repository = 1;
 }

uErrMsg (1,"Repository Number - " + Repository);

var MSKey = uGetEntryID();
var TaskID = 123;
var RefAudit = 0;
var UserID = Par.get('DISPLAYNAME');
var Delay = 20;;
var AuditRef = uProvision (MSKey, TaskID, RefAudit, Repository, UserID, Delay);

uErrMsg (1,"MSKey: " + MSKey + " TaskID: " + TaskID + " RefAudit: " + RefAudit + " Repository: " + Repository + " UserID: " + UserID + " Delay: " + Delay);
uErrMsg (1,"AuditRef: " + AuditRef);

}// FUNCTION

Of course the names of the Business Units and Repository values will depend on your project, and you might use a completely different attribute to base your Repository decision on.

The trick to this solution lies with the uProvision function to execute the task using the correct repository. Now I know this could have been done using a standard “To-LDAP” pass with some lookups, but I wanted something more flexible. By using this technique, you are matching the provisioning action to a repository which gives us much more flexibility in the workflow.

2 comments:

SCviaDC said...

This looks vaguely familiar...

I'd also suggest adding a uIS_SetValue to your script to store the Repository ID with the user in an attribute just in case you have to do some other uProvision later in the workflow and will need it.

-Jared

Matt Pollicove said...

Jared,

I thought you might :)

That's a good point about adding an attribute to hold the Repository Value.

M