Thursday, 17 October 2013

Using AppSense DesktopNow to set permissions (Registry and filesystem)

Let's go back to basics a bit today....I still get a lot of email complaining about various limitations in the AppSense DesktopNow products, emails that to be fair would be much better directed at the Feature Request section of, given that I am not a product developer or in any way affiliated with the company :-) Anyway, one that crops up occasionally is people complaining about the fact that they can not set permissions from within AppSense Environment Manager, either on a filesystem or Registry level. You can do it by invoking the legacy binaries or PowerShell, so to save myself sending the same email out again next time I get a query along these lines, I have opted to knock together a (very) quick blog article.

EM versus Group Policy

Microsoft fanbois tend to quite quickly jump on the "you can do it in Group Policy" bandwagon - a bit too quickly, in my opinion. Sure, you can do it in Group Policy, but it's part of the "old" area of Group Policy, in Policies | Windows Settings | Security Settings, and everything in here tends to feel a bit creaky and inflexible. But the very fact that you can do it in here is why I think it would be better done in EM natively - because then you'd be able to take advantage of Conditions and Triggers to set them. In Group Policy land, this isn't even part of Group Policy Preferences, so you don't get Item-Level Targeting on your side.

Setting Registry permissions in GPMC - feels very Windows 2000

Of course, the advantage EM has if that you need to go to a scripted solution, you can call the script natively from within the console and also use Conditions and Triggers to fire it only in specific circumstances. Once you get around to scripting it via Group Policy, you are more or less restricted to calling external scripts from your Logon/Logoff and Startup/Shutdown trigger points provided by the Policies | Windows Settings | Scripts part of GP. There aren't any conditional options available here either - so you're left to build the conditions into the external scripts as well, increasing time and resource needed to put it together.

However, don't think I'm a rabid anti-GPO fanatic - I use Group Policy all of the time and I'm a big fan of it. I just think EM has a couple of advantages over it.

So first we will take a look at the "legacy binary" approach

Legacy binaries - in or out?

A while ago - once even on this blog - I was an unwitting advocate of calling legacy binaries from external scripts in AppSense Environment Manager. Obviously when I realized the error of my ways, I was quite annoyed. Suffice to say, if you're going to go the legacy binaries route, it's more sensible to call them directly from AppSense EM Execute Actions rather than write a batch file, maintain it externally and call out to it from EM.

Pick your tool

Microsoft have given us a few tools down the years for managing permissions - remember cacls.exe and xcacls.exe - and also for Registry permissions - regini.exe being the one most referenced. However, with the advent of Windows Server 2008 onwards we now have the much-improved icacls.exe for filesystem permissions. On a Registry level, the legacy binary I've always preferred is subinacl.exe, although annoyingly it doesn't ship as part of Windows. If you can't drop it into your base image, then you may need to use some sort of function to get it onto your endpoints.

Annoyingly, this is an area where Group Policy seems a lot more robust than AppSense. When performing a Computer Startup Action to do a File or Folder Copy, AppSense EM can be a little flaky, especially when said files are coming from the network. You can use a "Wait for network" Condition such as referenced here to get around this (unless your problems are permissions-related), but it doesn't alter the fact that when you set this sort of file copy up in Group Policy Preferences, it works straight away without any fuss. I guess it's another demonstration of the idea that you should use GP for managing devices and EM for managing the user - but I just think it's a bit vexatious that the functionality for this is in Environment Manager, but just doesn't seem to work to its full capability.

Group Policy Preferences showing EM how to do a machine-level file copy without any drama

Create the Actions

Anyway - once you've got the tools available on your endpoint, it's now time to start altering the permissions using them. The key to this is using Execute Actions using the Parameters section to specify the switches you would normally use on the command line, as shown below

Running icacls.exe from AppSense EM

Subinacl.exe, the swiss army knife of permissions binaries, running from EM

You can alter your permissions in any Trigger or from any Condition you desire, which is the whole beauty of EM. Obviously, though, a native File Permission or Registry Permission Action would be much appreciated!

So next let's quickly look at the scripted options, for those who want to be cool and hip :-)

PowerShell Registry permissions

The PowerShell to set Registry permissions is quite straightforward, so you can import this straight into a Custom Action of type PowerShell

$acl = Get-Acl HKLM:\SOFTWARE\AppSense
$rule = New-Object System.Security.AccessControl.RegistryAccessRule ("JRR\jrrtest","FullControl","Allow")
$acl |Set-Acl -Path HKLM:\SOFTWARE\AppSense

Which works beautifully first time out!

PowerShell file permissions

And doing the file permissions is just as straightforward(ish)

New-Item -type directory -path C:\Test
$Acl = Get-Acl "C:\Test"
$Obj = New-Object"JRR\jrrtest","FullControl","Allow")
Set-Acl "C:\Test" $Acl

Use this or similar in a Custom Action of type PowerShell, and you should be good to go.


So, if you want to do file or Registry permissions from inside of Environment Manager, you can do it either of these two ways. Until AppSense decide to give us a native Action for both of them, which I am hoping they may have on their radar. But don't feel shy about going and filling in a feature request on MyAppSense to give them a bit of incentive to do it.


  1. Good article, but how would you allow users to modify a key that is read-only (for the user) under HKCU?

    Windows makes HKCU\Software\Microsoft\Windows\CurrentVersion\Policies read-only by design...

    I have a requirement to evaluate if user belongs to several groups at login trigger, and set a different registry value to NoDrives and NoViewOnDrive depending on what groups user belongs.

    Because I have 4 different groups to evaluate, this would became a monster of 12 different conditions in AppSense, and very ugly to Service Desk understand.

    I've created a structure that modifies an user variable depending on group membership, followed by a sub node that contains a Powershell script that interprets the variable and defines what value should be added to NoDrive and NoViewOnDrive.

    But now I've hit a brick wall...
    1. The key is read-only...
    2. AppSense actions to write values in registry can overcome this, but it doesn't accept variables as values, so I can't pipe the powershell value back to an AppSense action...
    3. If I try to set this key in the Powershell custom action, it doesn't work because the key is read-only....
    4. If I run the Powershell custom action as "System User" it doesn't work either, as AppSense loads the system user profile and the key that gets changed it is actually in HKCU of system, rather than the interactive user session...
    5. I could easily enumerate the user SID via WMI (after sooo many years, why the AppSense has provided WMI integration to EM? Even GPO has...) , and write to HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\SID, but user won't have permission to write there.... If I run as system, I wound't be able to know what user has to be changed, as the machine may list dozens of different SIDs!
    6. I haven't see any way to input arguments from AppSense conditions or actions into Custom actions, as this would easily solve this issue...

    Btw, AppSense integration with Powershell is just ridiculous... It is using the same principle as they've done with cscript. It just loads a new console process with the script in the custom action. A complex login can have several powershell.exe running and wasting machine resources.... AppSense could do much better on this... but never mind...

    1. Can't you use the Run As user library in EM to achieve this? Or does that load the profile for the Run As-ed user?

      However, surely an easier way would be to use an ADMX Action to set the policy that controls the Registry keys, rather than using the key directly?

      I understand what you're saying about getting the User's SID and storing it somewhere, I tend to set it at logon using a WMI query.

      I will have a bit of a better read through of this tomorrow (just got back from some travel), I might hit you up for some more details so I can understand better.