Friday 30 November 2012

Assigning ThinApps by group membership using the SDK

The SDK for ThinApp recently got an update to version 4.7.3 and this prompted me to revisit login scripts I had previously written using thinreg.exe

Download from here: http://communities.vmware.com/community/vmtn/developer/forums/thinapp

The SDK offers lots of advantages over thinreg and will be faster as it does not require Windows to shell out.

The one bit of preparation we need to do is for any desktop going to register ThinApps. With a View environment this is quite straightforward as you can do the following steps to the Master or Parent VM
  1. Copy the ThinAppSDK.DLL (from the SDK download) into the Windows\System32 directory
  2. In a CMD prompt (with Administrator rights) register the DLL with: REGSVR32.EXE THINAPPSDK.DLL
This now allows us to reference ThinApp objects and carry out different operations on them. Full details on the functions are in the PDF document that comes with the SDK download. The most common operations and the ones I was interested in to replace thinreg.exe are Register and UnRegister. In a VBScript we need the following:

First we need to create an object so we can call the ThinApp commands:
 Set TAManagement = CreateObject("ThinApp.Management")

We also need to create a  variable to hold the Package while we work with it.
 Dim Package

We can now set this variable to the thinapp we are going to work with:
 Set Package = TAManagement.OpenPackage(\\server\share\Adobe Reader 9.exe)

This now allows us to Register a package with: Package.Register 1

And Unregister a package with: Package.UnRegister

I put this together into this login script 
Here's a link to download the login script. just remove the .txt extension to leave this as a .vbs file - https://sites.google.com/site/vkiltblog/view_login_sdk.vbs.txt

Save the text down in a vbs file and add it into the GPO that you should have created and linked to the OU that houses the View desktops. See my previous post on details on setting up a GPO for View: GPO's for View

You may look at the script and ask why I'm not using wildcards, why I'm checking for group membership and why I'm checking for registry entries. The simple answer is to speed up the execution of the login script and provide minimal disruption to the user on login. If we use wildcards or don't check the registry then subsequent registers will always be attempted. This can cause the screen to flash and slow down the login. I prefer to specify the thinapp, the group entitled and the registry key so we don't even attempt a register or unregister if it's not necessary. It also makes unregister's cleaner.

To make this repeatable I put the register and unregister in functions and then defined the variables to call that with.

For each application we define the following:
 ADGroup = "Adobe Reader"
 FileName = "\\server\share\Adobe Reader 9.exe"
 RegKey = "Software\Thinstall\ThinReg\Adobe Reader 9_28503025"
 CheckReg = True
 DebugMsg = False

where:
 ADGroup = The AD Group that is entitled to the app
 FileName = "Full name and path of ThinApped exe"
 RegKey = "Registry Key created when registered under HKCU"
 CheckReg = True or False, where True will check the registry to see if the ThinApp has already been registered
 DebugMsg = True or False, where True will popup message on register or unregister

We can then call the function for each application to either register, unregister or do nothing.
 RegUnRegApp ADGroup, FileName, RegKey, CheckReg, DebugMsg

You can also change the DebugMsg variable to True and you will get a pop up message on each register or unregister. You can also turn off the Registry Check by changing CheckReg to False (this is useful when registering a new application and you don't know what registry key will get created by the register). Note that when we don't check the registry each time a user logs in, we will attempt to either register or unregister based on their group membership every time.

More scripting examples can be found here.


ThinApp SDK Login Script


'===========================================================
'<CUSTOMER> Login Script
'===========================================================

'===========================================================
' Set Environment Variables
'===========================================================
Const HKCR = &H80000000 'HKEY_CLASSES_ROOT
Const HKCU = &H80000001 'HKEY_CURRENT_USER
Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE
Const HKUS = &H80000003 'HKEY_USERS
Const HKCC = &H80000005 'HKEY_CURRENT_CONFIG
Set WSHNetwork = WScript.CreateObject("WScript.Network")
Set WSHShell = WScript.CreateObject("WScript.Shell")
Set objShell = CreateObject("Shell.Application")
Set TAManagement = CreateObject("ThinApp.Management")
Dim ThinAppType, Package, RegKey, CheckReg, DebugMsg


On Error Resume Next

Domain = WSHNetwork.UserDomain
UserName = ""

While UserName = ""
   UserName = WSHNetwork.UserName
   MyGroups = GetGroups(Domain, UserName)
Wend

'===========================================================
'Register ThinApps Based upon Group Membership using the SDK
'===========================================================
'USAGE: RegUnRegApp
'<ADGroup = The AD Group that is entitled to the app>,
'<FileName = "Full name and path of ThinApped exe">,
'<RegKey = "Registry Key created when registered under HKCU">,
'<CheckReg = True or False, where True will check the registry to see if the ThinApp has already been registered>,
'<DebugMsg = True or False, where True will popup message on register or unregister>


'=====================
'Register Adobe Reader
'=====================
ADGroup = "Adobe Reader"
FileName = "\\demo.vmware\data\apps\Adobe Reader 9\Adobe Reader 9.exe"
RegKey = "Software\Thinstall\ThinReg\Adobe Reader 9_28503025"
CheckReg = True
DebugMsg = False
RegUnRegApp ADGroup, FileName, RegKey, CheckReg, DebugMsg

'=====================
'Register Firefox 3
'=====================
ADGroup = "Firefox 3"
FileName = "\\demo.vmware\data\apps\Mozilla Firefox 3\Mozilla Firefox.exe"
RegKey = "Software\Thinstall\ThinReg\Mozilla Firefox 3_80d24cdd"
CheckReg = True
DebugMsg = False
RegUnRegApp ADGroup, FileName, RegKey, CheckReg, DebugMsg

'=====================
'Register Virtual IE 6
'=====================
ADGroup = "VirtIE6"
FileName = "\\demo.vmware\data\apps\VirtIE6\VirtIE6.exe"
RegKey = "Software\Thinstall\ThinReg\VirtIE6_742e9c48"
CheckReg = True
DebugMsg = False
RegUnRegApp ADGroup, FileName, RegKey, CheckReg, DebugMsg

'===========================================================
'Exit Script
'===========================================================
WScript.Quit


'===========================================================
'Subfunctions and Routines
'===========================================================
'===========================================================
'Function: RegUnRegApp - Register or UnRegister a ThinApp
'===========================================================
Function RegUnRegApp(ADGroup, FileName, RegKey, CheckReg, DebugMsg)
   If INGROUP (ADGroup) Then
      If NOT CheckReg Then
         RegisterPackage FileName, DebugMsg
      ElseIf NOT KeyExists(HKCU, RegKey) Then
         RegisterPackage FileName, DebugMsg
      End If
   Else
      If NOT CheckReg Then
         UnRegisterPackage FileName, DebugMsg
      ElseIf KeyExists(HKCU, RegKey) Then
         UnRegisterPackage FileName, DebugMsg
      End If
   End If
End Function

'===========================================================
'Function: RegisterPackage - Register ThinApp
'===========================================================
Function RegisterPackage(FileName, DebugMsg)
   Set Package = TAManagement.OpenPackage(FileName)
   Package.Register 1
   If DebugMsg Then MsgBox Package.InventoryName & " has been registered.", 4160, "ThinApp Registration Check" End If
End Function

'===========================================================
'Function: UnRegisterPackage - UnRegister ThinApp
'===========================================================
Function UnRegisterPackage(FileName, DebugMsg)
   Set Package = TAManagement.OpenPackage(FileName)
   Package.UnRegister
   If DebugMsg Then MsgBox Package.InventoryName & " has been unregistered.", 4160, "ThinApp Unregistration Check" End If
End Function

'===========================================================
'Function: GetGroups
'===========================================================
Function GetGroups(Domain, UserName)
   Set objUser = GetObject("WinNT://" & Domain & "/" & UserName)
   GetGroups=""
   For Each objGroup In objUser.Groups
      GetGroups=GetGroups & "[" & UCase(objGroup.Name) & "]"
   Next
End Function

'===========================================================
'Function: InGroup
'===========================================================
Function InGroup(strGroup)
   InGroup=False
   If InStr(MyGroups,"[" & UCase(strGroup) & "]") Then
      InGroup=True
   End If
End Function


'===========================================================
'Function KeyExists - This method uses WMI to check if a registry key exists
'===========================================================
Function KeyExists(Key, KeyPath)
   Dim oReg: Set oReg = GetObject("winmgmts:!root/default:StdRegProv")
   If oReg.EnumKey(Key, KeyPath, arrSubKeys) = 0 Then
      KeyExists = True
   Else
      KeyExists = False
   End If
End Function