You may already be aware that Citrix doesn’t natively support a simultaneous logoff for a user’s published app and desktop sessions. In point of fact, this problem is likely better addressed through effective Citrix policies surrounding idle logoffs. However, I had a customer with enough users and resource bottlenecks to justify this workflow, and so I’ll leave this for anyone else who might relate. Just in case it needs to be said: this entire process assumes your users are accessing their published apps exclusively from published/virtual desktops. This strategy will bring nothing but chaos to any other situation. Lastly, the solution described here will make use of an environment manager–in my case: Ivanti/AppSense.
My customer’s problem was essentially with resource scarcity. They had a large enough user base and tight enough bottlenecks that, during a shift change, users would find themselves competing for sessions on published app servers. Although users were trained to log off their PDs at the end of a shift, they couldn’t reliably log off app sessions on those desktops. These sessions would get disconnected and wait to be released by Citrix idle policies. The idle logoff time was already pretty aggressive, and decreasing it further would have disrupted their basic roaming functionality.
Depending on the version of Receiver you’re using, you will either have access to pnagent.exe or SelfService.exe. These executables provide an interface to logoff connected sessions. Understandably, you might consider issuing the relevant /logoff command during the desktop’s logoff sequence–either by way of a scheduled task or an environment management like Ivanti. That was certainly my first idea… but there’s a problem. These self-service commands only work on connected sessions. And what’s the very first thing that happens during a logoff? Yep.
So, unless we can run our command preemptively before the disconnect (which I think requires precognition), we’ll need another approach. This is where the environment manager comes in. The instructions below will presume AppSense/Ivanti. For those of you without something similar, hopefully this post can provide something of a roadmap if not a direct solution.
Effectively, we will wait for our user to log off their PD session. At that time, we will create an arbitrary–but very specific–folder on a network share. A file would work just the same, but AppSense does not presently have a “create file” action.
This folder will act as a beacon to indicate a desktop logoff has occurred. Lastly, whenever our app server detects that a session has disconnected, we will tell it to check for this folder. If the app server finds the folder, it can be certain the user has logged off their desktop, and it can safely log them off as well–freeing resources for someone else.
Decide on a folder name. It will never be accessed or used except as a reference point, so it’s not too important what you call it. It just needs to be unique and unlikely to exist under any circumstances but those we create.
Now, we need to store this folder on a network share that’s writable by the user, and accessible from both our PD and PA servers. If your users do not have individual shares, you can always place it in a central share and name it something like %USERNAME%LOGOFFBEACON. Otherwise, placing it in the user’s own share probably makes more sense.
So, in your published desktops’ Environment Manager policy, add a new Create Folder action under the Logoff trigger. The path should look something like this:
Make sure your Environment Manager agent is installed on your published app servers. Again–failing that-you will need a means of detecting when a user disconnects from their session. On your application servers’ Environment Manager policy, create a new File Exists condition under the Session Disconnected trigger. Check whether the folder you defined in step 1 exists.
From here, create a new Execute action to be nested under this condition. Simply run shutdown.exe /l. This is, of course, the command to log out from a session. But wait! One more thing:
Create a new Delete Folder action to be nested under the Execute action from Step 2. Delete the folder you created in Step 1.
This will ensure that the folder is only present long enough to trigger the single logout we want. If you forget this step, the folder will exist permanently or until someone manually deletes it. If that never happens, a user will have their published app session logged out automatically every time they disconnect from it. Needless to say: do not skip this step!
That’s it! Again, if this did not solve your problem directly, I hope it at least inspired you to find one that meets your needs better, or that doesn’t require the environment manager. In any case, feel free to leave any feedback or suggestions below.