I guess this is more of a suggestion/idea than question, but someone might know a work around. I wish we had a field in Forms that could use active directory to pull names. That way we can avoid misspelling and updating a drop down list. I'm trying to create an "assigned to" field and I would love if it was similar to how we select an assignee for an user task in Forms
Question
Question
Answer
While I didn't actually use AD, I used a view that pulls info from the cf-users table in the Forms database. It seems to be storing all the users in Forms System Security. For my purposes, this is a better list than AD because only employees with Forms licenses are displayed:
SELECT username, user_type, displayname
FROM dbo.cf_users
WHERE (username LIKE 'OurDomain%') AND (user_type = '1')
Replies
For posterity's sake, if you dare to try configuring a linked server like Eric described above, below is how you can do it using MSSQL and SQL Management Studio. Familiarity with SQL helps, and familiarity with the structure of Active Directory you wish to query is required. Tools like ADExplorer from SysInternals can help with that.
Step One: Create a Linked Server
- In SQL Management Studio, connect to the SQL server. In the Object Explorer, expand the "Server Objects" node and right-click on "Linked Servers" to add a new one. You will get the "New Linked Server" dialog.
- Give the Linked Server a name. In the attached example 1-LinkedServerGeneral.png, I named mine "ADQUERY".
- For "Provider", select "OLE DB Provider for Microsoft Directory Services".
- For "Product Name", enter "Active Directory Services 2.5".
- For "Data Source", enter "adsdatasource".
- Go to the Security page in the left pane. By default connections will not be made with any security context, which in most cases will cause errors when trying to make the query. If using Windows authentication with an account that has rights to query AD, you can choose "Be made using the login's current security context". (2-LinkedServerSecurity.png) To be safe, you can specify a security context and provide the credentials to use to query AD.
- Click OK and you've got yourself a linked server!
Step Two: Structure of Query for this Linked Server
You can use SQL-style queries to query this new linked server:
SELECT * FROM OpenQuery( <LinkedServerName>, 'SELECT <ADAttribute1>, <ADAttribute2>, ..., <ADAttributeN> FROM ''LDAP://<domain>.<ext>/<BaseDistinguishedName>'' WHERE objectClass = ''User'' ')
There are a lot of variables to play with here:
- <LinkedServerName>: the name of the linked server from Step One above.
- <ADAttribute#>: attributes in Active Directory; for example displayName, cn, sn, mail, memberOf, etc.
- A good reference for user attributes in Active Directory is available online here.
- Note that you must specify attributes here for the results to be meaningful; if you try to use wildcard (*) the results will not be useful values, but instead LDAP:// URIs for the returned users.
- <domain>.<ext>: the domain of Active Directory you are querying
- <BaseDistinguishedName>: the distinguished name of the "maximum" organizational unit you will be querying; at minimum this will probably include "DC=<domain>,DC=<ext>"
Here's an example:
SELECT * FROM OpenQuery( ADQUERY, 'SELECT displayName, mail FROM ''LDAP://mydomain.com/OU=Users,DC=mydomain,DC=com'' WHERE objectClass = ''User'' ')
This returns SQL results in two columns: 'displayName' and 'mail'.
You can actually extend the query to include more WHERE and ORDER BY just like in SQL, using attribute names as though they were SQL column names. A useful example for the use case in this thread could be as follows:
SELECT * FROM OpenQuery( ADQUERY, 'SELECT displayName, mail FROM ''LDAP://mydomain.com/OU=Users,DC=mydomain,DC=com'' WHERE objectClass = ''User'' AND memberOf = ''CN=Sample Group,OU=My Group,OU=Users,DC=mydomain,DC=com'' ORDER BY displayName ')
This example returns all users from my fictitious Active Directory setup who are part of a group "Sample Group", ordered by their display names. Note the additional "memberOf" clause. The value is the distinguished name of the Windows group. How to find this? You'll have to get familiar with Active Directory. The tool I use is ADExplorer from SysInternals, mentioned previously.
One final note, for those following along in SQL Management Studio, is that when the query results are returned, the columns will be in the reverse order as specified in the query. So for example, if running the above query, the 'mail' column will be shown first, then the 'displayName' column.
Now to prepare this for use with Forms.
Step Three: Write a Stored Procedure to Query Active Directory
SQL-savvy folks can come up with queries that will take in parameters, etc. For now, here's code that will create a stored procedure that will run the Active Directory query from before:
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE sp_adquery AS BEGIN SET NOCOUNT ON; -- here's the query from before SELECT * FROM OpenQuery( ADQUERY, 'SELECT displayName, mail FROM ''LDAP://mydomain.com/OU=Users,DC=mydomain,DC=com'' WHERE objectClass = ''User'' AND memberOf = ''CN=Sample Group,OU=My Group,OU=Users,DC=mydomain,DC=com'' ORDER BY displayName ') END GO
In SQL Management Studio's Object Explorer, expand the Databases node, navigating to the database used as an external data source in Forms, then expand the Programmability node. Right-click on "Stored Procedures" to create a new one. Replace the code in the query tab with the code above.
Now if you set up the external data source in Forms and configure a lookup rule (nothing fancy here, just treat it like any other stored procedure), you should be able to set up something like 3-LookupRulesConfig.png. Then when viewing the form you should be able to get the results of the stored procedure querying Active Directory.
For an extra step, one could create a "dictionary" of Windows groups and their distinguished names, then use that as an intermediate step to pass a parameter to the stored procedure so one could select a Windows group by its display name in one field, that then populates another with a list of users in that group.
Apologies for the wall of content, and I hope this helps!
This is interesting LOL!...I know when to take a step back and reexamine my "Laserfiche Life Choices". This is definitely for the future ME!
While I didn't actually use AD, I used a view that pulls info from the cf-users table in the Forms database. It seems to be storing all the users in Forms System Security. For my purposes, this is a better list than AD because only employees with Forms licenses are displayed:
SELECT username, user_type, displayname
FROM dbo.cf_users
WHERE (username LIKE 'OurDomain%') AND (user_type = '1')
That's very clean, for purposes of choosing a user involved in the process. The WHERE part of the query can be modified to even include non-domain accounts with Forms logins. I recommend making this the marked answer.
The context for when I discovered how to set up the linked server stuff in my post was for a drop-down list that needed to be able to include people from our organization who were not necessarily part of the Forms process, so for that case in particular this would not have worked.
I will look into this...This seems like something my IT department might be able to fix up for me.
Glad I started this suggestion...Laserfiche community always has a great idea/workaround!
@████████ i'm still having trouble with configuring this the way it was mentioned above by Sheila. I am having trouble with the WHERE part. So following the model you came up with...How exactly would I fill out my javascript? Is "where" the actual field on the form
This isn't in the javascript. It's the SQL used for the view that I created in the database.
I'm not a DBA, so you DBA's out there may cringe at this :)
In your database, right click on Views and select New View.
Close the box that asks you to select a table.
The bottom pane shows the current SQL, which is simply
FROM
WHERE
Change it to
SELECT username, user_type, displayname
FROM dbo.cf_users
WHERE (username LIKE 'OurDomain%') AND (user_type = '1')
replacing "OurDomain" with your domain name.
Select File > Save and give the view a name. Save it and now you have a view that can be used for doing a database lookup. You don't need the username comparison above if your domain name isn't part of the username stored. Our is, and the comparison weeds out some of the usernames that don't belong to the staff.
Once you have the view created, you go into the form where you want a list of usernames and configure it on the Lookup Rules tab.
I hope that helps!
A slightly cleaner alternative approach to the same idea had later been posted here.
I've done this before. You need to create a "Linked Server" in your Laserfiche SQL Server to the AD Server. Once this is configured, then you can design a View that can suit your needs.
I can't be much help as far as the actual configuration details are concerned. I usually have a DBA help configure this.
Hope this helps!
I replied with a similar solution to James but for some reason my reply didn't upload until after James had replied and his looks much better so I've deleted mine. :o) However the reason I set it up for myself, in addition to getting the username, email, and department, was in order to configure Form routing to an AD user's manager, retrieving the manager's name from AD. Problem with that is that querying AD for the SQL table will bring the manager's name back in "CN=..." format so you need to add another column to the table in SQL, and run an additional query to provide the name in "Firstname Lastname" format.
(Note that this process is limited to a maximum of 1,000 entries.)
I don't have DBA skills so didn't take the Stored Procedure route, just manually created the table with column headings matching the attributes I'm pulling from AD, set up the linked server then set up a SQL query that I run on schedule to pull the required data from AD and overwrite the data in the table (trying to work out how to update the data rather than overwrite it got way too hard for my limited skills).
Here's the initial query where the linked server name is "ADSI" and I'm retrieving all User accounts from AD that have email addresses:
USE [ExternalTables] GO DELETE FROM [dbo].[AD_Staff] WHERE mail is not null GO INSERT INTO AD_Staff(samAccountName, [First Name],[Last Name],displayName,mail,department,manager) SELECT samAccountName, givenName [First Name],sn [Last Name],displayName,mail,department,manager FROM OPENQUERY(ADSI,'SELECT samAccountName,givenName,sn,displayName,mail,department,manager FROM ''LDAP://DC=DEMO,DC=LOCAL'' WHERE objectClass=''Person'' AND objectClass = ''User'' ORDER BY samAccountName') WHERE mail IS NOT NULL
Below that I've added following lines to format the manager's name:
Update AD_Staff Set [ManagerName] = REPLACE(SUBSTRING([manager],4,CHARINDEX(',OU=', [manager])-4), '.','') where manager is not null
And finally, I've saved the query as "D:\SQL_Queries\SyncAD.sql" and configured the following command in Task Scheduler to run the process on schedule:
sqlcmd -S servername -U user -P password -i path_to_query
... with sample data it looks like:
sqlcmd -S .\SQLEXPRESS -U Scheduler -P password -i d:\SQL_Queries\SyncAD.sql
Not as refined as James's solution, but workable.
I like the solutions you've come up with for accessing information in AD, and I'm sure we'll use those in the future. There are times when we'll want to show all names in the company and not just those in Forms.