Quantcast
Channel: Novell User Communities - Active Directory
Viewing all articles
Browse latest Browse all 30

Using the Scripting Driver to query Active Directory

$
0
0

In a prior article, I discussed an enhancement to the Active Directory Driver configuration which would allow you to create objects in the Identity Vault which represent the Active Directory domain. In this article, I will discuss one use for those objects.

Our client is concerned about a well known behavior in AD with regards to synchronization of the last logon time of a user. In Active Directory, the attribute lastLogon contains the last time a user logged in. This attribute, however, is not replicated between domain controllers. Therefore, since IDM runs off one of those domain controllers, only user who logged in at that specific DC would be synchronized.

In Windows 2003 they introduced another attribute, lastLogonTimestamp. This attribute does synchronize between domain controllers, but by default this happens no more often than once every 9 to 14 days. Assuming the typical user is logging in daily, this means that the value of this attribute could be up to two weeks stale.

In addition for certain logons, the attribute never gets updated unless AD is properly patched (see http://support.microsoft.com/kb/886705).

Now for most every application this is sufficient; you usually want to know that a user has been logging in over the last month or three to determine whether they are still a living breathing human using the workstation. However, if you are of the species auditor, you might have a different perspective, that the numbers need to be as perfect as possible.

In this case a monthly auditing report was produced and the dates were stale as we noted above, and therefore the client wanted a process to gather more accurate data.

We first utilized a simple VBA macro to accomplish this, but since they have 5 domains, this meant running a report against 15 different domain controllers using 5 different sets of credentials along with a macro which used the Novell ActiveX controls to report out the identity vault data, then reconcile this with another macro. It was long, it was unpleasant, and because it required a user with administrative privileges to run, and that was the same user that ran the domain, it violated auditing separation of duties principles.

So we whipped up a quick solution using the scripting driver (which thankfully they had already licensed) to accomplish this task. The solution does two things:

It maintains a multi-valued attribute of SYN_TYPED_NAME which is a structured attribute containing a DN and two bit unsigned integers (“level” and “interval”). Since time is internally stored as unsigned 32 bit integers, this was an appropriate use of the schema.

This attribute is used to store the DN of the domain controller representation in the identity Vault, the user’s last logon time at that DC, and the time the data was read respectively.

Second, the driver will compare the Last Login time from the Identity vault to the new value read from AD, which ever one is later will be stored as the Login Time in the Identity Vault.

The Solution

This client has a dozen or more AD domains, but in scope for this was six Active Directory domains in two forests. Five of the domains are synchronized into our identity vault. To deal with the two different name spaces, we store the data in separate attributes. Therefore, we maintain a GCV which contains the name of the attribute which contains the AD DN.

Note: For the additional domains, we defined a methodology of “plural” Active Directory attributes, i.e, DirXML-ADContexts and DirXML-ADAliasNames which are structured attributes containing the driver DN and the value for that tree. If it hasn’t already been documented by Geoff Carman, I will document that in a future article.

There are three parts to this solution:

  • Driver Policies
  • Script
  • Trigger Job

The basic concept is that a subscriber channel trigger fires once per night for all users; this trigger sends one trigger document per user. For each user, we will perform a query of Active Directory via the scripting driver using a specially formed class name which will direct the queries to the correct domain controller. The domain controllers are determined by the policies documented in a prior article on how to synchronize a representation of them from AD to the identity vault,

Driver Policies

GCVs

The following GCV is defined to indirect the name of the attribute containing the user’s AD DN in this name space:

<header display-name="CIS Custom Attributes"/>
		<definition display-name="Attribute containing context in this tree of this user" name="cis-ADContext-Attribute" type="string">
			<value>wattsLegacyADContext</value>
		</definition>

Subscriber Event Transform

This policy recognizes the trigger event and takes the following actions:

  1. It gets the DN of the user from whichever attribute is storing the AD DN for this tree. Since there a multiple domains and users may be a member of multiple domains, this allows us to find the correct DN for the instance of the driver we are running.
  2. It parses the domain part off the user’s Active Directory DN. We will use this later to calculate the context to find representations of the domain controllers.
  3. We set a node-set variable containing the current list of last logon times from the identity vault
  4. We initialize a variable to indicate the latest logon time across the various domain controllers.
  5. We iterate through list of computer objects at the domain location we created in the identity vault. For each object we take the following actions:
    1. Get the DN and the DNS name of the domain controller
    2. Call the script to get the last logon time from that DC
    3. If we get a value
      1. Iterate through and remove old last logon times from the identity vault list
      2. Update the list with the new value
      3. Calculate the latest login time from all the domains
      4. If the latest login time is later than the identity vault login time, update the identity vault to match.
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd""/home/rrawson/designer/plugins/com.novell.idm.policybuilder_3.5.0.201003011501/DTD/dirxmlscript3.6.dtd"><policy>
	<rule>
		<description>[CIS] Trigger</description>
		<conditions>
			<and>
				<if-operation mode="case" op="equal">trigger</if-operation>
				<if-attr name="DirXML-ADContext" op="available"/>
			</and>
		</conditions>
		<actions>
			<do-set-local-variable name="USER-DN" scope="policy">
				<arg-string>
					<token-lower-case>
						<token-src-attr name="~cis-ADContext-Attribute~"/>
					</token-lower-case>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="DOMAIN-PART" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">dc=</token-text>
					<token-xpath expression='substring-after($USER-DN,"dc=")'/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="AD-LAST-LOGONS" scope="policy">
				<arg-node-set>
					<token-src-attr name="wattsADlastLogons"/>
				</arg-node-set>
			</do-set-local-variable>
			<do-set-local-variable name="LATEST-LOGON" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">0</token-text>
				</arg-string>
			</do-set-local-variable>
			<do-for-each>
				<arg-node-set>
					<token-query class-name="Computer" datastore="src" scope="subordinates">
						<arg-dn>
							<token-global-variable name="cis-dc-landing-container"/>
							<token-text xml:space="preserve">\</token-text>
							<token-parse-dn dest-dn-format="slash" src-dn-format="ldap">
								<token-local-variable name="DOMAIN-PART"/>
							</token-parse-dn>
						</arg-dn>
						<arg-string>
							<token-text xml:space="preserve">L</token-text>
						</arg-string>
					</token-query>
				</arg-node-set>
				<arg-actions>
					<do-set-local-variable name="DC-SRC-DN" scope="policy">
						<arg-string>
							<token-xpath expression="$current-node/@src-dn"/>
						</arg-string>
					</do-set-local-variable>
					<do-set-local-variable name="DC-ADDRESS" scope="policy">
						<arg-string>
							<token-xpath expression="$current-node/attr[@attr-name='L']/value/text()"/>
						</arg-string>
					</do-set-local-variable>
					<do-set-local-variable name="LAST-LOGON" scope="policy">
						<arg-string>
							<token-query class-name="nTDSDSA@$DC-ADDRESS$" scope="entry">
								<arg-dn>
									<token-local-variable name="USER-DN"/>
								</arg-dn>
								<arg-string>
									<token-text xml:space="preserve">lastLogon</token-text>
								</arg-string>
							</token-query>
						</arg-string>
					</do-set-local-variable>
					<do-for-each>
						<arg-node-set>
							<token-local-variable name="AD-LAST-LOGONS"/>
						</arg-node-set>
						<arg-actions>
							<do-if>
								<arg-conditions>
									<and>
										<if-xpath op="true">$current-node/component[@name='dn']/text()=$DC-SRC-DN</if-xpath>
									</and>
								</arg-conditions>
								<arg-actions>
									<do-remove-src-attr-value name="wattsADlastLogons">
										<arg-value type="structured">
											<arg-component name="dn">
												<token-xpath expression="$current-node/component[@name='dn']/text()"/>
											</arg-component>
											<arg-component name="level">
												<token-xpath expression="$current-node/component[@name='level']/text()"/>
											</arg-component>
											<arg-component name="interval">
												<token-xpath expression="$current-node/component[@name='interval']/text()"/>
											</arg-component>
										</arg-value>
									</do-remove-src-attr-value>
								</arg-actions>
								<arg-actions/>
							</do-if>
						</arg-actions>
					</do-for-each>
					<do-if>
						<arg-conditions>
							<and>
								<if-local-variable mode="nocase" name="LAST-LOGON" op="not-equal"/>
							</and>
						</arg-conditions>
						<arg-actions>
							<do-add-src-attr-value name="wattsADlastLogons">
								<arg-value type="structured">
									<arg-component name="dn">
										<token-xpath expression="$current-node/@src-dn"/>
									</arg-component>
									<arg-component name="level">
										<token-local-variable name="LAST-LOGON"/>
									</arg-component>
									<arg-component name="interval">
										<token-time format="!CTIME" tz="UTC"/>
									</arg-component>
								</arg-value>
							</do-add-src-attr-value>
							<do-if>
								<arg-conditions>
									<and>
										<if-attr name="Login Time" op="available"/>
									</and>
								</arg-conditions>
								<arg-actions>
									<do-set-local-variable name="LOGIN-TIME" scope="policy">
										<arg-string>
											<token-attr name="Login Time"/>
										</arg-string>
									</do-set-local-variable>
								</arg-actions>
								<arg-actions>
									<do-set-local-variable name="LOGIN-TIME" scope="policy">
										<arg-string>
											<token-text xml:space="preserve">1</token-text>
										</arg-string>
									</do-set-local-variable>
								</arg-actions>
							</do-if>
							<do-if>
								<arg-conditions>
									<and>
										<if-xpath op="true">number($LATEST-LOGIN) < number($LAST-LOGIN)</if-xpath>
									</and>
								</arg-conditions>
								<arg-actions>
									<do-if>
										<arg-conditions>
											<and>
												<if-xpath op="true">number($LAST-LOGON) > number($LOGIN-TIME)</if-xpath>
											</and>
										</arg-conditions>
										<arg-actions>
											<do-set-src-attr-value name="Login Time">
												<arg-value type="time">
													<token-local-variable name="LAST-LOGON"/>
												</arg-value>
											</do-set-src-attr-value>
										</arg-actions>
										<arg-actions/>
									</do-if>
									<do-set-local-variable name="LATEST-LOGON" scope="policy">
										<arg-string>
											<token-local-variable name="LAST-LOGON"/>
										</arg-string>
									</do-set-local-variable>
								</arg-actions>
								<arg-actions/>
							</do-if>
						</arg-actions>
						<arg-actions/>
					</do-if>
				</arg-actions>
			</do-for-each>
		</actions>
	</rule>
	<rule>
		<description>[CIS] Screen Triggers from Shim</description>
		<conditions>
			<and>
				<if-operation mode="case" op="equal">trigger</if-operation>
			</and>
		</conditions>
		<actions>
			<do-veto/>
		</actions>
	</rule>
</policy>

Input Transform

Originally, I planned to utilize the existing policies which convert AD time to CTIME, however I decided that it would take more time to alter the existing script I had to remove it’s time formatting than to implement the convert time token.

However, the date and time comes through in a format that does not have leading zeroes on the single digit numbers, which meant I still had to parse the time string discretely. Perhaps more time spent on the convert time token would have resulted in a simpler solution but I for this project implementation time was key.

This policy simply takes the string which contains the date and adds the necessary leading zeros, then puts it back together to pass through the convert time token.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE policy PUBLIC "policy-builder-dtd""/home/rrawson/designer/plugins/com.novell.idm.policybuilder_3.5.0.201003011501/DTD/dirxmlscript3.6.dtd"><policy>
	<rule>
		<description>[CIS] lastLogon from script to CTIME</description>
		<conditions>
			<and>
				<if-op-attr name="lastLogon" op="available"/>
			</and>
		</conditions>
		<actions>
			<do-set-local-variable name="DATESPLIT" scope="policy">
				<arg-node-set>
					<token-split delimiter="/">
						<token-op-attr name="lastLogon"/>
					</token-split>
				</arg-node-set>
			</do-set-local-variable>
			<do-set-local-variable name="MONTH" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">0</token-text>
					<token-xpath expression="$DATESPLIT[1]"/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="DAY" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">0</token-text>
					<token-xpath expression="$DATESPLIT[2]"/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="YEAR" scope="policy">
				<arg-string>
					<token-substring length="4">
						<token-xpath expression="$DATESPLIT[3]"/>
					</token-substring>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="TIMESPLIT" scope="policy">
				<arg-node-set>
					<token-split delimiter=":">
						<token-substring start="5">
							<token-xpath expression="$DATESPLIT[3]"/>
						</token-substring>
					</token-split>
				</arg-node-set>
			</do-set-local-variable>
			<do-set-local-variable name="HOUR" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">0</token-text>
					<token-xpath expression="$TIMESPLIT[1]"/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="MIN" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">0</token-text>
					<token-xpath expression="$TIMESPLIT[1]"/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="MERIDIANSPLIT" scope="policy">
				<arg-node-set>
					<token-split delimiter="">
						<token-xpath expression="$TIMESPLIT[3]"/>
					</token-split>
				</arg-node-set>
			</do-set-local-variable>
			<do-set-local-variable name="SECS" scope="policy">
				<arg-string>
					<token-text xml:space="preserve">0</token-text>
					<token-xpath expression="$MERIDIANSPLIT[1]"/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="MERIDIAN" scope="policy">
				<arg-string>
					<token-xpath expression="$MERIDIANSPLIT[2]"/>
				</arg-string>
			</do-set-local-variable>
			<do-set-local-variable name="FMT-TIME" scope="policy">
				<arg-string>
					<token-xpath expression="substring($MONTH,string-length($MONTH)-2+1)"/>
					<token-text xml:space="preserve">/</token-text>
					<token-xpath expression="substring($DAY,string-length($DAY)-2+1)"/>
					<token-text xml:space="preserve">/</token-text>
					<token-local-variable name="YEAR"/>
					<token-text xml:space="preserve"> </token-text>
					<token-xpath expression="substring($HOUR,string-length($HOUR)-2+1)"/>
					<token-text xml:space="preserve">:</token-text>
					<token-xpath expression="substring($MIN,string-length($MIN)-2+1)"/>
					<token-text xml:space="preserve">:</token-text>
					<token-xpath expression="substring($SECS,string-length($SECS)-2+1)"/>
					<token-text xml:space="preserve"> </token-text>
					<token-local-variable name="MERIDIAN"/>
				</arg-string>
			</do-set-local-variable>
			<do-reformat-op-attr name="lastLogon">
				<arg-value type="time">
					<token-convert-time dest-format="!CTIME" dest-tz="UTC" src-format="MM/dd/yyyy hh:mm:ss a">
						<token-local-variable name="FMT-TIME"/>
					</token-convert-time>
				</arg-value>
			</do-reformat-op-attr>
		</actions>
	</rule>
</policy>

Script

The scripting driver allows you to run any script at the time of an event from eDirectory. The script is copied to the QUERY.VBS script. This script was adapted from a commonly used VBS script found through a Google search.

The scripting driver runs as a Windows service, and by default the service installs as the local system account. This will not suffice when querying Active Directory, and therefore the service must be stopped and reconfigured to log on as a user which has domain administrative privileges.

This script expects that the query sent by the IDM driver will contain a class name which is set to “nTDSDSA@<dns-name-of-DC>”. This is our flag to execute the query for the selected attribute. The attribute name is passed through from the query document, however this particular script is hard coded to expect that this is a date attribute, and therefore would not work for other attribute syntaxes without modification. It is not clear what other attributes in AD that do not synchronize would be of interest, however.

Sub QUERY
  ' *****************************************
  ' * Add implementation-specific code here *
  ' * Set the command to INSTANCE           *
   ' *****************
' Derived from LastLogon.vbs
' VBScript program to determine when each user in the domain last logged
' on.
'' ----------------------------------------------------------------------
' Copyright (c) 2002 Richard L. Mueller
' Hilltop Lab web site - http://www.rlmueller.net' Novell IDM Scripting Driver Query adaptation 
' Copyright © 2010 Robert Rawson DBA Rare Progeny Consulting
'  for Computer Integrated Services of NY LLC http://www.ciscony.com' Version 1.0 - December 7, 2002
' Version 1.1 - January 17, 2003 - Account for null value for lastLogon.
' Version 1.2 - January 23, 2003 - Account for DC not available.
' Version 1.3 - February 3, 2003 - Retrieve users but not contacts.
' Version 1.4 - February 19, 2003 - Standardize Hungarian notation.
' Version 1.5 - March 11, 2003 - Remove SearchScope property.
' Version 1.6 - May 9, 2003 - Account for error in IADsLargeInteger
'                             property methods HighPart and LowPart.
' Version 1.7 - January 25, 2004 - Modify error trapping.
' Version 1.8 - July 6, 2007 - Modify how IADsLargeInteger interface
'                              is invoked.
' Version 1.9 - December 29, 2009 - Output "Never" if no date.
' UPDATE: 1.10 – September 28, 2010 by Robert Rawson of CIS
'                Added filtering for use in multi-domain forests
'' Because the lastLogon attribute is not replicated, every Domain
' Controller in the domain must be queried to find the latest lastLogon
' date for each user. The lastest date found is kept in a dictionary
' object. The program first uses ADO to search the domain for all Domain
' Controllers. The AdsPath of each Domain Controller is saved in an
' array. Then, for each Domain Controller, ADO is used to search the
' copy of Active Directory on that Domain Controller for all user
' objects and return the lastLogon attribute. The lastLogon attribute is
' a 64-bit number representing the number of 100 nanosecond intervals
' since 12:00 am January 1, 1601. This value is converted to a date. The
' last logon date is in UTC (Coordinated Univeral Time). It must be
' adjusted by the Time Zone bias in the machine registry to convert to
' local time.
'' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty, obligations,
' or liability for such use.
dim strSearchName
dim strSearchNames
dim strClassName
dim strDCDNSName
dim strBase
dim strAttributes
dim strQuery
dim strFilter
dim strDN
dim adoCommand
dim adoConnection
dim adoRecordset
dim objDate
dim dtmDate
dim lngHigh
dim lngLow
dim objShell
dim lngBiasKey
dim lngBias

IDMTrace("Query Started")
IDMSetCommand "INSTANCE"' Obtain local Time Zone bias from machine registry.
' This bias changes with Daylight Savings Time.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
    & "TimeZoneInformation\ActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
    lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
    lngBias = 0
    For k = 0 To UBound(lngBiasKey)
        lngBias = lngBias + (lngBiasKey(k) * 256^k)
    Next
End If

' this is a constant which is what the IDM driver will use to indicate it is querying a specific DC
Const strFlagClass = "nTDSDSA@"

strClassName = IDMGetEventValue("CLASS_NAME")
IDMTrace("Class Name String: "& strClassName)
IDMWriteValue "CLASS_NAME", strClassName

If left(strClassName,8) <> strFlagClass then
    IDMStatusError "Query: class name must be "& strFlagName & "<dns-name-of-dc>"
    exit sub
    end if

' get the attribute name to search. Note this is hard coded to date attributes for now
strSearchName = IDMGetEventValue("READ_ATTRS")


If IsEmpty(strSearchName) Then
    IDMStatusError "Query: no search value"
    exit sub
    end if


     IDMTrace("Query attribute: "& strSearchName)

     Set adoCommand = CreateObject("ADODB.Command")
     Set adoConnection = CreateObject("ADODB.Connection")
     adoConnection.Provider = "ADsDSOObject"
     adoConnection.Open "Active Directory Provider"
     adoCommand.ActiveConnection = adoConnection

     strDCDNSName = right(strClassName, Len(strClassName)-Len(strFlagClass))

     strBase = "<LDAP://"& strDCDNSName  & "/"& IDMGetEventValue("DEST_DN") & ">"
     strFilter = "(&(objectCategory=person)(objectClass=user))"
     strAttributes = "distinguishedName," + strSearchName
     strQuery = strBase & ";"& strFilter & ";"& strAttributes & ";subtree"
     adoCommand.CommandText = strQuery

     IDMTrace("Query string: "& strQuery)

     On Error Resume Next
     Set adoRecordset = adoCommand.Execute

     If (Err.Number <> 0) Then
         IDMStatusError "Domain Controller "& strDCDNSName & " not available ("& cstr(err.number) & ") :"& err.description
         On Error GoTo 0
         exit sub
         end if

     On Error GoTo 0

     Do Until adoRecordset.EOF

         strDN = adoRecordset.Fields("distinguishedName").Value
         IDMTrace("Object Found: "& strDN)

         On Error Resume Next
         Set objDate = adoRecordset.Fields(strSearchName).Value

         If (Err.Number <> 0) Then
             IDMStatusError "Error retrieving "& strSearchName & " from "& strDCDNSName & "("& cstr(err.number) & ") :"& err.description
             On Error GoTo 0
             exit sub
             End If

         On Error GoTo 0

         lngHigh = objDate.HighPart
         lngLow = objDate.LowPart

         If (lngLow < 0) Then
             lngHigh = lngHigh + 1
             End If

         If (lngHigh = 0) And (lngLow = 0) Then
             dtmDate = #1/1/1601#
         Else
             dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
                + lngLow)/600000000 - lngBias)/1440
             End If

         IDMTrace("Returning "& strSearchName & "="& cstr(dtmDate))
         IDMWriteValue "ATTR_lastLogon", dtmDate

         adoRecordset.MoveNext
         Loop
    adoRecordset.Close

IDMStatusSuccess "Query from DC at "& strDCDNSName & " successful."

End Sub

The Job

The final element of this solution is a trigger job. The job is defined in iManager as follows:

Run the job every night at 1:00 am

Apply to users only

Send the events to all objects in scope

The XML of the job definition is as follows:

<?xml version="1.0" encoding="UTF-8"?><job-aggregation>
   <job-definition auto-delete="false" disabled="false" display-name="xlfid(job-display-name)Subscriber channel trigger" schedule="59 0 * * *" scope-required="false" type="java">
      <description>xlfid(job-description)This job submits zero or more trigger documents to the subscriber channel. The submission may either be a document per object if a scope is defined or may be a single document for each job run.</description>
      <containment>DirXML-Driver</containment>
      <java-class>com.novell.nds.dirxml.job.trigger.Trigger</java-class>
      <configuration-values>
         <definitions>
            <definition display-name="xlfid(process-unassociated)Submit a trigger document for objects without a driver association?" name="process-unassociated" type="boolean">
               <value>true</value>
            </definition>
            <group>
               <definition display-name="xlfid(use-job-cn)Use Job CN as trigger document identifier?" name="use-job-cn" type="boolean">
                  <description>xlfid(use-job-cn-desc)If set, use the job object's CN as the value of the trigger element's "source" attribute.</description>
                  <value>true</value>
               </definition>
               <subordinates active-value="false">
                  <definition display-name="xlfid(trigger-source)Trigger element source value" name="trigger-source" type="string">
                     <description>xlfid(trigger-source-desc)String to use as the value for the trigger element's "source" attribute.</description>
                     <value>1</value>
                  </definition>
               </subordinates>
            </group>
            <group>
               <definition display-name="xlfid(submit-method)Method for submitting trigger documents" name="submit-method" type="enum">
                  <enum-choice display-name="xlfid(submit-queue)queue (use cache)">submit-queue</enum-choice>
                  <enum-choice display-name="xlfid(submit-direct)direct (bypass cache)">submit-direct</enum-choice>
                  <value>submit-queue</value>
               </definition>
               <subordinates active-value="submit-direct">
                  <group>
                     <definition display-name="xlfid(start-driver)Start driver if not running" name="start-driver" type="boolean">
                        <value>false</value>
                     </definition>
                     <subordinates active-value="true">
                        <definition display-name="xlfid(stop-driver)Stop driver when finished processing trigger(s)" name="stop-driver" type="boolean">
                           <value>true</value>
                        </definition>
                     </subordinates>
                  </group>
               </subordinates>
            </group>
         </definitions>
      </configuration-values>
   </job-definition>
   <xliff version="1.0">
      <file datatype="xliff" original="Trigger.xml" source-language="de" xml:space="preserve">
      <header/>
      <body>
         <trans-unit id="job-display-name">
            <source>Abonnentenkanalauslöser</source>
         </trans-unit>
         <trans-unit id="job-description">
            <source>Mit diesem Auftrag werden null oder mehr Auslöserdokumente an den Abonnentenkanal abgesendet. Dabei kann es sich um ein Dokument pro Objekt handeln, sofern ein Bereich definiert wurde, oder um ein einzelnes Dokument für jede Auftragsausführung.</source>
         </trans-unit>
         <trans-unit id="process-unassociated">
            <source>Auslöserdokument für Objekte ohne Treiberzuordnung absenden?</source>
         </trans-unit>
         <trans-unit id="use-job-cn">
            <source>Auftrags-CN als Auslöserdokumentbezeichner verwenden?</source>
         </trans-unit>
         <trans-unit id="use-job-cn-desc">
            <source>Wenn festgelegt, wird der CN des Auftragsobjekts als Wert für das Ursprungsattribut des Auslöserelements verwendet.</source>
         </trans-unit>
         <trans-unit id="trigger-source">
            <source>Ursprungswert des Auslöserelements</source>
         </trans-unit>
         <trans-unit id="trigger-source-desc">
            <source>Zeichenkette, die als Wert für das Ursprungsattribut des Auslöserelements verwendet werden soll.</source>
         </trans-unit>
         <trans-unit id="submit-method">
            <source>Methode für das Absenden von Auslöserdokumenten</source>
         </trans-unit>
         <trans-unit id="submit-queue">
            <source>Warteschlange (Cache verwenden)</source>
         </trans-unit>
         <trans-unit id="submit-direct">
            <source>Direkt (Cache übergehen)</source>
         </trans-unit>
         <trans-unit id="start-driver">
            <source>Treiber starten, sofern er nicht bereits läuft</source>
         </trans-unit>
         <trans-unit id="stop-driver">
            <source>Treiber nach Verarbeiten von Auslösern anhalten</source>
         </trans-unit>
      </body>
   </file>
   </xliff>
   <xliff version="1.0">
      <file datatype="xliff" original="Trigger.xml" source-language="en" xml:space="preserve">
      <header/>
      <body>
         <trans-unit id="job-display-name">
            <source>Subscriber channel trigger</source>
         </trans-unit>
         <trans-unit id="job-description">
            <source>This job submits zero or more trigger documents to the subscriber channel. The submission may either be a document per object if a scope is defined or may be a single document for each job run.</source>
         </trans-unit>
         <trans-unit id="process-unassociated">
            <source>Submit a trigger document for objects without a driver association?</source>
         </trans-unit>
         <trans-unit id="use-job-cn">
            <source>Use Job CN as trigger document identifier?</source>
         </trans-unit>
         <trans-unit id="use-job-cn-desc">
            <source>If set, use the job object's CN as the value of the trigger element's "source" attribute.</source>
         </trans-unit>
         <trans-unit id="trigger-source">
            <source>Trigger element source value</source>
         </trans-unit>
         <trans-unit id="trigger-source-desc">
            <source>String to use as the value for the trigger element's "source" attribute.</source>
         </trans-unit>
         <trans-unit id="submit-method">
            <source>Method for submitting trigger documents</source>
         </trans-unit>
         <trans-unit id="submit-queue">
            <source>queue (use cache)</source>
         </trans-unit>
         <trans-unit id="submit-direct">
            <source>direct (bypass cache)</source>
         </trans-unit>
         <trans-unit id="start-driver">
            <source>Start driver if not running</source>
         </trans-unit>
         <trans-unit id="stop-driver">
            <source>Stop driver when finished processing trigger(s)</source>
         </trans-unit>
      </body>
   </file>
   </xliff>
   <xliff version="1.0">
      <file datatype="xliff" original="Trigger.xml" source-language="fr" xml:space="preserve">
      <header/>
      <body>
         <trans-unit id="job-display-name">
            <source>Déclencheur de canal abonné</source>
         </trans-unit>
         <trans-unit id="job-description">
            <source>Ce travail adresse un ou plusieurs documents déclencheurs (ou n'en soumet pas) au canal abonné. Il peut envoyer un document par objet, si une étendue a été définie, ou un seul document à chaque exécution.</source>
         </trans-unit>
         <trans-unit id="process-unassociated">
            <source>Soumettre un document déclencheur pour les objets sans association de pilote ?</source>
         </trans-unit>
         <trans-unit id="use-job-cn">
            <source>Utiliser le CN du travail comme identificateur de document déclencheur ?</source>
         </trans-unit>
         <trans-unit id="use-job-cn-desc">
            <source>Le cas échéant, utiliser le CN de l'objet Travail comme valeur de l'attribut "source" de l'élément déclencheur.</source>
         </trans-unit>
         <trans-unit id="trigger-source">
            <source>Valeur source de l'élément déclencheur</source>
         </trans-unit>
         <trans-unit id="trigger-source-desc">
            <source>Chaîne à utiliser comme valeur de l'attribut "source" de l'élément déclencheur</source>
         </trans-unit>
         <trans-unit id="submit-method">
            <source>Méthode de soumission de documents déclencheurs</source>
         </trans-unit>
         <trans-unit id="submit-queue">
            <source>file d'attente (utiliser le cache)</source>
         </trans-unit>
         <trans-unit id="submit-direct">
            <source>directe (éviter le cache)</source>
         </trans-unit>
         <trans-unit id="start-driver">
            <source>Démarrer le pilote au besoin</source>
         </trans-unit>
         <trans-unit id="stop-driver">
            <source>Arrêter le pilote à la fin du traitement des déclencheurs</source>
         </trans-unit>
      </body>
   </file>
   </xliff>
   <xliff version="1.0">
      <file datatype="xliff" original="Trigger.xml" source-language="ja" xml:space="preserve">
      <header/>
      <body>
         <trans-unit id="job-display-name">
            <source>購読者チャネルトリガ</source>
         </trans-unit>
         <trans-unit id="job-description">
            <source>このジョブはゼロまたは複数のトリガドキュメントを購読者チャネルに送信します。この送信はスコープが定義されている場合はオブジェクトごとに1つのドキュメント、または各ジョブ実行に対して1つのドキュメントとなります。</source>
         </trans-unit>
         <trans-unit id="process-unassociated">
            <source>ドライバの関連付けなしでオブジェクトに対するトリガドキュメントを送信しますか?</source>
         </trans-unit>
         <trans-unit id="use-job-cn">
            <source>ジョブCNをトリガドキュメント識別子として使用しますか?</source>
         </trans-unit>
         <trans-unit id="use-job-cn-desc">
            <source>設定されている場合、ジョブオブジェクトのCNをトリガ要素の「ソース」属性の値として使用します。</source>
         </trans-unit>
         <trans-unit id="trigger-source">
            <source>トリガ要素ソース値</source>
         </trans-unit>
         <trans-unit id="trigger-source-desc">
            <source>トリガ要素の「ソース」属性の値として使用する文字列です。</source>
         </trans-unit>
         <trans-unit id="submit-method">
            <source>トリガドキュメントを送信するための方法</source>
         </trans-unit>
         <trans-unit id="submit-queue">
            <source>キュー(キャッシュの使用)</source>
         </trans-unit>
         <trans-unit id="submit-direct">
            <source>直接(バイパスキャッシュ)</source>
         </trans-unit>
         <trans-unit id="start-driver">
            <source>実行していない場合ドライバを開始する</source>
         </trans-unit>
         <trans-unit id="stop-driver">
            <source>トリガの処理が終了した場合ドライバを停止する</source>
         </trans-unit>
      </body>
   </file>
   </xliff>
   <xliff version="1.0">
      <file datatype="xliff" original="Trigger.xml" source-language="zh_CN" xml:space="preserve">
      <header/>
      <body>
         <trans-unit id="job-display-name">
            <source>订购者通道触发器</source>
         </trans-unit>
         <trans-unit id="job-description">
            <source>该作业将向订购者通道提交 0 个或多个触发器文档。如果定义了范围,可以对每个对象提交一个文档,也可以对每次作业运行提交一个文档。</source>
         </trans-unit>
         <trans-unit id="process-unassociated">
            <source>为没有驱动程序关联的对象提交触发器文档吗?</source>
         </trans-unit>
         <trans-unit id="use-job-cn">
            <source>将“作业 CN”用作触发器文档的标识符吗?</source>
         </trans-unit>
         <trans-unit id="use-job-cn-desc">
            <source>如果设置,将把该作业对象的 CN 用作触发器元素的“源”特性的值。</source>
         </trans-unit>
         <trans-unit id="trigger-source">
            <source>触发器元素源值</source>
         </trans-unit>
         <trans-unit id="trigger-source-desc">
            <source>用作触发器元素“源”特性的值的字符串。</source>
         </trans-unit>
         <trans-unit id="submit-method">
            <source>提交触发器文档的方式</source>
         </trans-unit>
         <trans-unit id="submit-queue">
            <source>队列(使用超速缓存)</source>
         </trans-unit>
         <trans-unit id="submit-direct">
            <source>直接(绕过超速缓存)</source>
         </trans-unit>
         <trans-unit id="start-driver">
            <source>启动驱动程序(如果未运行)</source>
         </trans-unit>
         <trans-unit id="stop-driver">
            <source>完成对触发器的处理时停止驱动程序</source>
         </trans-unit>
      </body>
   </file>
   </xliff>
   <xliff version="1.0">
      <file datatype="xliff" original="Trigger.xml" source-language="zh_TW" xml:space="preserve">
      <header/>
      <body>
         <trans-unit id="job-display-name">
            <source>訂閱者通道觸發程式</source>
         </trans-unit>
         <trans-unit id="job-description">
            <source>此工作會提交零個以上的觸發文件至訂閱者通道。此作業可能每一個物件提交一份文件 (若已定義範圍) 或可能每一個工作提交單一份文件。</source>
         </trans-unit>
         <trans-unit id="process-unassociated">
            <source>是否要為沒有驅動程式關聯的物件提交觸發文件?</source>
         </trans-unit>
         <trans-unit id="use-job-cn">
            <source>是否要以「工作 CN」 做為觸發文件識別碼?</source>
         </trans-unit>
         <trans-unit id="use-job-cn-desc">
            <source>如果設定,則請以工作物件的 CN 做為觸發元素之「來源」屬性值。</source>
         </trans-unit>
         <trans-unit id="trigger-source">
            <source>觸發元素來源值</source>
         </trans-unit>
         <trans-unit id="trigger-source-desc">
            <source>字串,做為觸發元素之「來源」屬性值。</source>
         </trans-unit>
         <trans-unit id="submit-method">
            <source>觸發文件的提交方法</source>
         </trans-unit>
         <trans-unit id="submit-queue">
            <source>佇列 (使用快取)</source>
         </trans-unit>
         <trans-unit id="submit-direct">
            <source>直接 (不使用快取)</source>
         </trans-unit>
         <trans-unit id="start-driver">
            <source>啟動驅動程式 (若未執行)</source>
         </trans-unit>
         <trans-unit id="stop-driver">
            <source>當完成處理觸發程式時停止驅動程式</source>
         </trans-unit>
      </body>
   </file>
   </xliff>
</job-aggregation>

Conclusion

Once implemented, this driver provides a mechanism to update the Login Time attribute in the Identity Vault to accurately reflect the latest login time across all authentication domains. In a future article, we will discuss a driver to report on a scheduled basis data about the users via HTML eMail generated by IDM.

AttachmentSize
using_the_scripting_driver_to_query_active_directory.doc241.5 KB

Viewing all articles
Browse latest Browse all 30

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>