Retrieve Active Directory Users on a Perspective Component

I am trying to create a dataset out of all user in the active directory to be used in a perspective drop down, but I am running into a few errors.

I first created a simple script named 'getUsers':

users = system.user.getUsers("AD")

Then I bound it to the option properties on the dropdown component using the following expression:

runScript("getUsers")

However, I get the error that the expression is retrieving a string but is expecting a string/dataset. So my next step was to convert the python list into a dataset using the following script:

headers = ["User", "First", "Last", "Roles"]
data = users = system.user.getUsers("AD")

users = system.dataset.toDataSet(headers, data)

print(users)

When I do this I get the following error: "TypeError: toDataSet(): 2nd arg can't be coerced to org.python.core.PySequence"

This may be due to the structure of the list that is produced by the getUser function. When printed it displays a list in the following format:

[User[username=user, firstname=Kawsar, lastname=Ahmed, roles=[role1, role2, role3..]], User[username=user, firstname=Kawsar, lastname=Ahmed, roles=[role1, role2, role3..]]...]

Has anyone encountered something similar that may be able to help me?

Thanks!

You'll have to process the returned list of nested objects into a list of flat objects that your component understands.

When I flatten the list, it no longer returns the values, but returns a list that looks like:

[com.inductiveautomation.ignition.common.config.PropertyValue@435571909, com.inductiveautomation.ignition.common.config.PropertyValue@435ea1909, com.inductiveautomation.ignition.common.config.PropertyValue@43071909, com.inductiveautomation.ignition.common.config.PropertyValue@43071909,...]

I used the following script to flatten the list:

flat_list = []
for sublist in data:
      for x in sublist:
           flat_list.append(x)

print(flat_list)

PropertyValue is a complex object:
https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.29/com/inductiveautomation/ignition/common/config/PropertyValue.html

You need to extract the .value property.

Please edit your two posts above (pencil icon) select the code blocks and format it correctly with the </> button.

Thank you very much! I used the following code snippet to extract the value and it worked (kind of):

headers = ["user", "first", "last", "roles"]
data = system.user.getUsers("AD")

filters = ['role1', 'role2']

filteredData = []
for sublist in data:
     if any(item in filters for item in sublist):
        continue
     filteredData.append(sublist)

flat_list = []
for sublist in filteredData:
     for x in sublist:
          flat_list.append(x)

extracted = [propertyValue.value for propertyValue in flat_list]

users = system.dataset.toDataSet(headers, extracted)

print(users)

Now a couple of new errors come up.

  1. I would like to filter some users out if they do not have the roles in filters. However when I run the loop and print the outcome of filteredData it is no different from the original data set. (The case is the same whether I filter prior to or after flattening)

  2. The flattened list is missing data that was once in the nested list (some users are missing their roles, it doesn't show as an empty set either.) This was not caused by the filter as I tested it by commenting out the filter portion.

  3. When trying to convert to a dataset, I get the following error: IndexError: Row 0 doesn't have the same number of columns as the header list. I believe this may be tied to issue 2

So, I think you want something like this. Keep in mind that depending on where you're using it, you don't really want to try to embed nested complex data (such as an arbitrary length list of roles) into a dataset column, so I joined them into a comma separated list.

headers = ["user", "first", "last", "roles"]
users = system.user.getUsers("default")

filters = ['Administrator', 'Operator']

extracted = [
	[
		user.get(user.Username),
		user.get(user.FirstName),
		user.get(user.LastName),
		', '.join(user.roles)
	]
	for user in users
	if any(role in filters for role in user.roles)
]

ds = system.dataset.toDataSet(headers, extracted)
print ds

This worked perfect for me thanks! I adjusted the code a little to only extract the username twice. This way when bound to the options of the dropdown menu the username will be visible as well as stored in the database.

def transform(self, value, quality, timestamp):
	headers = ["Value","Label"]
	data = system.user.getUsers("AD")
		
	filters = ['Operator', 'Supervisor']
		
	extracted = [
		[
			user.get(user.UserName),
			user.get(user.UserName),
			]
			for user in data
			if any(role in filters for role in user.roles)
		]
			
	users = system.dataset.toDataSet(header, extracted)
	return users