Are you the publisher? Claim or contact us about this channel

Embed this content in your HTML


Report adult content:

click to rate:

Account: (login)

More Channels

Channel Catalog

Channel Description:

IT Consultancy in the North East of England

(Page 1) | 2 | 3 | .... | 9 | newer

    0 0

    This week I was privileged to be invited to attend the inaugural ACA Summit at AppSense HQ in Daresbury. The stated goal of the AppSense Community Advisor program (ACA) is to "recognize exceptional community leaders from around the build a global technical community of experts in the Enterprise Consumerization market". It is intended to work along the same lines as Citrix's CTP and Microsoft's MVP programs, and I was quite honoured to sit around the table with a group of recognized independent experts in the AppSense field, amongst them CTPs and MVPs. It just goes to show a little blogging can go a long way, I suppose!

    It's important (for me, anyway) to note that being part of the ACA program doesn't in any way affect my status as being independent and fairly vendor agnostic (the irony of my blog title and Twitter moniker aside). I'd like to say that if AppSense put a product or feature out that I feel doesn't bring anything of value to the table I wouldn't hesitate to point out my opinion. But what the ACA does bring, especially in those sort of scenarios, is a close engagement with the guys who actually design, market and direct the product lines, and an ability (hopefully!) to channel the product a bit in ways that actually make a difference in the real-world scenarios that we face on a regular basis. It was interesting to hear from Keith Turnbull who was involved in the CTP program in its early days talking about lessons learned from those experiences.

    I have to say that I found all of the AppSense staff really genuinely passionate about the products that are currently available and the plans they have for the future. It was nice to get a feel for the way the existing product lines actually developed and to see how they were making plans to align them for future developments. I think there's sometimes a tendency for software vendors to try and invent problems to fit with the solutions they have available, but some of AppSense's newer products - particularly DataNow - seem to be dealing with real-world issues that are touched on by IT departments in a lot of the environments I work in. Seeing the features of DataNow in use has definitely given me a bit of impetus to finally finish the posts I've been intending to publish on it for a while now.

    It was also good to get involved in discussions with guys who work in different customer environments from the ones I generally find myself in and hear how they were using AppSense to tailor solutions to particular problems. Aaron Parker gave us an overview of the "lite" configuration he put together and which is hosted on his blog (intended to be implemented without the need to stand up a Personalization Server infrastructure for POC situations), and I was a bit embarrassed to realize I'd actually failed to realize the point of it when I first read his article :-0

    Another very interesting side of the event was seeing the plans being made for improvement of the actual AppSense console interface. Because I'm so familiar with it I'd actually forgotten how unintuitive the consoles can actually be to a user who is coming across them for the first few times. I think AppSense's UI has suffered in that it is generally meant to be used by technical people, but just because techies will be using it doesn't mean that it should be acceptable if it is clunky or illogical in its presentation. If the consoles evolve in the way AppSense are imagining they should, I can see a lot of users being won over.

    Yet another part of this that stuck in my memory (I am sure all the other ACAs noticed that I don't bother to take notes, either electronically or on paper) was the fact that almost 10% of AppSense's total staff are involved in QA. The guys I spoke to in this area were looking for feedback from the trenches about how to improve their processes and I had to admit that given the diversity of platforms and applications that their software runs on or alongside, they still seemed to be quite optimistic that they could continue to do it better and more comprehensively. A lot of QA and testing guys I had previously spoken to from other companies often seemed to be quite resigned and/or potentially suicidal, so it was nice to see them fairly upbeat for a change :-)

    So hopefully the ACA program will, amongst other things, allow us to enable users and administrators dealing with the software on a day-to-day basis to channel their experiences back more effectively to the people who develop it, as well as allowing the software developers to reach out into the technical community and get feedback on their features and future plans. But most importantly, it gives us an opportunity to add to the knowledge we already possess and share this knowledge in a way that benefits both AppSense and their customers. It's been a very rewarding couple of days and I have plenty of material to cover in my next few blog posts which should hopefully explore a few new avenues in the Management Suite and the other products that AppSense are slowly but surely bringing to market. I'd just like to thank Benny Tritsch, Keith Turnbull and all the staff at AppSense for introducing the ACA program and for being so hospitable during our visit. And on a personal note, it's been quite humbling to sit amongst a gathering of AppSense gurus and exchange thoughts and ideas. For someone who just started blogging to keep himself out of hotel bars Mondays through Thursdays, I certainly seem to have come quite a lot further with this than I expected to when I put up my first post!

    Read more about the inaugural ACA members on the AppSense company blog here

    0 0

    Let's have a bit of a departure from our normal fare today. This is more on the consumer side of things than the enterprise, and hopefully should be a solution to a problem that's bitten me on more than one occasion. When you lose a device - such as a hard drive failure on a laptop - how do you get past the problem of reinstalling and reconfiguring all your applications? What happens if you miss one out? Is there any way, using free tools, that you can mitigate against this sort of problem?

    In an enterprise environment I'd simply (!) recommend using something like Citrix, App-V or AppSense StrataApps to deliver the applications back down to a newly-imaged device, which would then use AppSense Personalization Server to resupply you with all of your configured settings. But from a consumer's point of view this is a complicated and often expensive solution. For myself at home, setting up the infrastructure required to support something like this is quite frankly not an option.

    However, for years I've used a copy of Firefox Portable on a USB stick to carry my browser bookmarks and add-ons with me from place to place. The problem in this instance always came from leaving the USB key behind and having to install a new copy of FF Portable, before finding out that you need another device or the Recovery Key to use Firefox Sync correctly. But with the advent over the last couple of years of DropBox, which I've found eminently useful, that set me thinking if I could use DropBox instead of the USB key. It certainly seems like an idea worth exploring a bit further!

    Now I know you can use AppSense's new product DataNow in the same way as DropBox, but for the purposes of this article - which is aimed at consumer-level users, don't forget - I'm also going to consider the use of DataNow to be out-of-scope due to the extra setup involved. However, if you are a customer who uses AppSense Management Suite but doesn't use an application delivery platform such as Citrix, App-V or RDS (and I'm not entirely sure that any of those actually exist), you could certainly use DataNow in the same way I'm about to describe here - but I'm not sure how much value you would actually get from it. Certainly in an enterprise environment it would be far more cost-effective to simply purchase and use one of the delivery platforms specified rather than try to make DataNow function as a cheap alternative to one of these. But I'm digressing.

    So, let's start by installing the DropBox Client onto the laptop. Normally you need administrator rights for this, but if you don't have them, then here's a good use case for AppSense StrataApps :-)

    Once the client is installed and set up, which doesn't take long at all, we need to download the portable application we're intending to use first. In this case, we will select the portable version of Firefox and download it from SourceForge

    We will save the downloaded executable into the DropBox folder. We have created a subfolder called Apps that will keep our applications separate from all the other stuff we have in DropBox (lots of it!)

    Now we'll run it.

    Now, when we arrive at the installation location section, we will see that the installation path is already pre-populated with a subfolder in the DropBox folder. This keeps things neatly compartmentalized again, so we will accept the default.

    And now we will run our portable Firefox just to ensure everything works as we want it to. In this case, this means verifying that Firefox Sync is working, and that we can see all of our add-ons

    Here's all of our bookmarks....

    ...and here we have some common add-ons loaded

    Now, we need to simulate a hard drive failure :-0 Luckily I have an unused laptop we can pretend has just been factory restored. The idea is, when I log on to this new machine, is that all I need to do is install the DropBox Client and we should have access to all my applications and settings. So we will install the DropBox Client first and configure it to connect to my account in the normal fashion. You should see it downloading the updated files when it connects to the Internet (although hopefully you'll have a better connection than the wireless in the image below!)

    Next we will simply try to run Firefox Portable from the machine that it has just synchronised to. Let's see what happens. Firefox starts OK, and we have bookmarks...

    ...and we have our add-ons. Actually, we have an extra add-on, as the new computer already had Avast installed on it!

    One glaring problem with this, though, is although the application is now "installed" on all your Dropbox-enabled devices, it won't create a shortcut unless you do this yourself, whether it's by creating it on the desktop, pinning to Taskbar, etc. However, if you are on Windows 7 or greater, you can use the Search feature on the Start Menu to easily type the name of the application in and find it, provided that the local Dropbox folder is indexed (it should be, as it is normally sat in %userprofile%). Once you've typed and found it once, you can easily pin it or create a shortcut as you require. There are any number of ways you could recover or maintain your previous shortcuts and restore them to the new imaged laptop - but that's a bit out of scope for the article itself.

    It's also quite cool that when I launch the application on the laptop without Avast installed, the Avast add-on doesn't load or try to load. However, an obvious drawback is that you can't use the application on two or more machines simultaneously and not expect there to be any problems with file locks as they try to synchronise back - but that's not a major pain point for the use I am going to put it to.

    So, I suppose, what else is available in a portable application format that we can do this nifty trick with? So far, I have "virtualized" (if that's really the word for it) Firefox (as seen), Sumatra PDF, VLC Media Player and Mozilla Thunderbird. Not a bad start for my goal of being able to have a PC or laptop die and then simply install the Dropbox Client on my new one, and synchronise my applications back. However, there are a lot more I'd like to see on there - MRemote, 7Zip and Notepad++ are the ones I am after next, but I'm not sure whether they are available in a portable format.

    One final thing to note is that if you end up using the web-based version of DropBox, this approach won't be very useful unless you actually manually copy the files down locally and then copy them back. If you don't have administrative control of the device, performing this routine will be very difficult, unless your IT department have embraced a piece of UIA technology such as AppSense StrataApps. And if you share your device with another user and you both want to use this approach, you'll have to install your apps into two separate folders inside DropBox, or you'll overwrite each other's settings.

    So there we go, a bit of a change from the usual AppSense Bigot articles and an exploration of how to try and use existing and emerging technologies in tandem to make your life a bit easier in sticky situations. What I'd like to try and do now is come up with a definitive method of doing the same sort of thing on an enterprise level, and there are plenty of technologies to look at for that particular requirement. Something hopefully we can look at in the not-too-distant future.

    0 0

    Time for some good news that I first heard at the ACA Summit in Daresbury. Yes, AppSense's patches and updates will now be distributed in the MSP file format. This will bring the Management Suite patches firmly into line with the industry standards that are used by the likes of Microsoft, Citrix, etc.

    The idea is that you will now simply receive a patch for a hotfix or a feature release, unlike the current process where a full build is released with only the minor version number changing. As well as making the patches much easier to deploy using your tool of choice, this should also allow for a vastly easier rollback procedure, where you can simply uninstall the MSP rather than having to reverse the full upgrade process.

    In addition, we should now have a much clearer delineation between fixes and features, rather than the somewhat muddled miasma of version numbers that we have currently. Private hotfixes (patches), and rollups of hotfixes (which will be known by the term Service Pack, a term Microsoft coined but seem to be abandoning) will be distinct from Feature Releases in that the hotfixes and service packs contain bug fixes but the Feature Releases introduce new functionality or behavioural changes.

    The Environment Manager Agent will be the first to support patching, closely followed by the Environment Manager Console, Application Manager and the  Management Center, with Performance Manager adding the ability to be patched at a later date. Personalization Server, for complexity reasons, won't be patched via MSP at present time.

    So, all of the products that make up the AppSense Management Suite should, going forwards, now explicitly state if they are a Service Pack Release or a Feature Release. The intention is that most bug fixes will be dealt with as Private Hotfixes and Service Packs; Feature Releases will only contain new features, fixes to bugs that cause a change in behaviour and those fixes which cannot be incorporated into a Service Pack due to the technical limitations of MSP files. The version naming will appear as Version x Feature Release x or FRx, rather than x.x and Service Packs will be named Service Pack x or SPx. The actual build numbers will now only appear in the product consoles About box and in Programs and Features.

    You can read more about this if you log into MyAppSense and click on the Product Patching link.

    0 0

    I used to contract at a client where one of the systems support engineers was a tad, shall we say, prone to mistakes. Seeing him digging about in AppSense configurations or App-V sequences used to bring me out in a cold sweat. You couldn't lock him out of the consoles either - he actually needed access to the configurations to update printers and mapped drives, etc., so it was just something we had to put up with.

    However, the imminent release of AppSense Environment Manager 8 Feature Release 4 (check out our shiny new terminology!) should bring an end to this with the use of "layered" configurations. You can now "merge" small configurations together into one single unit for deployment to endpoints. So if you had a support team member like the one mentioned above (we'll call him Frank for posterity), he doesn't need to go into the entire configuration to make small cosmetic changes. We could simply give him access to the Printers or Mapped Drives parts of the configuration, let him update those, and then we simply merge his altered configuration into the "master" one.

    As well as neutralising some of the threat provided by the Franks of this world, this "layering" of configurations should be ideal for larger organizations where different groups need to administer different parts of the configuration, again without having access to the whole thing. Your application packaging team could manage App-V shortcuts, your SQL team could provide ODBC connections, your security team could handle lockdown of the desktop - you get the idea. The AppSense administrators would only need to merge the various configurations into one and deploy it to the endpoints.

    Hopefully this layered solution will come with some detection tools built in, so that you can tell when settings may conflict with or override settings from other layers of the configuration. An RSOP-style tool that tells you what the final settings for a user or group will be would be very useful, and I'm fairly sure that AppSense will have features like this available.

    It certainly makes for a very interesting addition to the AppSense Environment Manager product, and I've barely scratched the surface of the possible applications of this feature in this quick article. As soon as I can get my hands on the new software, we will do a walkthrough on how to put together and deploy a layered configuration, and most importantly, how to troubleshoot it.

    I'm not entirely sure yet whether the "layering" feature will be extended to Application Manager and Performance Manager, so I will update on that as soon as I know more.

    AppSense Environment Manager Feature Release 4 is due for release "imminently", so hopefully this means in the next day or so!

    0 0

    I see all sorts of Environment Manager configurations at different clients. Some are put together really well - others make basic mistakes that contribute to the configuration being ineffective, slow or bloated. I've already covered the workflow of a good Environment Manager configuration in a previous post. What this article is more concerned with is some general hints and tips on how to use Actions and Conditions, rather than the structure of the configuration itself.

    Node groups

    Node Groups are possibly the most little-known feature in AppSense Environment Manager (I think, if I remember correctly, that they first appeared in version 8.1). We've already covered the basics of node groups in this previous post, but it is worth mentioning their usage again here. When AppSense was single-threaded in version 7, it was quite easy to prognosticate the execution order, because everything ran more or less in the order they were laid out in the console. Of course, this naturally had a trade-off in a longer processing time. In version 8, the multi-threaded model allowed for faster execution, but setting up dependencies became a little trickier between nodes.

    The answer to this trickiness is to use a node group, which means that any Reusable Nodes set up in the node group run before any child nodes can run.

    Reusable nodes/conditions

    Reusable Nodes (and Reusable Conditions) follow on nice and logically from Node Groups because once you start setting up Node Groups you will need to populate them with Reusable Nodes! Again, we've already done some coverage of Reusable Nodes/Conditions here, so we won't bother to reinvent the wheel too heavily. The beauty of Reusable Nodes/Conditions is that if you have the same Condition, Action or group of Conditions and Actions used multiple times within the same configuration, if you then need to modify that task, you only need to do it in one place to update all the instances of it within the configuration. Reusable Nodes also reduce the amount of data within the configuration which has the added bonus of reducing the memory footprint of the session.

    Environment variables

    Anyone familiar with any sort of scripting will recognize the value of a variable being set. For instance, if all your users imported some files in from \\SERVER1\Public\SharedStuff\AppSense\SharedFiles\General in twenty different Actions throughout the configuration, why not use an environment variable called %LocalShare% instead of the full path?

    Setting environment variables within the root section of the triggers (Startup, Shutdown, Logon or Logoff) rather than in individual sub-nodes is also more logical, because then the variables are available to all of the sub-nodes in the triggers.


    Do I have to mention this again? I think it must be a plague particular to IT staff, this problem, because an awful lot of places I go to (and this is not confined by any means to AppSense configurations - Active Directory groups and OUs are equally as bad for it) have no comments in the Description field. Just to reiterate, it is really important just to add a small description - something that will take you no more than ten seconds - to the tasks you create, especially Lockdown items. The amount of time, money and heartache that can be saved by doing this is immense. And while I'm on the subject, would it hurt anyone to put in a proper description when they save a change to the configuration? The amount of descriptions I see for configuration changes that are simply the default of "Other" beggars belief.

    Computer Startup vs Network Connected

    I've also seen quite a lot of people trying to do things such as network file copies in the Computer Startup node. I'm not a big fan of using the Computer Startup trigger - especially in PVS or other non-persistent environments - but if you insist on doing so, if there is anything you need to do that requires network connectivity, it might be an idea to use the Network Connected trigger rather than the Computer Startup one. You will be certain that network connectivity is available for your Actions if you do it this way - just make sure the Action is configured only to run once, as the network could disconnect and reconnect during a session.

    Active Directory lookups

    Something you can usually guarantee will be referenced quite a lot in any AppSense configuration is an Active Directory group lookup. When a user logs on, it doesn't make a lot of sense to send every Active Directory lookup to a domain controller - this will drag out the logon time as well as making it impossible to provide any offline support. To make sure these problems don't occur, make sure that every Active Directory lookup uses the local security token instead - identified by the "LSA Supported" suffix shown next to the relevant Condition.

    Stop if fails

    The Stop If Fails checkbox (you can see it in the image above) ensures that sub-nodes won't run if a Condition is not met. If you structure your configuration intelligently enough, you can use Stop If Fails to ensure that the configuration runs in the minimum possible amount of time for the majority of your users.

    Folder Redirection folder creation

    A lot of people have a Folder Action running prior to Folder Redirection to create the redirected folder if it doesn't exist. This isn't necessary - the Folder Redirection Action will create the folder if it doesn't exist.

    Group Policy and Registry action groupings

    This is something I also try to recommend when dealing with standard Group Policy Objects. From a troubleshooting standpoint, it is always simpler to have a rule of "one Action, one setting". With both Group Policy Actions and Registry Actions you can lump together lots of different settings into one Action. Whilst this may seem desirable to save time, when it comes to diagnosing issues with these Actions, it is much easier for support teams to undo specific settings without impacting others when the settings are divided on a one-to-one basis into individual Actions. Specifically for the Group Policy Actions, there is also a performance impact from putting too many settings into a single Action.

    Too many Group Policy settings in a single Action

    The bcdedit myth

    I've seen this pop up in AppSense configurations at more than a few clients and I am sure it was a rumour spread in various forums across the Internet (it's not specifically an AppSense thing - I've seen it done at a multitude of places). Apparently some people think by disabling Data Execution Prevention there is a performance gain on XenApp platforms. If your configuration contains a bcdedit command designed to disable DEP permanently, I wouldn't bother with it. I've brought this up with various people, amongst them a CTP who verified it with a XenApp product architect, and there is no performance gain to be had from implementing this tweak on a XenApp system.

    Executing command scripts

    Using the "Do not create window (console-based applications)" option is handy for ensuring that your users aren't disturbed by command prompt windows when Execute Actions run.

    Group Policy Actions as a Reusable Node

    Any Group Policy Action which contains both User and Computer Configuration settings should not be set as a Reusable Node, as it is impossible to determine which one should be applied.

    Scripted Actions

    AppSense themselves recommend, for support and troubleshooting purposes, to keep the amount of Custom scripted Actions to a minimum (which is kind of ironic when you see the heavy scripting in some of AppSense's own configurations, but maybe those are special cases). Certainly, if there is another way of doing it natively through the console, it's not a good idea to script it. I once saw a Custom Action that called a VBScript to launch Internet Explorer - why that couldn't have been done through a standard Execute Action, I may never know.

    Computer Group Conditions

    If you need to use Computer Group Conditions, be aware that these can't be used on offline devices. If you do need to do this on offline devices, use the Computer Group Condition to set an environment variable to achieve it.

    Printer mappings

    Be careful if you are using the "Unmap at logoff" feature with AppSense-delivered printer mappings. If a configuration is deployed mid-session, the user's printers will be unmapped if this option is selected. Another option (although a little convoluted) would be to create explicit printer unmap actions in the Logoff trigger if this issue became badly apparent in your environment.

    Active Directory Group Condition in Query mode

    Imagine you have a node full of ten or twenty Actions that all have a different AD group lookup associated with them. How could you prevent a user that isn't in any of these groups from running through all ten or twenty of the lookups?

    Well, if the AD groups being looked up all had a common link - maybe, just for an example, they all begin with ENG - then you could use an Active Directory Group Condition Query to filter off users that don't match the common part, saving users who don't match the initial query the time of ten or twenty AD group lookups. You implement this with the normal Condition | User | User Group, but change the Condition to Query as below


    So, I think that just about covers all the tips that I can think of offhand with regard to streamlining your Environment Manager configuration. But let's be clear, there's really no substitute for good planning, testing and verifying. You should always be looking to try and make your Environment Manager configuration more effective, because it controls some of the primary areas - such as logon and application launch time - that your end-users will use to gauge the performance of their systems.

    Thanks to Richard Thompson for introducing me to more than a few of the performance tweaks I've covered here.

    0 0

    Must apologize for being so quiet lately...I've been working on quite a lot of interesting posts but because of some personal issues I've never managed to get around to finishing any, yet! I'm also stuck in App-V packaging hell, which doesn't help. So hopefully we should have some more posts before Christmas descends, if I can find some spare time - but just in case I don't I've chucked a Christmas greeting in with this short post.

    I bumped into an old issue a few days back that I'm just quickly going to take the time to remind everyone about, the problem with logoff actions not applying correctly.

    AppSense Management Suite utilizes a local group policy object to run a logoff script to invoke all logoff actions. The Windows logoff architecture requires that all running applications respond within a certain defined time limit to the application close requests. If an application does not respond within the time request a black screen is displayed allowing the user to force an application closed or wait for it to close.

    In order to ensure AppSense Environment Manager is not listed within the list of applications for closure, a mechanism was required to ensure the logoff process was triggered by group policy. Group policy is permitted to run as long as it requires at logoff. In order to achieve this AppSense implements a local group policy on each endpoint to run the logoff applications.

    In order to ensure the process works correctly it is important to ensure that the following group policy object is not enabled within an AppSense-enabled environment - Computer Configuration | Policies | Administrative Templates | System | Group Policy | Turn off local Group Policy Objects processing

    And that should ensure that everything runs as expected at logoff.

    Finally, just in case I get further sidetracked by my personal issues and don't have lots of exciting new content for everyone before Christmas, I'm going to take this opportunity to wish everyone all the best, and say thankyou for your continuing site visits, comments and emails. Hopefully we can all enjoy the holidays and then get back to some more interesting UVP stuff in the New Year!


    0 0

    I blogged some time ago about how to "normalize" a Citrix Provisioning Services vDisk on an AppSense level when you are updating a gold image. AppSense isn't the only piece of software that needs some manual normalization routines - I've seen it done with AV and system monitoring tools, amongst others. However, an incident recently where someone updated a gold image and forgot to perform the manual normalization routines got me thinking. AppSense EM should be able to handle at least part of this for you, as long as the gold image has picked its configuration up when it was booted. The wide-ranging problems that can occur as part of a bad gold image update certainly made me think this was at least worth some further investigation.

    When you start to prepare your updated gold image for imaging and provisioning you normally launch the XenApp Server Role Manager (I'm talking specifically about XenApp 6 and 6.5 here, but you could easily extend this to XenDesktop images with a bit of imagination if required). So it would make sense to use the trigger for this as the XenAppServerRoleManager.exe process

    Thinking about it, it might be a good idea to put a check in to see if the user is an Administrator. Standard users shouldn't really be running XenAppServerRoleManager.exe - it should be on the list of disallowed user applications in Application Manager, for starters - but if they somehow do, we don't want AppSense EM to inadvertently trigger the resultant Actions. So we would now nest an Is Administrator check inside the Process Name Condition

    Now comes what I thought would be the hard bit - but turned out not so bad! We want to also verify that the vDisk is in Private Mode, which is usually a tell-tale sign that updates are being applied to the master image. Luckily a bit of Googling about alerted me to the existence of a string in the Personality.ini file in the root of the vDisk that we can check for using a File | Text File Search Condition. The existence of the string $WriteCacheType=0 in this file should indicate the vDisk is in Private mode, and therefore likely being updated.

    Once we've done this, we can automate the processes we need to run when we update the master image. Your own needs will dictate what goes here - but just to cover the things we do from an AppSense point of view, we will first stop the AppSense Client Communications Agent using an Execute Action

    and then use some Delete Registry Value Actions to remove the AppSense entries that identify the system

    Now the entire node we have created looks like this

    You don't have to stop by just doing this, though! There are other things you could trigger here too, such as running an Execute Action to start the Provisioning Services Target Device Optimizer, removing Registry entries associated with AV or monitoring tools, run defrag tools, flush the DNS cache - anything you require really prior to gold image sealing. Perhaps about the only thing you couldn't do is remove an AppSense configuration, although I haven't tried, but using a configuration item to remove the configuration seems a bit insane, and I'm not in a position to test it just right now! But hopefully you get the idea of how AppSense Environment Manager can be leveraged in this way to make your life, and that of your IT guys, that little bit easier.

    0 0

    I've long been aware of this particular feature within Application Manager, but had yet to see a real-world application of it. However, recently I did some work for a client with a very large infrastructure and a lot of delegated administrative access to servers and clients. It turns out that some server support groups had been adjusting the time on their managed servers to bring it into line with their local times, conveniently forgetting that the servers were hosted in an overseas datacenter.

    Now, allowing servers to fall out of synchronization time-wise is pretty bad. Firstly, your logs are now going to be completely inaccurate. There are also the effects this can have on hosted applications - think a database application that relies heavily on time accuracy, and the resultant screw-ups that can occur as a result of this being skewed. If the servers are DCs that have been erroneously adjusted, then you're going to have a world of problems with replication just to start with. Some applications even flat-out refuse to start if an incorrect date and time is detected - it can cause that many issues.

    Of course, there is probably something you could do with a server admin group that changed the time on their managed systems without proper due diligence - I think shooting them, or at the very least handing them their notice, would be high up everyone's lists. But in this case, once the people involved had been harshly warned about their conduct, management wanted to put into place some way to prevent a user with administrative access from actually being able to change the system time. How could we achieve this? Well - enter AppSense Application Manager.

    First we need to open the Application Manager Console and create a new Group Rule, as we only want to apply this rule to a particular group of Administrators. If we applied it across-the-board to all local Administrators, nobody would be able to change the system time! So we will use a specific Active Directory group to apply this configuration. We choose the group "EMEA Server Support", and this group is designated as "Restricted", as we are going to restrict their execution options slightly.

    Now, we have a couple of options as to how we could restrict the user from being able to change the time. We could use remove the user right "change the system time" from this user by setting up a custom User Rights Policy, or we could use the "Builtin Restrict" pre-built policy to simply reduce the user's rights when they launch the required Control Panel applet to change the time. It is simpler to use the latter option, so that's what we will opt for in the first part of this example - although we will come back to the other option later.

    So, next we will need to add a new Component to the Restricted Items section under our Group Rule

    Select Date and Time from the list of options selected. These Components refer to particular applets called by Control Panel, mmc.exe and other programs

    Click OK and you will be presented with an option to select a User Rights Policy to apply to this Component. As we haven't created any custom ones (yet!), we simply have the choice of the Builtin Elevate (which adds administrative rights to the user) and the Builtin Restrict (which removes administrative rights from the user). We want to select Builtin Restrict as below

    Now, that's all that is actually required! Save the configuration into your Management Center with a sensible name, and then deploy it to a test system. Log onto the system with administrative privileges, and see if you can change the system time by clicking on the time in the system tray and choosing Change date and time settings | Change date and time

    Great news - it works! But what if the administrative user decides to run time or net time from the command prompt - will our configuration stop the change then? Let's find out...

    ...and as you can see the answer is a resounding no. So how can we stop the admin group from being able to change the date or time from the command prompt? Well, as I alluded to earlier, we can use a custom User Rights Policy to alter the user right for Change the system time. Might this be of use to us? Let's go back to our configuration and have a try.

    First we need to go to the User Rights Policies node and create a new one, before giving it a sensible name. Then switch to the Privileges tab of your new policy and change the SeTimeZonePrivilege and SeSystemTimePrivilege to Remove as shown below

    Now, we need to go back to our Group Rule and add the required files to the Applications tab under User Rights. I've added the cmd.exe program from both the system32 and syswow64 folders because I am working on an x64 platform and you don't know when people might launch this from unexpected areas. I've also added the applications as both File and Signature items to show you both the options, but either one should suffice.

    Also, you need to make sure each item has the Apply policy to child processes option ticked, in case the user uses something like net time which calls out to a different command (net.exe in this case)

    So when all of the items are added to the Applications tab, you need to make sure that you select the correct User Rights Policy for each one as below (i.e. the one we created previously!)

    Now let's save and deploy this configuration to our test machine, log on as an administrator who is part of the target group and try each of our net time, date and time commands from an elevated command prompt

    Success! Now our target group have administrative privileges but can't change the system time and date to create problems.

    Bear in mind that if you remove these privileges in this fashion, they can be a little annoying to reinstate. You will actually need to change the configuration and then restart the Application Manager service to get the changes to revert - simply deploying an updated configuration doesn't seem to make it go away.

    One final word on this. Administrators do have the power to get around almost anything. If someone was determined to change the system date and time, the easy way to do this would be to simply stop the AppSense services and change it. However, this sort of thing isn't intended to be bombproof - merely to stop someone in the server admin group (in this case) from unintentionally altering something that could have serious knock-on effects. If your admins are in the habit of shutting down core system services (that are possibly outside of their management remit) just to do what they think is right, then clearly you've got an issue that you'll need to look beyond IT and into the HR department to solve :-)

    You can also download this configuration from this link, obviously the group name will need to be changed if you wish to use it yourself.

    And before I forget, Happy New Year everyone, rather belatedly!

    0 0

    I've had this thought quite often, that it would be useful to have a "baseline" library of Environment Manager Reusable Nodes and Reusable Conditions to import into new configurations, and then simply delete or disable those that you don't require. So why not - let's do it! However - I need your help, because this configuration is intended to be "live", i.e. I really want a lot of people to contribute all their useful bits of configuration, to make this a really good resource. So...please don't post comments saying "you should have included x" - instead, drop me the details of whatever x is and I will include it in the configuration library with a relevant credit. It would also help if you could include an example of the trigger and the situation in which you've used the Node or Condition.

    The downloadable configuration is available here and there's also a link at the end, but we will also run through each part of the library in turn so that you can understand exactly what each item does. Some are fairly self-explanatory, whereas others require a little more detail.

    If you download it and import it, you will see that at time of writing that I'm pretty short on content! So let's make this a real community effort - dig out your Nodes and Conditions that you find useful, traditional or scripted, and let's put them all together in one central location to share the tricks and shortcuts that we've found.

    Reusable Nodes

    The Reusable Nodesare sets of Conditions and/or Actions that can be used to achieve a particular task, either by direct links in the configuration or through the use of Node Groups. They can be referenced as many times as required throughout the configuration.

    Set user SID as variable

    Nice useful trick from AppSense themselves here - an elegant way of retrieving the user SID from the Registry. The SID is normally used to then set a local profile to temporary (see the next item) in order for the local profile to be purged at logoff. This trick was discussed in this previous post - however this Reusable Node offers a much better way of achieving the "profile flip" than the VBScript mentioned in the original post.

    Set local profile to temporary

    Best done in the Logoff trigger, this ensures that a local profile will be purged by setting the state of the profile to that of a temporary one.

    Disconnect session

    Also best done in the Logoff trigger (for obvious reasons!), this disconnects the user's session as it logs off, giving the impression of a quicker logoff time. It was discussed in this previous post.
    Set online/offline status

    It makes sense to use this Node in the Computer Startup, Network Connected and Network Disconnected triggers (as discussed in this previous post). It writes a flag to the Registry defining whether the client is connected to the corporate network or not.

    Check desktop folder size

    A nice one provided here by Michael Ruefli ( which shows a warning if the user's Desktop folder size is over a certain threshold (30MB in the example provided).

    Set Desktop background

    Provided by Andrew C, this shows that even very straightforward stuff can be useful - simply setting a particular image as the Desktop background for the user and centring it.

    Set Office version as variable

    Don't know where I came across this one (probably from Richard Thompson), but this uses the version of Outlook which is installed to set a variable identifying the version of Office in use. You can probably alter this one to use other programs if needs be.

    Identify chassis type

    Discussed in this post, this If Else Group uses a WMI query to indentify the chassis type and then set a custom Registry key to flag it. This Reusable Node is required for the two Reusable Conditions below (Detect Laptop and Detect Desktop) to function correctly.

    Flag connecting client OS / unflag connecting client OS

    Discussed in this post, these Reusable Nodes use ctxclios.exe to write the client device OS into a Registry key, and to remove it when the session disconnects or is logged off. Note that the path to ctxclios.exe is hard-coded into the PowerShell and will need to be adapted for your own environment.

    Set Session ID / remove Session ID

    Discussed in this post, these Reusable Nodes were used to write (and then erase) the Citrix Session ID of a user session to an environment variable.

    Legal Notice

    Discussed in this post, this Reusable Node sets the LegalNoticeText Registry entries with correct formatting.

    Wait for network

    Provided by Michael Ruefli, this node ensures that the corporate network is accessible so that network-dependent Actions can execute.

    Reusable Conditions

    The Reusable Conditions are simply Conditions or groups of Conditions that can be referenced multiple times within a single configuration.

    OS conditions

    Nice and simple this - there is a set of OS Conditions which detect the operating system of the system the user is connected to.

    Architecture conditions

    Again, very straightforward - this Condition differentiates between x86 and x64 architectures.

    Terminal services conditions

    Some more simple ones - identifying whether the system is TS/RDS-enabled or not. Very useful for separating XenApp/RDS systems from traditional non-SBC clients.

    Check if vDisk in Private mode

    As discussed in this previous post, this simply checks whether a Citrix Provisioning Services vDisk is in Private mode.

    Check if vDisk in Standard mode

    And this simply does the opposite (more or less) to the above, checking if the PVS vDisk is in Standard mode (any flavour of Standard).

    Check if XenDesktop

    This verifies whether the endpoint is a Citrix XenDesktop virtual machine.

    Check if battery is present

    This used to be very useful for identifying laptops, but with the advent of tablet devices it is possibly becoming a bit less relevant. I'm working on some scripts to identify client systems (watch this space!), but for the moment you may be able to get some mileage from this.

    Detect laptop

    This uses the Registry key written in the Identify Chassis Type Reusable Node to flag a machine as being a laptop.

    Detect desktop

    This uses the Registry key written in the Identify Chassis Type Reusable Node to flag a machine as being a desktop.

    User session runs XenApp 6.x / machine runs XenApp 6.x

    These Conditions detect whether a machine or user session is running on Citrix XenApp version 6.x

    And that's all I seem to have for the moment (although I am working on some client identification stuff, hopefully to be added very soon!) So come on, send me your snippets of Nodes and Conditions and hopefully we can turn this little library into a really good resource for building AppSense Environment Manager configurations.

    The configuration, as mentioned earlier, is available for download here.

    0 0

    Just to keep us all confused, AppSense Management Suite (the collective name for Environment Manager, Application Manager, Performance Manager and the Management Center) is now AppSense DesktopNow. I can see the reasoning behind this easily enough - it's aligning the brand with the two other major AppSense offerings, DataNow and MobileNow. It's just that the name DesktopNow doesn't sit that well with me - it's almost as if they've sold the product a bit short. The AppSense Management Suite wasn't just about delivering custom desktop settings, there are plenty of other things tucked away in it like application control, licensing control, user rights management, performance enhancements, etc. You could argue that all these things are aimed at improving the end-user's desktop experience - even if they are using AppSense for published applications rather than full desktops - but as I said, it just doesn't seem like the ideal selection at first glance. However, I can't really come up with any decent alternatives (suggestions are welcome!), so maybe this is just the best that their marketing guys could find.

    The new product at least maintains the current version numbering, so we now have DesktopNow with Environment Manager 8 Feature Release 4, supporting MSP patching and layered configurations. I'm downloading it now so I can have a good play with the layered configurations, so watch this space for an article about it pretty soon.

    Here's a quick look at the new AppSense branding for anyone interested, with new funky icons for the various parts of the Management Suite DesktopNow. I'll get used to it eventually, I promise!

    Update - I took the liberty of making sure that the various parts of DesktopNow are all still available to license separately, which is correct. You can now also pay for a subscription license for DataNow on its own, and also, interestingly, the User Rights Management part of Application Manager is available as a license on its own too. See this article for details on the URM Edition

    0 0

    Configuration Assistant is often described by AppSense staff as one of their “hidden gems”. Really it shouldn’t need to be so hidden, but that’s something that hopefully they will address as their product focus improves. What Configuration Assistant does is allow you to deploy a Personalization-enabled configuration to your managed endpoints, but without necessarily doing any Personalization. It instead then collects data from the endpoints as users run and use their applications, but it then pulls the data together in a handy user interface, allowing you to quickly formulate inclusions, exclusions and Session Data. It’s much better than just turning on Discovery, which simply identifies applications being used and lumps the data into Personalization Server ready to be managed. Config Assistant allows you to see a full overview of the Registry keys and files being used by applications, allowing you to create streamlined Session Data and Personalization Groups ready to turn on the full power of Personalization Server, without encountering the heavy and disruptive initial tuning phase that I so often see in greenfield AppSense deployments.

    First of all you will need to create a Personalization Group containing the users who will be trying to run the applications in this testing phase. Ideally you should run this environment side-by-side with your existing production environment, allowing the users to still do their day-to-day jobs whilst at the same time performing testing of their applications on your new AppSense-enabled environment. The best way is to lump this phase alongside the actual application testing, so while they are verifying application functionality they can also be providing data for Config Assistant.

    I’d recommend that this data gathering is done without any Personalization data actually being saved or utilized – that means for this Personalization Group nothing will be whitelisted, and no Session Data, Desktop Settings or certificates will be captured. This does however mean that the users in the test phase will not see any of their settings being retained, unless you configure another solution such as Registry hiving in AppSense Environment Manager, Citrix Profile Management, standard Windows roaming profiles or another solution. Perhaps the easiest way though is simply to restrict the users in this test phase to a single server or client and force local profiles to be used. That’s the way I’ve done it in the past, and it quite helpfully keeps the profile load times nice and fast and prevents users from logging profile issues whilst they are trying to do application-level functionality verification.

    You can then turn on the Analysis functionality by visiting the properties of your Personalization Group and setting them to match those below

    Also ensure that the Personalization Group has nothing configured in the Whitelist settings as shown below

    Here's a quick gotcha right here - don't forget to turn Personalization on in your Policy Configuration and deploy it! Might seem obvious - but I wasted an hour before I realized this. :-(

    Now you will need to allow your users to run the applications over a period of time and hopefully use as much functionality as possible. One of the things to encourage them to do is run tasks that involve integration with external applications – e.g. integration with Office apps, the browser, external data, etc. Don’t worry if your apps are delivered via App-V, Citrix Streaming or Thin App – AppSense EM is clever enough to intercept the settings for all of these packaged application types. For the purposes of this demo, we've just run a few simple applications, but you will want to get as many done as possible.

    Once you’ve allowed the application usage to run long enough to capture some meaningful data, the next thing to do is install the actual Configuration Assistant itself. This doesn’t have to be done on the Personalization Server, Management Server or anywhere in particular – just somewhere that can access the SQL database that your AppSense infrastructure is writing Personalization data to.

    Install the Config Assistant by navigating to the \Software\Products folder of your DesktopNow (got it right this time!) software and installing the Config Assistant for your CPU architecture

    Simply accept the install defaults. Now launch the Config Assistant

    You will see the screen below. Click the Connect button

    And then enter the details for connecting to your SQL server as below

    Now you should see it pulling in the data for the apps we've already run

    Click Proceed to enter the main Config Assistant window. There's a Getting Started screen you can choose not to see again once you've read and understood the information here.

    I will draw your attention to the Reset Data/Purge function in the bottom left. This will remove any pairings and exclusions and pull in the latest data if you use the Reset Data function. Apparently it is good practice to do this every time you log in to the Config Assistant, but I am not sure if this is relevant in the latest version as there appears to be an Auto Refresh function in the Options section. Maybe someone from AppSense can tell me what the best way to handle this is?

    Session Data and Global Exclusions can be created by clicking on the Popular Registry Keys and Popular Folders sections. Viewing the Registry keys and files/folders associated with each application should give you a very granular insight into what (and where) the application writes. You will soon find that some applications write to areas where there is no real need for them to - Windows Explorer areas, HKCU\Software\Microsoft and the like. Use common sense and be as sparing as possible when deciding which to add as Folder or Registry inclusions. You can always add extra Includes if something doesn't work, but when you remove erroneous Includes, the captured data will stay in the database.

    This should help greatly with putting new Applications and Application Groups together in Personalization Server. It is good practice to add Excludes for HKEY_CURRENT_USER\Software, {CSIDL_PROFILE}, and {CSIDL_COMMON_APPDATA} as below.

    Then you can add all the necessary Includes you've identified in Config Assistant. Don't forget, setting up an Exclude for HKCU\Software\Microsoft and an Include for HKCU\Software\Microsoft\Paint (for example) would include the Paint Key, but nothing extraneous from the parent key. It's better to miss something out than add something unnecessary in - keeping that Personalization Server database as lean as possible can only be a good thing for your user base!

    There's a lot more to the Config Assistant than this quick example we've run through here, but hopefully you can make invaluable use of it in AppSense implementations where the configuration of Personalization Server is going to be complex or long-winded. There are some great features that will help you create groups of applications and streamline the data that users need to save to retain all of their settings. If you've never used this tool before, then you really need to fire it up and have a play!

    0 0
  • 02/06/13--03:00: A year of AppSense bigotry
  • On 6 Feb 2012, a conversation started over on the NT SysAdmin mailing list about hiring practices in IT. Approximately 115 posts later, the conversation had gone all the way through to how to raise your profile when self-employed. Guys like Carl Webster, Michael B Smith and Brian Desmond (amongst other thought leaders on that list) all agreed that writing articles and books was the best way to do so, and midway through the discussion I declared I might start blogging a little bit about AppSense software because I thought it was a little under-represented.

    Well, one year later, I've put out 111 posts, had over 92,000 page views and managed to find myself a recipient of AppSense's ACA award. It certainly goes to prove what the guys on the SysAdmin list said was true! I've gotten involved in a lot of diverse work for clients in lots of different places and generally learned a huge amount more about AppSense and the technologies that support it in the user virtualization world. I also took to Twitter and have found that, to my surprise, to be quite a handy resource for quickly discussing technical issues and finding out about interesting new articles and publications. I don't think I'm any better off because of this - but my children have a wider selection of toys, so it must be helping financially at least a little bit :-)

    I guess I'd just like to say thanks to everyone who takes the time to read my articles, and hope that you continue to do so, and that I can also continue to provide content that is both relevant and interesting. For the second year, I'm hoping to concentrate a lot more on the newer AppSense kit, as well as diversifying a bit into surrounding technologies like App-V and some of Citrix's newer acquisitions. If there's anything you'd like to see me cover, please leave a comment or email me using the details on the About Me tab.

    Thanks again!

    0 0

    The requirement to allow users to install applications is becoming more and more common. The days of providing a unified set of monolithic desktop applications to each end user are slowly being worn away. Today's users are often a little more tech-savvy, sometimes requiring access to new applications as circumstances dictate. Most of these applications will be what we classify as long-tail apps - not core business or departmental systems, but niche applications required by certain users for certain specific tasks or enablements, sometimes even things they need to run at certain times of the year.

    Of course, you can't simply give your users administrative rights and then allow them to install software from anywhere. That would rapidly compromise the security and integrity of your managed environment. What would be useful is to provide a set of applications that have been pre-verified by IT - an app store of sorts, to steal a phrase from somewhere else - that users can install on demand, without having to raise a call with the IT department. It also removes the need for each and every individual application to be packaged or delivered - the IT department, once they've verified the software, can simply drop the install files into the AppStore share and let the users install them as required.

    AppSense already have StrataApps which allows users to install applications into a bubble of sorts, but as yet (rather disappointingly) this isn't integrated into Application Manager. Which means that if you deploy StrataApps as the solution to UIA (user-installed apps), you are allowing your users to install pretty much anything. I am reliably informed that AppSense are working hard on the StrataApps integration with Application Manager, and this will be a very exciting development when it happens, but just for the moment, we will have to do without the advanced stuff we could have gleaned from StrataApps and try to achieve our goal through Application Manager itself.

    The next dilemma you'll face when thinking about UIA is whether it is suited to server-based computing or not. Primarily this sort of thing is aimed at desktop, laptop or VDI users, simply because there won't be the constraints of disk space or performance that you may get when allowing users to install their own apps onto an SBC platform. Now you could do something like fire up AppSense DataNow and do some editing of the various application installation files to point the install location into the user's DataNow folder (which is network-based), but this raises so many possible issues of application failure and additional complexity that I am going to consider this as out-of-scope for this article. Right this minute, we will assume that you are going to deploy this UIA solution onto single AppSense-enabled endpoints - desktop computers, laptops, or VDI sessions running Windows.

    So, the first thing we need to do is configure the network share we are going to use as our enterprise AppStore and populate it with a few applications. We will choose Notepad++ for our developers, mRemoteNG for our first-line support staff, and TweetDeck for some of our marketing bods. Not a particularly complicated line-up, but I'm sure you get the idea :-)

    Next, because we will be using the Trusted Ownership feature of Application Manager to verify that these files can run, we need to ensure that the NFTS permissions and ownership are set correctly. Users should simply have RX (Read, eXecute) permissions to the folder and files, Administrators should have F (Full Control), and the owner should be set to the BUILTIN\Administrators group. Also ensure that the files in the folder are inheriting permissions from the parent folder.

    Next we will verify that our current users can't actually install these apps themselves. I will log onto a user session and try to install a couple of the applications we placed in our AppStore.

    As you can see, the user can't install applications without having administrative rights, which is what we'd expect. In this situation a user would probably be calling the helpdesk, logging a case and facing a long wait as the call was queued and prioritized according to a company's SLA - maybe even experiencing further delays if the application needed extensive testing or packaging for delivery. However, we will now try and use AppSense Application Manager to get around all of this!

    We're going to use a specific Active Directory group to make this AppStore accessible to, so we will first add a Rule Group, the process of which I should hope regular readers of this blog might already be familiar with :-)

    In the Accessible Items section of our Rule Group, we will need to add a Folder item

    then we will supply the required details

    and ensure that the Trusted Ownership and Include Subdirectories options are selected for this particular item

    Now we need to utilize the User Rights node of our Rule Group to allow us to elevate permissions of the user when they are executing content from this share. We need to add the folder we specified above to the Applications tab of the User Rights section

    and then ensure that the following options are set (note - you may want to use the Substitute environment variables where possible option, the reason I didn't is because for reasons of quickness I hosted my AppStore share on a domain controller)

    Once this is done, you'll need to ensure that the User Rights Policy you've selected is the Builtin Administrator Elevate as shown below

    The Apply policy to child processes option needs to be selected because often installers will spawn other processes, such as installing pre-requisites

    The Standard user rights on common browse dialogs optionis very important, not just for this particular scenario but any in which you make use of elevated user rights. This stops elevated administrative rights "leaking" into things like Explorer windows where users could technically use their elevated privileges for nefarious purposes, and it's one of the best features of Application Manager IMHO

    Next, as most installers leverage the Windows Installer process, we need to configure the pre-defined Windows Installer node under Process. In the Accessible Items node for the Windows Installer process, we need to add *.msi to the list of allowed items

    And then we will need to add the file share as a Folder to the User Rights node of the Windows Installer Process Rule

    And as mentioned earlier, ensure that the User Rights Policy for this Folder is Builtin Administrator Elevate

    Now, the only other option you need to check before deploying this configuration is on the General Features tab under Options. User Rights Management should be selected for this to work (it is enabled by default, but check this just in case someone has turned it off)

    Once all this is set up, you will need to save the configuration and deploy it to your target endpoints. When the configuration is successfully deployed, we can now log on again as a non-admin user and put it to the test! First we will try a traditional MSI installer file...

    ...and hey presto! We have a flawless install process instead of the error about policies preventing the installation.

    Next we will try a non-MSI installer, a standard .exe file, using the Open command, not the Run As Administrator option...! This one works perfectly too!

    Now just to prove that we haven't inadvertently allowed everything to be installed, we will take our final example installer, the mRemoteNG one, and drag that onto the user's desktop before we try to run it...

    ...and now, because we have a valid Application Manager configuration running, we see that the user isn't simply restricted from running installers, they can't run anything at all that hasn't been allowed according to the configuration rules. Sweet!

    This looks like a really great way to allow users to install longtail applications from a pre-approved network share, allowing IT to verify the applications are valid and relevant but freeing them from the overhead of management and deployment. There are a few things worth mentioning, though:-

    1.  If you want to force users to install to a non-standard location or disallow them from changing other installation options, you are going to have to customize the installation files you provide on the AppStore share. There are various ways you can do this dependent on the software in use, using Orca is one of the more popular methods.

    2.  The security of the AppStore share is of absolute paramount importance. If a user manages to place a non-standard or malicious installer file to this area, you're going to be in a world of hurt. Lock it down as hard as you can, and make sure you test the security!

    3.  Uninstalling applications delivered in this way is a little tricky, because if you allow users the rights to uninstall things they can remove anything, not just the apps you've installed through this method. This is one of the reasons why I'd sooner use StrataApps combined with Application Manager rather than just Application Manager itself, because StrataApps, amongst other useful UIA features, allows users to perform uninstallations of their self-installed apps. As soon as AppSense integrate StrataApps nicely with Application Manager, we will have to revisit this whole subject, as StrataApps is specifically designed with UIA in mind and does a whole lot more than we can achieve with Application Manager on its own. If you need self-installed apps uninstalling in the meantime, users will have to leverage the IT department to do it.

    Well, here's hoping this method proves useful to some of you out there. It's certainly something I've put in place for a couple of clients to get around problems, mainly with power users like developers, but as the application needs of the general user populace grow ever more diverse, it will probably spread to other groups a lot more quickly than we anticipate.

    I've also made the configuration I put together in this article available, should you wish to download it. Usual caveats apply regarding the AD group name and obviously the network share, and please also bear in mind that I unchecked the option for using environment variables because I'd hosted the file share on a domain controller - you may want to reinstate this in your own environments.

    0 0

    I've been doing a bit of work recently for a company with offices right across Europe. As they were also using a full AppSense deployment, this raised an interesting problem - that of configuring the AppSense software's popup messages for users in different languages.

    At the minute AppSense's configurations appear to be blissfully unaware of the end-user's selected language, and simply display the message that has been configured within the configuration regardless of the endpoint's actual settings. Note - I haven't gone to the very latest version of AppSense DesktopNow yet, so expect to see this post hastily updated if it turns out they've built this functionality into it :-) The way the client I was working with were getting around this was by putting all of the required languages into a single message, but that didn't look very good - especially on some client devices, where the popup message filled just about the whole screen, covering as it did eight different languages.

    So how could we tidy this up? There are popup messages configurable in Environment Manager, Application Manager and Performance Manager, and they all have different uses. I'm sure most of you have gotten to the answer already, but for those who run into this issue, I thought writing a quick article about it might help save you some time.

    The answer is of course environment variables. Let's imagine we've got AD groups set up for our various different-language users. One of them could be called LANG_FRENCH for the users who need these messages in French.

    In Environment Manager we will need to set this using the Trigger Environment for the Logon trigger. We don't put environment variables into sub-nodes - this causes refreshes to have an impact on the running of other Actions. In your Logon trigger, right-click in the Environment tab and choose Condition | User | User Group

    Next you will need to fill in the details of the required AD security group, which in this case is our French language group

    Once we've added the Condition, we now need to create the required environment variables for this user group. There are a lot of these we will need to create for each one, so in the interests of keeping this article succinct, we will simply configure the settings for the Application Manager messages rather than all three major parts of DesktopNow. We are going to use Google Translate to provide us with the French translations of the popup messages, so if there are any inaccuracies, please a) notify me, and b) don't castigate me!

    Here's the first one

    And the second one

    I'm sure you get the idea now, so I will create the next six without providing screenshots. Now your Trigger Environment area should look something like this

    So now, when a user logs on from the French language security group, EM will set these eight environment variables for the user that correspond to the messages that could be displayed by AppSense - specifically, in this case, by Application Manager.

    Next we will need to open the Application Manager console and go to General Features | Message Settings. Here we will need to replace the various configurable messages with the relevant environment variables. Note that I have also had to do translations on some of the captions as well as providing the environment variables.

    Obviously, if we have seven or eight different AD groups with environment variables mapped to the various translations, you need to keep the environment variable names the same across each group, otherwise you will soon get lost :-) Thinking about this, it's probably better to call the environment variables names like %APPMAN_MSG_AccessDenied% and %APPMAN_MSG_AppLimitsExceeded% rather than the numerical format I chose, which would make things easier to work through for your support teams.

    With all these changes saved and deployed (and you'll need to do them for Environment Manager and Performance Manager also, if necessary), your users should get the correct popup messages from the DesktopNow software based on their AD security group. This should help to make their experience of the AppSense environment a lot smoother and more user-friendly, which can only be a good thing!

    0 0

    The security settings in the AppSense DesktopNow Management Center are, well, to be quite nice about them, a little clunky and unintuitive. As it often takes a while to get your head around these when you are looking to get something done quite quickly, it would make sense to do a quick article on setting up some basic permissions for Management Center access. So, here we go!

    Before we begin, it might make sense to define what we want from the security roles we are about to set up. In my test lab currently, we have one Deployment Group set up (the imaginatively named "#1"). We are going to set up three distinct custom sets of permissions:-

    1.  Allow users to log in to the Management Center and create, view and modify packages globally
    2.  Allow users to log in to the Management Center and deploy packages globally
    3. Allow users to log in to the Management Center and assign computers to the Deployment Group #1 only

    It's worth noting now that AppSense Management Center divides permissions into two distinct types - Server and Object. Server roles operate globally across the Management Center, whereas Object roles can be assigned to specific objects such as Deployment Groups, configurations, reports, agents and Alerts. The granularity you can achieve by combining these two sets of permissions is quite diverse - it is simply the lack of intuitiveness in the UI that achieves this that holds it back slightly.

    So the first thing we would need to do is add our groups and then define our custom roles. We will need two custom server roles for permissions sets 1 and 2 described above, and a custom object role for permissions set 3.

    First we will need to open the Management Center and connect to a Management Server. Then, from the left-hand side menu, select the Security tab.

    Next we will need to add the groups we want to use in these custom roles to the Management Server. Click on the Add Group button and add the groups you need. It's important to add users and/or groups here, as this is where the right to log on to the Management Console itself is defined. Even if you add users and groups specifically to object Security properties, they won't be able to log on to the console to exercise said rights unless they are specifically added here.

    The default security setting is "Logon Allowed but no Server Permissions", meaning that group members can access the Management Center but not perform any tasks until they are specifically given the permissions. As we haven't defined our custom roles yet, we won't add any of the default ones. The predefined ones are:-

    Server Roles

    Modifier - permission to perform edit and delete actions across the whole management server.
    Server Administrator - permission to perform create, edit and delete actions across the whole management server. This role is assigned by default to the user installing the Management Center.
    Viewer - permission restricted to read-only across the whole management server.

    Object Roles

    Viewer — permission only to view the object.
    Modifier— permission to perform edit actions, but not delete actions, on the object.
    Full Control— permission to perform edit and delete actions on the object.

    Now we need to define two new Server Roles and one new Object Role. Click on the Security Roles | Server icon in the left-hand pane, and then click New Server Role. For our "Package Admin" role (number 1 in the list we compiled earlier), we will choose the following options:-

    And for our "Deployment Admin" role (number 2 in the list we compiled earlier), we will follow the same process and choose these options:-

    Now our Server Roles list should look something like this:-

    Next click on the Object tab underneath Server in the left-hand pane and choose the New Object Role task from the Action pane on the right. Add the options as required below for our "#1 Computer Assignment Admin" (number 3 in the list we compiled earlier)

    And now our Object Roles list will look like this:-

    Next we will switch back to the Server Permissions section in the left-hand pane and highlight the first group we added, in this case this was the AD group First line support. Click the Edit Roles button in the Action pane

    We will now see that the Server Roles we have added are available to be added here. We will add the First line support group to the Package Administrator role

    and add the Second line support group to the Deployment Administrator role using the same Edit Roles button

    You will notice when doing this that you can Deny as well as Allow each role. The Deny functions would be used normally when using groups that may overlap in their responsibilities - for instance, when a user is a member of a group that allows Server Admin access due to some other permission defined on the group that the user requires. In this case, you would define a Deny for the user to disallow the access (although really you should separate the responsibilities assigned to the group into two separate AD groups). When you define a Deny, the Security Role appears in brackets to denote the denial.

    Now our list of Server Permissions looks like this

    Those two server roles, which are now assigned, should fulfill our first two requirements successfully. However, we still need to define a group that can add Computers to Deployment Group #1. As you may have guessed, even though we have defined the Object Role for this we now need to apply it directly to the Deployment Group itself, so switch to the Deployment Groups tab.

    Right-click the Deployment Group we are looking to manage, and click the Security option

    Click on the Add button and select the user or group you wish to add. In this case we can choose directly from AD (a little demonstration of the non-uniformity of the Security parts of the console here), but we will need to bear in mind that adding a user here does not grant the right to access the Management Console, as I mentioned earlier. We should also see at this stage that we can select our custom Object Role for the user or group at this point.

    If you give a user or group rights to do something to a Deployment Group (such as in this case, add Computers) but not to View the Deployment Group, you will run into an issue, insomuch that the user can't see the Group to add Computers to it! So in the screenshot below, you will see that the Viewer permission has been added as well as the custom role.

    Now we have successfully set up our third requirement! So, let's log on as a user who needs one of these three requirements and see if the security roles we have set up work correctly. (Handy hint - you don't need to open multiple sessions to test AppSense permissions - when you connect to a Management Server, there is always a "Connect As" option displayed which lets you connect as a different user. Neat!)

    First we will log in as the user who has been simply given permissions to add Computers to Deployment Group #1. Straight away you notice a few differences in the initial logon screen. You can see that the Global Permissions are Restricted

    We do, however, have the option to view our Deployment Group titled #1. However, when we browse each screen in the Deployment Group you will again see a restricted interface. For instance, the Assigned Packages screen looks very bare

    and the Installation Schedule screen can't be interacted with much at all, despite repeated attempts

    The Computers screen, though, allows us to still make use of the Add and Discover functions, which is what we'd expect

    We can continue this process with members of the two AD groups that we set up with global server permissions, but now that you've seen it in action once, I will leave it up to yourselves to explore the various permissions that can be set, and how they then behave when you launch the various management consoles associated with AppSense DesktopNow software.

    One final word that I should mention - ownership. As in NTFS land, the ownership attribute trumps all other permissions and overrides any restrictions which may apply. You can set the owner explicitly on objects within the Management Console. I am fairly sure that also as in NTFS, the creator of an object becomes the owner initially.

    So that covers a quick run-through of the basic security permissions and roles within the AppSense consoles. Note that this doesn't include Personalization Server access - that's controlled from within the User Personalization part of the Environment Manager console under Global | Access Rights. The configurable user roles are a lot more linear in Personalization Server - you are simply assigned a role from Administrator, User, Web User, Web Administrator and Self-Service as shown below. Because these roles mostly deal directly with accessing the Personalization data through the web interface, we will leave this part of it for the article on setting up web access and self-service - hopefully coming fairly soon!

    0 0

    I still get quite a lot of requests from people regarding how to add applications into Personalization Server. A few of these requests revolve around best practices, but the lion's share are about actually how to get the applications in there with the minimum effort required, mainly from people with limited time and resources who are also concerned about the effects on their user sessions and application performance if they haven't configured Personalization correctly. We will use this post to do a quick run-through of how to add a simple application into Personalization for those who need a step-by-step guide, and use the Config Assistant and Template Creator to (hopefully) keep the data being saved as lean and mean as possible.

    Remember that this "application personalization testing" process should generally be done for all applications prior to go-live or, if you've new applications coming on-board, in a test environment that runs alongside your live systems. As we are going to use the Config Assistant rather than just letting Personalization Server discover all the user data itself, and additionally, we're going to remove the global includes and excludes, we can expect this approach to a) increase the database load, and b) possibly affect the Personalization of live systems that are relying on the global includes and excludes. I know most of my readers are quite savvy, but I never know when a lawsuit could be coming my way, so the disclaimer is here nice and early :-)

    Obviously you first need to have the EM agents deployed to your endpoints and Personalization turned on in your deployed configuration. You'd be amazed how many times people (including myself) forget to actually turn Personalization on in the config.

    We also need to be at version 8.3 or higher if we are going to use the Config Assistant Template Creator. If your infrastructure is 8.2 or lower, you can only use the Config Assistant and you will have to cut and paste the necessary Registry keys and folders straight from the Config Assistant into the Personalization console.

    Next thing to make sure you've got configured is a Personalization Group that your test users are actually a member of. Obviously, if no Personalization Groups are configured, then users will be caught by the Default Users group, but it is not intended to be used for actually deploying Personalization applications.

    Note - when configuring the Membership Rules for your Personalization Group, try to avoid the use of Computer Group and Computer Name rules. It also pays to try and keep them as simple as possible - lots of ORs and ANDs doesn't help the processing time.

    Now, we need to turn on Data Collection in the Properties tab of our Personalization Group. As we are going to use the Config Assistant (discussed in this previous post) to help us personalize the application, this is a necessary step. I'm not clear on whether Data Collection also requires the "Automatically Discover User Applications" function to be turned on, but as I've seen some spurious output when it's not activated, I generally also make sure it is on at this stage.

    You will get a warning at this stage about the increased overhead of Data Collection, simply accept the warning and continue.

    Now at this stage a lot of people would add the application they are trying to personalize into the Applications | Application Categories | User section and then Whitelist it for their target Personalization Group, but this shouldn't be done. The Config Assistant will only gather data on applications that aren't whitelisted, and when you create the template, any existing entry in the Application Categories | User section will be overwritten anyway, so neither of these actions is necessary.

    The next step would be to make sure that the Global Includes and Excludes in your Personalization Server are set to the lowest level possible (i.e. - nothing and everything). Now, as mentioned earlier, please don't blithely change these options in an environment where applications are already personalized and being used - there's a very good chance you will break the existing Personalization. Ideally, you should set these options as you begin your initial Personalization discovery process. You will find that each application will take a little bit more work when you use the Global Includes and Excludes in this way - but after a period of time, you will realize your Personalization database is leaner and meaner than it would have been with the default options left set. In some environments, where the Personalization database has become bloated and unwieldy, I have seen clients who opted to create a new Personalization database and re-import all their applications by following this process, and then moved their existing users across to the new database.

    The Global Includes and Excludes (which are found in the root of the Applications tab, on the left-hand pane in the User Personalization part of the Environment Manager console) configured in this aggressive format should look like this:-
    Registry Global Includes
    Folder Global Includes
    Registry Global Excludes
    Folder Global Excludes

    I must proffer an apology to Richard Thompson at this point. As I am currently working on a live system with no access to my test lab, I had to steal the previous four screenshots from his own blog article regarding best practices for Personalization. It's a good article and can be found at this link. Sorry Richard :-)

    Next we are going to pick an application to capture data for. In the interests of keeping this article as simple as possible, we will go for the time-honoured lite version of Word that nobody ever uses but is present on just about every Windows system since the 90s - Microsoft WordPad.

    First we will log on as a test user and run WordPad. Initially we will run it and find a setting that we can change so that we can see where it writes these settings to. Ideally, with every application you should explore as much functionality as possible - particularly functionality that interacts with other applications and other parts of the operating system. For purposes of this demo, first we will open WordPad as normal

    and then we will turn off the options that show the rulers and the status bar, before adding a few items to the Quick Access Toolbar

    Once we've done that, we need to make our way across to the system where we have installed the Config Assistant. The installation of the Config Assistant was covered in the previous article I did on this, so we won't need to go through that again now. Start the Config Assistant as normal

    and click the Connect button, which shows you the following screen

    (don't forget to specify Server\Instance, rather than just Server as in the screenshot). Click OK to connect to the data which has been collected, which will show you a summary screen before reaching the main window. As mentioned in my previous article on the Config Assistant, I normally use the Reset function from the Maintenance menu as soon as I enter the main part of the interface, but I am still not sure whether this is absolutely necessary in the latest version. It certainly was necessary on the 8.2 system I tried it on :-)

    Now we can click on the Current Applications menu on the left-hand side and see if any data has been collected for our WordPad application.

    Excellent! There it is. So now I will click on the Application Registry Usage menu item to see what Registry keys it has been reading from and writing to (the Reads and Writes are denoted by the respective columns in the screenshot)

    and just for posterity, clicking the Application Folder Usage menu item will show which folders in the filesystem it has been reading from and writing to (again, there are separate columns)

    Well, there would be separate columns, but as you can see from the screenshot the No data available message indicates that the application hasn't actually read from or written to the filesystem at all.

    Anyway, let's assume we are happy with the data we've captured. How do we get information for a particular application that we've captured from the Config Assistant into the Personalization Server console, and hence, the database? This is where the nifty little utility called the Configuration Assistant Template Creator comes into play, which we will just refer to as the Template Creator from now on. It's a standalone executable with an accompanying config file that you can download from MyAppSense on this link.

    Once you've downloaded and extracted the two files (no installation is required), you simply need to run the executable, where you will be confronted with a screen where you can supply the database server name (and instance, if necessary), and the name of the database itself

    Once you click the Submit button, assuming you haven't made any typos or something is blocking the connection to the relevant ports, you should see a screen something like this

    The Template Creator interface shows you a list of applications which data is available for on the left, the version numbers in the centre, and the captured Registry keys and folders on the right. You can select the application you require and the version number by clicking on them, and then you can multi-select the Registry keys and folders you wish to add to the template. In this example, we don't want to keep the Registry keys that reference Adobe Acrobat (it's interesting to see some of the strange places that do get written to by applications!), so we will select the rest of the Registry keys as shown below

    and then click the Create Template button to save it to an XML file. The interface will ask you for a location and filename, as you'd expect.

    Next we head back to the Environment Manager Console window, in the User Personalization section, and locate the Tools | Import button

    Select the XML file you created earlier for import. Next you will be presented with the following warning, which you can suppress if you are planning on doing a lot of these. As you should be working on a test or pre-live database with a good backup strategy, you shouldn't need to worry too much about anything going awry.

    Then you will see the Configuration Import window. As we haven't grouped any applications together, we opt not to import the Application Group, simply the User Applications. Naturally, if you had used the Config Assistant to group some applications up, you should use the Application Groups option.

    Now, as I was doing this to a test database that already had some applications added to the User section, I didn't realise wordpad.exe already existed in there. But handily, this gave me a dialog that you might see if you're in the same or a similar situation. When a conflict is detected, you can opt to Replace or Skip - I've obviously selected the Replace option

    Finally you will get this warning that reminds you that you should have a backup in case anything goes horribly wrong

    Once the import successfully completes after you click OK (and despite all the warnings, I've yet to see one go horribly wrong - although that isn't an excuse for you to avoid backups!), you can now view your application or application group and see that the Registry and Folder Includes and Excludes have been nicely configured for you
    Registry Includes and Excludes from the imported template
    Folder Includes and Excludes from the imported template
    Now this takes us on to another interesting point - the consolidation of Registry keys and folders. In the example above, we are capturing a large amount of Registry keys under two particular parent keys. Now if a root folder is selected, there's no need to select child keys or folders. However, in this case, as the root key is \applets\WordPad, there's a good chance that the entire root key is both relevant and required. So I will use a bit of common sense and condense the Registry Includes and Excludes to the following

    So now for the big question - will the Personalization Server now save my data? Well, I log back in as my test user, run WordPad again and hide the rulers as well as adding lots of items to the Quick Access Toolbar - and then I close WordPad and log out. When I log in again and run WordPad, what do I see?

    Excellent! As you can see from the screenshot, all of the Quick Access Toolbar is being restored, and I also don't see the rulers or the status bar.

    So, now you can take this process and apply it to all of your applications to get them Personalized in as streamlined a way as possible. Personalization done in this way takes time and effort - but it is worth it, as you maintain good application load and response times, and keep the Personalization database from growing beyond control.

    I think it would be an idea for Personalization Server to be configurable in a couple of different modes - POC Mode, which would turn on a lot of Global Includes and Excludes like it does at the moment, and Production Mode, which makes the defaults as we have configured in the article you've just read. That's something for AppSense to look into for future releases maybe, I will certainly try and run it by them.

    Additionally, I am hoping to publish a few XML files soon which should allow you to import the settings for commonly-used applications into your Personalization Server console which should hopefully reduce the amount of time it takes to get a Personalization infrastructure up and running. I am currently testing a few of these and should have some published in the near future.

    0 0

    A long time ago I did a post on how to detect iPad and/or iPhone sessions. Whilst effective (at the time), it was rather blunt and prone to becoming useless as soon as the hardware changed in any way. So since then I've been meaning to try and find a slightly more reliable way to perform detection routines on a connecting client.

    Firstly, why would you want to know the OS of a client connecting to your Citrix infrastructure? Well, as mentioned in the original post, you can tailor the user experience based on the device the user is utilizing - resolution- and control-wise. You could block certain devices from being able to launch sessions or apps, should you wish to. You can also gather statistics on your connecting devices, if you need to report on how many users are using particular devices. There's probably a plethora of uses you could come up with, so the reason I like to build this into my configurations is that when the day comes that you have a requirement to know this, it's already there, just waiting to be utilized.

    Secondly, as a total dinosaur, I fell back on my natural tendencies and elected to use CTXCliOS.exe from the clever guys at Ctrl-Alt-Del IT Consultancy to provide me with the information I need. If you've never come across their utilities before, they are well worth a look - any terminal server admin worth his salt can definitely find some mileage in the freeware utilities they provide on their site. The caveat around CTXCliOS is that it will only run on Citrix systems (so if you're looking to do this on RDS, that'll probably have to wait until I can brush up on my scripting). The utility returns values for the systems shown in the screenshot below, so it's fairly comprehensive.

    Naturally it makes sense to do this via a Reusable Node. We are going to write the result of the query into the Registry at HKCU\Software\Custom\AppSense in a value called ClientOS, but naturally you can tailor the type and format of the flag to whatever you feel comfortable with.

    As we need to check whether the CTXCliOS.exe utility is actually present on the Citrix system before we can execute it, it would also make sense to do this via an If Else Group, which if you remember are found in the context menu of your EM console under Condition | Flow Control | If Condition.

    In the Expression Builder window we will now add a Condition to check for the existence of our executable. If you've got the executable stashed away on a share somewhere, you could always perform some sort of file copy Action to make sure it's always available, but for the purposes of this example in which we are dealing with a PVS system, we'll just list the client OS as UNKNOWN if the executable isn't there. As PVS should ensure all Citrix systems are identical, we're pretty sure that the executable should always be there.

    If the file exists, we'll next need to check that the target Registry key to hold our flag value exists. If it doesn't exist, we can use an EM Action to create it, so let's do something a bit funky here, and nest an If Else Group inside another one.

    In the Else section of this nested If Else Group, we will need to create the Registry key if it doesn't exist, so we will add that Action now

    Now, we need to actually run CTXCliOS.exe and write the value to the Registry. However, as it's a command-line tool, if we write a separate command-line batch script to trigger it, we will have yet another file (in this case a .bat or .cmd file) to worry about providing on the endpoint. Is there a better way to trigger the command-line executable from within AppSense EM?

    Well of course there is, don't forget that Environment Manager has built-in scripting support for JScript, VBScript and PowerShell. Wherever possible, I'd recommend that you exclusively use PowerShell to do your various scripting bits and bobs, because it's becoming something of a standard across various different software technologies. In fact, now that I mention it - I hope my loyal readers love the way I tend to remember things halfway through writing posts - there are PowerShell extensions for Citrix that can probably achieve what I am trying to do here without leveraging an external file. Well - I've started doing it this way now, and it seems like a useful exercise, so I will leave the thought of moving this whole process exclusively into PowerShell for the future :-)

    So next we will need to insert a Custom Action under both parts of the nested If Else Group. As I'm not much of a PowerShell guru (yet!), I must send a credit to Ben Scott (for throwing me a fish) and Michael B Smith (for trying to show me how to fish) for their help in creating this simplistic line or two of code.

    The Custom Action uses this script

    $match = & d:\apps\CTXCliOS\CTXCliOS.exe | Select-String -Pattern 'ClientOS=(.+)'
    if($match) {
            $clientOS = $match.Matches[0].Groups[1].Value
            Set-ItemProperty -Path 'HKCU:\Software\Custom\AppSense' -Name ClientOS -Value $clientOS

    which runs CTXCliOS.exe from the path specified, pulls the required part of the output, and writes it into the Registry at HKCU\Software\Custom\AppSense in a value called ClientOS. So now your entire nested pair of If Else Groups should look something like this

    Now the final thing to do for this part is to complete the original If Else Group by providing an Action for the Else section, which in this case would be to write an "UNKNOWN" value to the Registry for ClientOS, because if it reaches this stage it means that CTXCliOS.exe can't be found

    So, the entire Reusable Node now looks like this

    and we can reference this Reusable Node in the Logon trigger to ensure that we have a record of the connecting client OS. Cool!

    However, let's not forget that a user can disconnect from a session and reconnect from another device, so we will create another Reusable Node to unflag the OS (i.e. delete the Registry value we created)

    We can reference this node (the one to unflag the OS) in both the Logoff and Session Disconnected triggers. Naturally, once we've done this, we will also need to reference the first node we created (the one that flags the connecting OS) in the Session Reconnected trigger. Dependent on your testing, and whether or not you are using XenDesktop, you may also find it prudent to put the flag node in Session Unlocked and the unflag node in Session Locked. Underneath is a screenshot showing the linked Reusable Nodes to give you an idea what I am getting at.

    So there we have it - a way to write the connecting client OS on your Citrix systems into the Registry for manipulation in any way you see fit. The configuration we created in this post is available here, should you wish to download it for yourself - the usual caveats apply.

    0 0

    In a lot of places where AppSense is used to manage virtual (VDI or SBC) sessions as well as physical ones (laptops and desktops), there are often different configurations for each. However, these different configurations often have a lot of common ground, so if an administrator updates a setting on one configuration and forgets to update the same setting on the other, you're going to have problems. To get around this you can use a single, monolithic configuration and simply insert some kind of custom detection to apply the settings that need to be different for physical endpoints, which means that the shared settings only have to be updated once, removing the potential for error.

    So how are we going to identify a physical session as opposed to a virtual one, and then how are we going to split it into desktops and laptops (as there are often settings required for mobile devices that differ from those applied to static ones)? A long time ago I wrote a post about how to perform laptop detection based on the presence of a battery, but I did note at the time that the explosion in tablet computing and other mobile devices would soon pretty much render this obsolete. One of the comments at the time was from a guy called Chris who mentioned detecting the chassis type using a WMI query. Whilst I'd looked at this, it seemed a bit convoluted at the time.

    However, now that I've actually had to cross this bridge in a work situation, I've actually had to go and do the hard part (always the way, isn't it?) :-)

    For the first part - separating virtual and physical sessions. This is fairly simple. You just need a node with a couple of Reusable Conditions held together with an OR. The first Reusable Condition simply checks for Remote Desktop Services (Terminal Services to the slightly older amongst us) on the endpoint

    and the second runs a check for your VDI poison of choice. In this case it was XenDesktop, so we can simply reuse the "check for XenDesktop" Condition we've mentioned a couple of times in earlier blog posts.

    So, now I will create a new Node in my Logon trigger and OR these two Reusable Conditions together like so

    which means that any child Nodes of this node will only execute if one of the Conditions are satisfied, so the child nodes will hold the settings I only want applied to virtual sessions.

    Naturally if you also have settings you only want applied to physical sessions, you can "reverse" this node and create one that works the other way. Note, however, that this is an AND instead of an OR, as both of the "negative" Conditions, as it were, must be satisfied.

    From here all of your settings for physical sessions would be set as child Nodes of this node. You could also get away from having to have two separate nodes by utilizing a single node with an If Else Group as below

    It's up to you which method works best for you - probably determined by the complexity of the Actions you need to perform for each session type and whether sub-nodes are necessary or not.

    So now we can separate the settings for virtual vs. physical, how do we divide the physical endpoints into laptops and desktops? Whatever we choose, it's obviously going to be a permanent setting for the endpoint, so what we can do is perform a detection at startup, write a Registry key, and then use that Registry key as the Condition for stopping the detection running again.

    As I appear to be rather fond of If Else Groups at this moment in time I don't see why I shouldn't leverage another one for this situation :-) To start with, though, we will put in a check for the Registry value we are going to write. We only need to run this detection once, so once the Registry value is written for the machine type, we don't want it ever to run again. So the If Else Group is going to be dependent on the non-existence of the Registry value

    If this Condition is satisfied (i.e. the Registry value specified doesn't exist), we will open our If Else Group with a check to see if the machine is a desktop. As we are leveraging the ChassisType property from the Win32_SystemEnclosure class to give us this information, it's about now that we actually need to know what possible output we could get. If you haven't seen the output of the ChassisType property before, here's a list of what it may return

    ;1 Other
    ;2 Unknown
    ;3 Desktop
    ;4 Low Profile Desktop
    ;5 Pizza Box 
    ;6 Mini Tower
    ;7 Tower
    ;8 Portable
    ;9 Laptop
    ;10 Notebook
    ;11 Hand Held
    ;12 Docking Station
    ;13 All in One
    ;14 Sub Notebook
    ;15 Space-Saving
    ;16 Lunch Box 
    ;17 Main System Chassis
    ;18 Expansion Chassis
    ;19 SubChassis
    ;20 Bus Expansion Chassis
    ;21 Peripheral Chassis
    ;22 Storage Chassis
    ;23 Rack Mount Chassis
    ;24 Sealed-Case PC

    I know what you're thinking - mental! Still, after a lot of thought and discussion, I came to the conclusion that chassis types 3, 4, 5, 6, 7, 15, 16 and 24 would denote a desktop, and 8, 9, 10 and 14 would indicate a laptop. Any other returned type I would designate as OTHER, which would ensure that it didn't get the specific settings for either desktops or laptops.

    So, with this in mind, I am going to create the Condition for my If clause as a Condition | Custom and use this bit of scripting to identify a desktop machine

    and if this returns successful, we will write the Registry value to denote this

    Next we will insert an Else If (highlight the first If clause, and choose the Flow Control item from the Conditions tab)

    and we will modify the previous script ever so slightly, so now it returns success if it meets the output that we've decided denotes a laptop system

    So now the Action underneath this clause will write the Registry value to indicate a laptop

    Finally, if the two Custom Conditions specified in our two clauses don't return success, we will write the Registry value as OTHER

    So now we have a Reusable Node that is intended to run when the AppSense-enabled endpoint starts, and write a Registry key denoting the machine type. We can now reference this Reusable Node in the Computer Startup trigger, which means that if there is no Registry value denoting machine type one will be written at boot time.

    If you want to make use of this Registry value, all you simply need to do is write a Condition or Reusable Condition that checks it. For instance, the Reusable Condition below is used for laptop detection

    and it should be completely straightforward to do the same for desktop detection.

    Well, hopefully that should take care of the detection not just for physical/virtual, but also for laptop/desktop, at least for the foreseeable future. OK, maybe not for the foreseeable future, but until I find enough spare time to brush up my (very basic) PowerShell and convert these detections to something a lot more elegant. Or maybe just long enough for AppSense to build these sorts of detections into the DesktopNow software natively? That would be ever so cool ;-)

    0 0

    It's a long time since I last focused on anything to do with the usage of Group Policy settings and files in Environment Manager. To be honest, the original article is getting a bit old - and some of the images seem to have become corrupted, rather distressingly - so we will give it a quick rewrite and bring it back to the present day :-)

    Let's start with some basics.

    Why use Environment Manager to deploy Group Policy settings?

    Why indeed? Most environments have the Group Policy engine running alongside their Active Directory infrastructure, so why would you need to use EM to deploy your GPO settings? Well, first and foremost is the idea of having "everything under one roof". I've worked at lots of places where, to troubleshoot a user issue, you'd have to look at the AppSense console, rake through Group Policy, dig into some Citrix policies, open the App-V Management Console, and finally read through a logon script. All this takes time, and for support guys time is often of the essence when users are screaming about not being able to work. If you are using AppSense the software has enough power for you to seriously consider using it as your "one-stop shop" for the deployment of all user settings - and, if you want to, a lot of your machine ones too. AppSense Environment Manager and Application Manager together can give you all the functionality of most GPOs, just about anything in Group Policy Preferences, probably everything you ever wrote into logon scripts, deploy streamed apps from App-V and replicate most (but not all, sadly) of the functionality you get from Citrix policies (something which we will touch on in a later post).

    The limitations around the GPO functionality reside around things that are normally found outside of the Administrative Templates, which include things such as setting startup types for services, account policies, and the like. If you desperately needed to get all GPO functionality into the AppSense console, you could accomplish it with registry imports and custom scripts, but there's no shame in having some of your settings still provided by standard GPOs, particularly if they are flowing down into your AppSense-enabled systems from a higher OU. A lot of places adopt a mantra that sometimes you will hear from AppSense themselves - "manage the user through AppSense, and the device through Group Policy". Whilst not suitable for all, it's certainly a good guideline to adopt if you occasionally find EM and GP at odds with each other.

    And don't forget, there's always the chance that later versions of AppSense EM and AM may incorporate functionality that allow you to do these things that currently you have to fall back on GPOs to accomplish. For instance, the latest version of Application Manager includes the functionality to dynamically assign User Rights to users or groups from the domain. There are also functions in Environment Manager that cover commonly-used GPO tasks like Folder Redirection, which in Group Policy land is also outside of Administrative Templates.

    When Microsoft acquired the Group Policy Preferences part of their software they certainly ramped up the competition between themselves and AppSense, but AppSense still wins on one major count - the unique trigger actions that AppSense allows you to take advantage of. Currently, user-level Group Policies apply at logon and then reapply every x minutes, machine policies apply at startup and again every x minutes. With AppSense, you can cut down your logon time by only applying the GPOs when you need them - "just in time, not just in case". For instance, if you had a whole host of GPOs associated with Microsoft Word, why do they need to be imported when a user logs in? Using AppSense EM, you can import them when Word starts, saving valuable logon time - and also ensure that the policies are never applied again until the user starts a new session. Without AppSense, you can only limit the scope of your GPOs by OU/site, or by security group/user, unless you fancy doing some tricky WMI filtering. With AppSense, you have a whole host of Triggers and Conditions to take advantage of that are quick and easy to set up. You could launch GPOs based on logon/logoff, processes starting, session locks and unlocks, registry keys, environment variables, date and time, files and folders, screen resolution, even screen colour depth! Most, if not all, of the "item-level targeting" features you get from Group Policy Preferences are available through Environment Manager - with the added bonus of the triggers too, which GPP doesn't have in its armoury.

    I also prefer to use Group Policy Actions with AppSense Environment Manager rather than using Registry Actions. This preference also involves me using old-fashioned .ADM files as well as .ADMX files, because I find it easier to write old ADM files than use XML :-) But seriously, I know Microsoft themselves actually recommend using Group Policy Preferences to deploy Registry settings rather than using an old ADM file, but look at it this way - from the two screenshots below, which of them is better at telling the administrator what the setting you are deploying actually does?

    Deploying a setting via a Registry value (whether set by EM or GPP) - not very clear as to what the setting does

    Deploying a setting via a Group Policy file - much more clear as to what the setting does
    Naturally, it's the second one - the ADM file we have created gives us much more of an understandable explanation than the simple path to the Registry key, some of which can be far more cryptic than the example provided.

    AppSense's implementation of Group Policy is also configurable in little ways that make it even more appealing. There's the option to use User Personalization to either override or be overriden by GPOs - essentially allowing you to turn any Policy into a Preference of sorts. They also have a handy "apply policy settings permanently" check box which lets you decide whether or not the GPO can "tattoo" the user profile. There are settings similar to this in GPP - think "remove this item when no longer applied" - but the AppSense setting can also apply to standard GPO settings.

    However - there are limitations. Group Policy is applied on a scheduled refresh basis, whereas the AppSense policy is pushed out based on pre-determined triggers. Additionally, in a PVS or other streamed-disk environment, Computer GPOs are much easier to deploy than AppSense Computer Startup actions, which currently necessitate a vDisk update every time you make a minor change. There's also the overhead of finding out some of the Registry keys involved and/or creating ADM/ADMX files for settings you may find that are beyond the scope of the software - although AppSense are getting good at adding new things into there as time goes by.

    And now onto the bit you really want to know :-)

    So, how do we deploy Group Policy settings using the AppSense console?

    Well, the first thing to do is create a central share or repository where you can find all of your required ADM and ADMX files and add new ones as required. You can either create a central area or alternatively place them all into your golden image, if you're using a technology like Citrix Provisioning Services. The main thing to remember at this stage is put the files somewhere all admins can get to them - no matter where they have the consoles installed - because there's nothing more frustrating than an error message like this when you are trying to edit a GPO Action

    So, once you've done this bit and ensured that all of your ADM and ADMX files are globally available to your designated admins, let's start creating some settings! We will put together some settings for the Screen Saver in this example.

    Another quick note before we start - for troubleshooting and optimization purposes, it is important to keep your GPO Actions as "one setting, one Action". (I mean each GPO setting you configure should be contained in an individual Group Policy Action in the console, in case I'm not being clear enough) Now, if because of previous bad practice you end up having to migrate a single Action containing tens or hundreds of settings into individual ones, you may experience a lot of frustration - but believe me, the frustration will be worth it because it will a) run more smoothly, and b) be a hell of a lot easier for your support staff to troubleshoot. When you have many settings in one Action, you can only disable them individually by removing and re-adding them - but if you have one setting per Action, you can simply right-click and choose Disable, making trial-and-error troubleshooting vastly easier. Examples of good and bad Actions are shown below.
    An example of a BAD Group Policy Action - many settings in the single Action
    And a GOOD Group Policy Action - a Node with lots of settings in individual Actions
    Now, we are going to put these Screen Saver settings in the Logon trigger, as that is the most logical position for them. If you were creating something like Microsoft Word settings, you would place them inside the Process Started trigger for winword.exe, as we must load our policy settings when we need them - not if we need them.

    To insert a Group Policy Action, we right-click in the right-hand pane and choose Action | Group Policy | Set ADMX Policy or Set ADM Policy (naturally this is defined as to whether you are using ADM or ADMX files for the settings!) Most newer Windows systems use the XML-based ADMX format, as will most custom files these days, unless they're written by me :-)

    Next you will be confronted by this screen. If you've stored your ADM/ADMX files in a different location to the default (the default for ADMX is c:\windows\PolicyDefinitions, and for ADM it is c:\windows\inf), you will need to use the Browse button to locate the folder where the target files are stored.

    Note the "apply policy settings permanently" option (unchecked by default). If this option is checked, the settings applied by your Group Policy Action will not be removed at logoff. Effectively, they will be saved as Registry settings under the user Registry in the user profile (ntuser.dat, if it's writeable) or into Personalization Server, if you're using it. Machine settings in this case would be saved into the endpoint's own Registry. I'd recommend not using this setting unless you have a particular need for it - otherwise you may end up putting together Registry Actions just to reverse the possible implications of one-time Group Policy Actions.

    Some people have recommended using the "apply policy settings permanently" feature, especially with mandatory profiles, to ensure that issues with mid-session configuration changes don't revert GPO settings. Whilst this is technically correct - the nature of a mandatory profile will mean that settings can't persist in this way - it's not recommended, especially if you use Personalization Server, another profile management tool or any form of Registry hiving. If you're having issues with mid-session configuration changes, I'd update to the very latest version of the AppSense DesktopNow software and log a case with AppSense support if your issues continue, rather than continuing to box around the issues by using a feature that could give you problems in the future.

    Next we click the Add button to add in a policy and are presented with this screen. Obviously, if you've already defined some policies here, you can use the Remove button to get rid of them - although if you've stuck to "one setting, one Action", then you just have to remove the Action itself, and the Remove button will become redundant.

    This screen shows you all the available Group Policy settings from the folder specified earlier (so if you've got something like the Microsoft Office ADMX files loaded, expect to see a lot more settings displayed here). Note in the bottom left of this screen, the input bar which allows you to Filter the settings. This is a very handy utility - start typing into it and it will dynamically filter the settings until you find the one you're looking for. In this case, we will start by typing Screen saver

    and you can see that the list of available settings has been reduced instantly, making the job of finding a setting so much easier. Cool!

    So now we will locate the setting we want to deploy, which is Enable Screen Saver, and double-click the setting to configure it

    then click OK three times (yes, three times, that's a bit of a pain, unfortunately), and we're done!

    Now it's time to rinse and repeat this as many times as necessary to get all of your Group Policy Actions set up - nesting them as required inside of Conditions and Nodes to achieve the correct settings for all of your users.

    It's worth mentioning that I've seen GPO settings deployed in this fashion behave somewhat strangely on a couple of occasions when configurations are deployed mid-session, and it doesn't appear to be limited to Actions that avoid the use of the "apply policy settings permanently" checkbox. If you do see anything like this, I'd recommend updating your software to EM8 FR4 SP1 (due to be released in the next few weeks, if I remember correctly) as soon as possible, as this seemed to resolve the issue for me.

    The other feature around Group Policy Actions is the Personalization (UEM) tab. If you are using the Personalization Server feature to save profile settings, if a user changes the setting, Personalization Server will capture this and apply it at next logon. This tab allows you to select whether the policy setting (set by you) or the Personalization Server setting (set by the user) takes precedence. In effect it is giving you the choice of setting this option as a Policy (can't be changed) or a Preference (set at first logon, but can then be altered by the user). In most cases you will probably want the setting to persist, so if that's what you want, set the policy to override Personalization Server as shown below. Note that the Personalization (UEM) tab only appears in Group Policy Actions configured in the Process Started trigger - as Personalization Server only operates on a per-application basis.

    Hopefully this covers all of the questions that people have around using Group Policy ADM and ADMX files in Environment Manager, as well as replacing the damaged article that was published on this subject originally. In my opinion - and especially for userland settings - running Group Policy settings through EM gives you a far more granular control of your user environment. When combined with custom files, they also allow you to do everything Group Policy Preferences can achieve - and more. I am working on providing some downloadable custom files to allow us to work with things that we currently can't in Environment Manager, such as Citrix policies and Folder Options, to name a couple off the top of my head. Hopefully these will be available soon and we can extend the power of EM combined with Group Policy further still!

    0 0

    I've been asked on more than a few occasions whether it is possible to deploy Citrix policies through AppSense DesktopNow Environment Manager, and I've been trying to find information on this for some time (just ask Carl Webster, who I've bugged more than a few times for facts on this subject). I can see where the motivation for this comes from - it's the "everything under one roof" drive that I touched on yesterday when we discussed Group Policy Actions in EM. If you can apply your Citrix policies through Environment Manager, again, it is one less console to check for your support staff. You can also leverage the power of EM to deploy Citrix policies based on the broad spectrum of Conditions and Triggers, which dwarf those available through the Citrix native method.

    Where are policies stored?

    Citrix policies, since the advent of XenApp 6.x, can be deployed "old-style" through the IMA, or alternatively via Active Directory Group Policy if you've loaded the Citrix Group Policy Management add-in. However, rather disappointingly, they can't be managed via ADM or ADMX files. To quote Citrix directly - "Citrix policies are associated with Group Policy Objects (GPOs) using console extensions. Citrix policies are stored in Sysvol together with the ADM files, but they are not ADM templates. There is no Active Directory schema extension."

    They may not be manageable by ADM files, but they certainly are written to the Registry, which allows us to manage them through AppSense Environment Manager Registry Actions. Strangely enough, both Citrix User and Machine policies write to the HKEY_LOCAL_MACHINE area of the Registry. The areas they write to are


    MACHINE - HKLM\Software\Policies\Citrix
    USER - HKLM\Software\Policies\Citrix\<SessionID>


    MACHINE - HKLM\Software\Wow6432Node\Policies\Citrix
    USER - HKLM\Software\Wow6432Node\Policies\Citrix\<SessionID>

    where <SessionID> is the Session ID of the user.

    Finding the relevant Registry values

    So, if we want to manipulate Citrix policy settings through Environment Manager, firstly, we need to work out which Registry values under these keys correspond to each setting. Thanks to Tom over on the Citrix forums, I was pointed in the direction of this article - - which links to a spreadsheet containing the Registry keys for all of the available Citrix XenApp 6.x policies. 

    In the interests of keeping this blog article reasonably short, we will simply elect to use AppSense Environment Manager to set a couple of Citrix policies - one machine, and one user. We will set the User policy to set up shadowing, and the Machine setting for licensing (server name and port).

    Now, you may be thinking that first we may need to run a check for the CPU architecture type, as there are different Registry keys for both x86 and x64 platforms. However - as we are aiming this article at XenApp 6.x, you may recall that this version of XenApp only runs on x64 platforms. If you were using the same process to deploy XenDesktop settings to x86-based endpoints, you would need to put in a check for the architecture type, but for the purposes of this article, it's not necessary.

    The logical first step, then, is to find a way to extract the session ID of the user, otherwise we won't be able to work with the Registry keys for the user policy items. Now, in Citrix terms, this doesn't apply to the RDP session id, but the actual %sessionname% variable which is usually something along the lines of ICA-TCP#x. We will have to strip away the protocol and the hash to leave us with the SessionID, and then write this somewhere. The most straightforward way to do this would be, I believe, to write this to a new environment variable, so we will create a Reusable Node to do this and reference it during the Logon process. We will add a Custom (scripted) Action with the following options set

    And then add the following code to it...please, please, please forgive my ultra-rudimentary PowerShell and the overload of variables - all suggestions about making it better are welcomed.

    $session = $env:sessionname
    $split = $session.split("#")
    $split1 = $split[1]
    [Environment]::SetEnvironmentVariable("SessionID", $split1, "User")

    It's interesting to note that we've had to use the .NET Framework and its SetEnvironmentVariable method to make this variable permanent for the user, otherwise the environment variable would have been discarded as soon as the PowerShell process exited.

    Now, we can reference this in the Logon trigger somewhere so that it is set before we get down to the nitty-gritty of setting the Citrix policies in our configuration. In this example, we've called the Reusable Node from a Node Group quite high up in the configuration, and henceforth early in the logon process.

    Note - a lot of you are probably aware that you are supposed to declare environment variables in the root of the Trigger to get them to function optimally. In this case, as we're not doing it native to EM, we can't really do it in the root. I will look at a way to tidy this up in future - for the moment, we've had to sit it as high as possible. The screenshot below shows it added to a Node Group along with some other settings we want to apply fairly early.

    So now we've captured our Citrix Session ID into a variable which will allow us to do the User side of this without error, we can go to work on setting our Citrix policy items by writing to the Registry. What we need now is a way to ensure that we only write these settings into a session that requires them. In this case, we are working with XenApp 6.x sessions, so we will need to write a Reusable Condition that identifies a XenApp 6.x system. How can we do that?

    Filtering the XenApp 6.x systems

    Well, XenApp 6.x only runs on Windows 2008 R2, which is a start. Don't forget we need to write a Condition to identify this on a machine and a user level, as we need to apply policies to both. So for the machine Condition, we will create a Reusable Condition and populate it with these two dependent Conditions (in that they are nested inside each other to create an AND)

    These Conditions check for a Windows 2008 R2 TS-enabled system on which a file called ImaSrv.exe is present in the specified folder. This should pretty much ensure that the system is running XenApp 6.x

    For the user Conditions, we can again create a Reusable Condition but use a slightly different pair of nested Conditions

    What we have now is a Condition that the OS must be 2008 R2 TS-enabled, and the user must be using the ICA protocol to connect - again, filtering out anything but XenApp 6.x sessions.

    Setting the Machine policies

    So, in the Computer Startup trigger we can now reference the first Reusable Condition we just created, preferably in a logical position in the configuration.

    Now we need to create the Registry Actions to enforce our Citrix policies for the machine. If you can recall that far back, we were going to set the Licensing, so we will reference the Citrix policies spreadsheet we linked to earlier and create the required Registry Actions as children of the parent Reusable Condition.

    This value will enforce the License Server host name (change the value as required)
    This value will enforce the License Server port (normally 27000, but change as required)
    Note that the example above shows the value in hexadecimal, but it is in fact set to the default of 27000 for the license server port.

    What might also be prudent is to enter a description for these Actions that tells you (or anyone following your work) what the Actions do, as shown below

    So once you've done all the Citrix policy settings you require for the Machine, we can then move on to the user part.

    Setting the User policies

    We can now reference the second Reusable Condition we created at an appropriate level in the Logon trigger.

    And inside this Condition we will add the appropriate Actions. We were intending to create the user policies for shadowing at this point. Note that we will now start to leverage the %SessionID% variable that we created. Also note that these are HKLM entries, not HKCU like you'd expect.

    This sets the setting for Allowing Shadow Input
    This sets the setting for turning on Shadow logging
    And this turns on the setting for notifying the user about Shadowing
    One thing you will have to do is, given that these are all HKLM entries, is change them to run as System rather than the user, as shown below. Alternatively you could change the permissions on the required Registry keys using something like subinacl.exe or a bit of scripting

    This will ensure that the entries are written correctly.


    Finally, to avoid problems with the %SessionID% variable being maintained across sessions, it would be sensible to configure another Reusable Node to be called in the Logoff trigger. This Action will remove the environment variable for SessionID, ensuring that if you are using the sort of profile management that could persist this, it will not be saved.

    You would then call this in the Logoff trigger, as shown below


    So, now, should you wish to do it, you can move the enforcement of your Citrix Policies out of the Citrix console or ADUC, and into the AppSense Environment Manager console.

    I'm sure plenty of you are saying "why?" I would only do this if there is something specific to gain from the change - whether it is using the breadth of triggers and Conditions available from the EM console, or simply allowing people access who otherwise wouldn't be able to administer the Citrix policies because of political or organizational issues. I've certainly been asked if it's possible a few times, although I concede that most people will probably opt to manage user policies through this rather than machine ones. But it's another good demonstration of what you can achieve with a piece of software like AppSense DesktopNow, if you put some time and effort into achieving it.

(Page 1) | 2 | 3 | .... | 9 | newer