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 among 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 😉