# Retrieve Active Directory Users on a Perspective Component

**URL:** <https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138>\
**Category:** Ignition\
**Tags:** perspective, scripting\
**Created:** [July 10, 2023, 3:18pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138 "2023-07-10T15:18:20Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kawsar\_Ahmed](https://avatars.discourse-cdn.com/v4/letter/k/8797f3/32.png) [@Kawsar\_Ahmed](https://forum.inductiveautomation.com/u/Kawsar_Ahmed)\
**Post date:** [July 10, 2023, 3:18pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/1 "2023-07-10T15:18:20Z")

</div>

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:

```auto
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!

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [July 10, 2023, 3:20pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/2 "2023-07-10T15:20:34Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Kawsar\_Ahmed](https://avatars.discourse-cdn.com/v4/letter/k/8797f3/32.png) [@Kawsar\_Ahmed](https://forum.inductiveautomation.com/u/Kawsar_Ahmed)\
**Post date:** [July 10, 2023, 3:52pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/3 "2023-07-10T15:52:12Z")

</div>

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:

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

print(flat_list)

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 10, 2023, 4:05pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/4 "2023-07-10T16:05:26Z")

</div>

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

You need to extract the .value property.

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [July 10, 2023, 6:14pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/5 "2023-07-10T18:14:34Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Kawsar\_Ahmed](https://avatars.discourse-cdn.com/v4/letter/k/8797f3/32.png) [@Kawsar\_Ahmed](https://forum.inductiveautomation.com/u/Kawsar_Ahmed)\
**Post date:** [July 11, 2023, 2:09pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/6 "2023-07-11T14:09:34Z")

</div>

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

```auto
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

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 11, 2023, 2:35pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/7 "2023-07-11T14:35:46Z")

</div>

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.

```python
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

```

---

<div class="post-metadata">

**Author:** ![Kawsar\_Ahmed](https://avatars.discourse-cdn.com/v4/letter/k/8797f3/32.png) [@Kawsar\_Ahmed](https://forum.inductiveautomation.com/u/Kawsar_Ahmed)\
**Post date:** [July 12, 2023, 4:47pm UTC](https://forum.inductiveautomation.com/t/retrieve-active-directory-users-on-a-perspective-component/76138/8 "2023-07-12T16:47:11Z")

</div>

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.

```auto
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

```
