*This post originally appeared on the AppSense blog prior to the rebrand in January 2017, when AppSense, LANDESK, Shavlik, Wavelink, and HEAT Software merged under the new name Ivanti.


One thing I see often when reviewing configurations is customers still using custom actions/conditions to achieve goals that can be addressed natively with the latest versions of our products, even after upgrading. While many of these approaches may “do the job”, there is a better way.

The most common example of this by far is “Profile Spoofing”, where a custom action changes the user's profile type within:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\<SID>

Typically, this is done to change a mandatory profile to appear to the OS as a roaming profile and allow certain types of certificates to roam.

In this case, the engineering setting SpoofProfileForWholeSession was added way back with Environment Manager 8.1.544 and made readily available via the console in 8.3.157.

For the vast majority of configurations, this custom setting alone is all that’s required.

Another common use of custom actions is to pass variables to a command line utility, such as RoboCopy. Since RoboCopy allows the use of environment variables, the use of a custom action to achieve this is often unnecessary, and it would be faster to just run an Execute action directly. More importantly, however, and more relevant, Mirror and Sync folder actions were introduced in Environment Manager 8.3, and merged to a single Copy Folder action in Environment Manager 8.5 (with a drop-down to set the type as Copy, Mirror or Sync). Whilst this may not offer all the options of utilities that RoboCopy does, the most common options included, such as folder depth to copy, file attributes, security / owner information, date / size comparisons, folder / file exclusions, etc.

As for custom conditions, the most common I see is checking if a registry value is set to a specific value. This too can be achieved using the native “Registry” conditions.  Though the UI shows these as simply “Key Exists” and “Value Exists”, both contain further options for greater flexibility. In particular, the Registry Value Exists condition has operators (comparison modes) for:

  • Exists
  • Does Not Exist
  • Value Type Exists
  • Equal To
  • Not Equal To
  • Less Than
  • Less Than or Equal To
  • Greater Than
  • Greater Than or Equal To

I ran a simple test with two process start nodes – one for calc.exe, one for notepad.exe.

Within the notepad.exe node was a custom condition to check for the existence of a registry value using vbScript’s shell.regread method, whilst the calc.exe node used an EM Registry Value Exists condition. Examining the logs of both over several runs, the scripted method typically took 983ms, and the native method typically took 125ms. Most of this time is spent writing out the custom action to a .vbs file and then calling wscript.exe. Powershell is slower still, as launching the host takes much longer than wscript.

Session Variables – Your secret friend

A related feature that can be greatly beneficial is Session Variables. These were introduced in Environment Manager 8.4. However, in Environment Manager 8.5 onwards they can be used in most native actions and conditions, such as passing a session variable to a file/folder/registry action. There are a number of built-in Session Variables, which can simplify many common scenarios:

SessionID - The current Session ID

UserSID - The user’s Security Identifier

UserTemp - The location of user’s Temporary Directory

As an example, creating a variable for the users SID is often done with a custom action using WMI, such as the below:

Screen Shot 2015-05-06 at 3.45.45 PM

However, using Session Variables this can be achieved with a single action to just set the “UserSID” variable to its Session Variable equivalent, ie “$(UserSid)”:


Again, using process start actions for calc and notepad, we can capture logs for each of these to determine the difference. In my case, the custom action approach took 1139ms, whilst the Session Variable approach took 110ms. Furthermore, this may not even be required, as everywhere that you may need the user's SID, you can just use “$(UserSid)”, rather than “%UserSid%” (once set). Why set a variable in the first place, if the Session Variable already exists?

If you feel other internal variables should be exposed as session variables natively, then I’d urge you to raise feature requests for them. The most commonly requested may then be added to the product in a future release, so always check the Product Guides.


Always review what features have been introduced when you upgrade, in relation to the version you’re upgrading from. You can do this by reading the updated product guides, or looking at any custom actions / conditions you have, and then checking in the latest console to see if there’s functionality that achieves the same result. Session Variables are detailed within the “AppSense Environment Manager Policy Product Guide.pdf”