User Schedules with Active Directory

Starting a new topic, because this one has been out there for a few years now with no solution.

How are user schedules defined with an Active Directory user source?

When looking at ‘manage users’ there is a field for ‘Schedule’ and there is a ‘Schedule Restricted’ option in the user source configuration, implying that schedules should work, and I imagine the idea is that schedules are pulled from AD, just like everything else. But as far as I’m aware, schedules aren’t a thing in AD – the AD administrator would have to create custom attributes, and then what is even the format that they would need to be defined in AD to map to Ignition schedules?

I have a project where the client wants IT to be responsible for user’s roles and contact info, but I also need to define schedules for alarm notification. Am I stuck with either the former (full AD integration) or the latter (AD/Hybrid)?

Unfortunately, there’s no code to attempt to bring in schedules from AD on Ignition users, so there’s no way to define things in AD and have them brought in as a schedule.

If you just need to define schedules, then you could try getting a little bit hacky - define a pure AD ‘real’ user source, then copy specific usernames into a purely internal (or database) user source where you define schedules. Then in your alarm notifications, you could use system.user.getUser to retrieve the same username (in a different user source) and retrieve their schedule.

Thanks, I’ll try and get IT on board with doing hybrid integration, and try this if that’s a no-go.

Is this feature (allowing schedules to be assigned to users from a pure AD user source) something that can/will be added in a future release?

Well, as you mentioned, the tricky part would be modeling schedules in a way that maps to what active directory can actually provide. Theoretically some text-based encoding like JSON might work, but that’s a pretty fragile mechanism.

There’s also the complication that at some point, everything in the gateway, designer, etc will use web-based identity providers - either exclusively or preferentially. In that model, Ignition wouldn’t have to do low-level AD operations manually, and it would be a case of bridging information the identity provider sends to Ignition information. Parsing schedule information (in some way) out of an identity provider is probably more likely to happen than adding schedule parsing to the existing AD user source - but that doesn’t mean either will ever happen.

You’re welcome to post this to https://ideas.inductiveautomation.com/, though - ideas posts are a great way for us to gauge community interest in a feature, which is a big part of deciding whether to integrate it.

Yeah, pulling in schedules seems pretty complicated – I was just looking for a way to connect schedules created in Ignition to users pulled in through AD, without using AD/Hybrid. Basically a built-in version of the ‘hacky’ solution.

But thank you for the info, I will definitely post this there!

How would you recommend copying specific usernames into an internal user source where schedules are defined? Manually? Is there someway to do this automatically at an interval?

Anything's possible with scripting, but there's nothing available "out of the box".

Is there an existing gateway variable I can poll users from a User Source and create/update another User Source? I'm not finding it but I want to verify before I stick my head into that wasp's nest. Otherwise I'm looking at creating a Gateway script that runs every hour and using python ldap to poll users from AD and push to a database (update everything but schedule) and then setup the database User Source so schedules can be adjusted.

https://docs.inductiveautomation.com/display/DOC81/system.user.getUsers
https://docs.inductiveautomation.com/display/DOC81/system.user.addUser

I'm not really sure what you're asking for with "gateway variable".

That's exactly what I needed. Thanks!

For anyone who needs it/has improvements I ended up using the code below. It will grab users from an AD User Source, grab the Schedules from an Internal User Source, combine the two, and remove + add users back into the Internal User Source. I used a gateway timer delay event. Not sure how it will impact CPU with thousands of users but I'll find out next week.

#grab all users from Active Directory. I called the "User Source" domain2
domainUsers = system.user.getUsers("domain2")

for user1 in domainUsers:
#	if user already exists in internal "User Source"
	try:
#		get the user from internal "User Source". I called it NewProfile. Will be used later to grab the schedule
		userInternal = system.user.getUser("NewProfile", str(user1.get("username")))
		if (userInternal.get("Schedule") <> "Always"):
#			get schedule from internal User Soucr and set it to currently selected domain user
			user1.set("Schedule", userInternal.get("Schedule"))
#			remove the user from internal "User Source" schedule to allow contact info to populate correctly
			system.user.removeUser("NewProfile", user1.get("username"))
		
	finally:
#		add user from domain "User Source" to internal "User Source"
		system.user.addUser("NewProfile", user1)
	

EDIT: Thanks for the info about </>!