SHIFT-WIKI

--- Sjoerd Hooft's InFormation Technology ---

User Tools

Site Tools


idmmultivalue

Identity Manager and Converting Multi-Valued Attributes to Single-Valued Attributes

This is an article on how to combine multiple values from a multi-valued attribute into a single valued attribute. This is required when you have multiple values in for example the Location or Room Number in eDirectory.

Symptom

We are first going to see what goes wrong:

One value

When we populate the location field in iManager for a synchronized user the value gets synced as well: Enter the single value in iManager: idmmultivalue01.jpg
And the value get synced to Active Directory: idmmultivalue02.jpg

Two values

Now we first remove the original value (make sure the removal of the attribute gets synchronized) and then add two values to the attribute: idmmultivalue03.jpg
But the value doesn't sync through: idmmultivalue04.jpg
But in the dstrace log we see an error:

13:07:48 AD-driver ST:
DirXML Log Event -------------------
Driver: \SHIFT-TREE\shift\AD-driver\AD-driver
Channel: Subscriber
Object: \SHIFT-TREE\shift\SHIFTUSERS\SjoerdH
Status: Error
Message: <ldap-err ldap-rc="20" ldap-rc-name="LDAP_ATTRIBUTE_OR_VALUE_EXISTS">
   <client-err ldap-rc="20" ldap-rc-name="LDAP_ATTRIBUTE_OR_VALUE_EXISTS">Attribute Or Value Exists</client-err>
   <server-err>00002081: AtrErr: DSID-030F10D6, #1:
   0: 00002081: DSID-030F10D6, problem 1006 (ATT_OR_VALUE_EXISTS), data 0, Att 13 (physicalDeliveryOfficeName)
</server-err>
   <server-err-ex win32-rc="8321"/>
</ldap-err>

Solution

To solve this issue we need to create a new policy, and in that policy we have to create three rules:

  • Setup Local Variable
  • Concatenate Values
  • Remove Values If Needed

First I'll show you each rule individually and after that the end result.

Create Policy

The policy has to be created in the “Event Transformation Policies”: idmmultivalue05.jpg
Click 'Insert' and provide the required values: idmmultivalue06.jpg

Setup Local Variable

We first create a simple rule that creates a local variable that is a nodeset of the L (location) attribute: idmmultivalue07.jpg

Concatenate Values

The second rule is a bit more complex. The conditions are still simple: idmmultivalue08.jpg

But the actions are a bit more complicated. Below I show you first the complete action list, and then I explain the first and third one a bit more in depth: idmmultivalue09.jpg

The first action is not even entirely visible. Click on the 'Edit the Actions' button. Now you see that 'for each' value you create a local variable called lvlocationoffice: idmmultivalue10.jpg

And again, this time the arguments, are not entirely visible. Click on the 'Edit the arguments'. Here you set the variable to itself, followed by a comma, a space, and a special value called 'current-node'. The current-node is the attribute value for the specific increment the loop is on: idmmultivalue11.jpg

The third actions needs a more in depth view of the arguments, if you click 'Edit the arguments' you can edit the verb 'Replace First'. Don't forget that you're replacing a comma and a space: idmmultivalue12.jpg

Remove Values If Needed

Needed in case it's a “remove all values” event“: idmmultivalue13.jpg

End Result

iManager view

idmmultivalue14.jpg

XML

<?xml version="1.0" encoding="UTF-8"?><policy>
	<rule>
		<description>Setup Local variable</description>
		<conditions>
			<or>
				<if-op-attr name="L" op="available"/>
				<if-op-attr name="L" op="changing"/>
			</or>
		</conditions>
		<actions>
			<do-set-local-variable name="locationoffice">
				<arg-node-set>
					<token-src-attr name="L"/>
				</arg-node-set>
			</do-set-local-variable>
		</actions>
	</rule>
	<rule>
		<description>Concatenate Values</description>
		<conditions>
			<and>
				<if-local-variable name="locationoffice" op="available"/>
				<if-src-attr name="L" op="available"/>
			</and>
		</conditions>
		<actions>
			<do-for-each>
				<arg-node-set>
					<token-local-variable name="locationoffice"/>
				</arg-node-set>
				<arg-actions>
					<do-set-local-variable name="lvlocationoffice">
						<arg-string>
							<token-local-variable name="lvlocationoffice"/>
							<token-text xml:space="preserve">, </token-text>
							<token-local-variable name="current-node"/>
						</arg-string>
					</do-set-local-variable>
				</arg-actions>
			</do-for-each>
			<do-strip-op-attr name="L"/>
			<do-set-dest-attr-value class-name="User" name="L">
				<arg-value type="string">
					<token-replace-first regex=", " replace-with="">
						<token-local-variable name="lvlocationoffice"/>
					</token-replace-first>
				</arg-value>
			</do-set-dest-attr-value>
		</actions>
	</rule>
	<rule>
		<description>Remove Values If Needed</description>
		<conditions>
			<and>
				<if-src-attr name="L" op="not-available"/>
			</and>
		</conditions>
		<actions>
			<do-strip-op-attr name="L"/>
			<do-clear-dest-attr-value name="L"/>
		</actions>
	</rule>
</policy>

Test

Now the values in eDirectory give these values in Active Directory: idmmultivalue15.jpg
But also, these values sync back: idmmultivalue16.jpg

Sources

idmmultivalue.txt · Last modified: 2021/09/24 00:24 by 127.0.0.1