Using ThinApp to Troubleshoot Misbehaving Applications

One of my customers had a challenge with a nonpersistent VDI pool.  They were using a web app that required some specialized software in order to work.  That specialized software installs per user, when the web app is executed.  On persistent desktops, it’s not too big of a deal, since the user installs it once and is good to go.  On the nonpersistent pool, it proved to be a pain point, as it was prompting to install every day for every user.

After digging into it a bit, it turned out that the key to the install was a .cab file.  Extracting that file didn’t prove helpful, so I went another route.  If you buy VMware View, you get ThinApp along with it.  So, I ThinApped Internet Explorer and set it to WriteCopy isolation mode.  I stuck the executable onto a file share and created a ‘thinstall’ folder alongside it (so that the sandbox for that package would reside on the file share).  Once that was in place, I instructed one of the desktop administrators to execute that ThinApp and perform the software install.  He did so, giving me a fully populated sandbox to examine.

I immediately found the contents of the cab file, but it was all placed under %SystemRoot% and %programfiles%.  Neither of those are user specific, so that left me with the registry as the potential source of the per-user settings that I was trying to resolve.  After taking a bit to refresh my memory of ThinApp Registry file manipulation (wow, I formatted those early posts really poorly), I went to work.

I used vregtool to export the registry changes from the sandbox, then started looking through it.  I compared the keys from the sandbox with the keys that were on the nonpersistent desktop’s master image (where the administrator had installed that software under his account) and found a disconcertingly large number of differences under HKLM (I was expecting them to all be under HKCU).  A lot of them were easy enough for me to discard, based on their contents… but a lot of them related to either the files within the cab or to the web server that was running the web app.  Quite a few of the registry entries specified absolute paths to the administrator’s local appdata folder (for the user who installed the software).  Bingo.

So, I decided to just go ahead and recreate these registry entries on my master image, correcting paths to use variables such as %localappdata% wherever needed.  This process called for a lot of keys… and where there’s a repetitive task, there’s a use case for a script.  I’m not quite comfortable with a script running mad and making registry changes, so I wrote this one to output a whole bunch of “reg add” commands that could be put into a batch file… hopefully after an administrator has verified that there are no catastrophic syntax errors.  This script is built to take the output of vregtool and parse through it, making registry entries for whatever is contained in the file.  In this case, before parsing through the vregtool output, I opened it up in Notepad and did a quick find and replace to correct the local appdata issues that I had identified.

Once I had agnosticized the registry entries (and deleted the ones that I didn’t want to recreate, including all of the ThinApp HKLM\FS\* entries), I fed that file into this script.  The script generated the expected ‘reg add’ commands, which I ran on the master image for the nonpersistent VDI Pool.  Once those (corrected) registry entries were in place, the desktop administrator had one of his users try out the application and it ran successfully.  Even (perhaps especially?) when you’re not actually using ThinApps for the users, it’s a great troubleshooting tool!

Anyway, here is the script that I wrote to translate the ThinApp Registry differentials into Reg Add commands.  As always, use this at your own risk.  While it worked for me in my situation, that is no guarantee that it will work for you in yours.  If you improve it, please let me know and I'll happily incorporate your feedback!

#Takes a thinapp registry differential output (from 'vregtool Registry.rw.tvr PrintKeys - ShowValues -ShowData -ExpandMacros') and generates a series of "reg add" commands to create the HKLM and HKCU registry entries contained within.
param
(
   $inFile = "C:\temp\reg-everything.txt"
)
$regAdds = @()
$allReg = Get-Content $inFile
foreach ($thisLine in $allReg)
{
   #reformats the line to better match "reg add" syntax
   $thisLine = $thisLine.trim()
   $thisLine = $thisLine -replace "HKEY_LOCAL_MACHINE", "HKLM"
   $thisLine = $thisLine -replace "HKEY_CURRENT_USER", "HKCU"
   $thisLine = $thisLine -replace "^writecopy", ""
   $thisLine = $thisLine -replace "^deleted", ""
   $thisLine = $thisLine -replace "^sb_only", ""
   $thisLine = $thisLine -replace "^full", ""
   if ($thisLine.StartsWith("REG_SZ"))
   {
      $thisLine = $thisLine -replace "#00\)", ")"
   }
   $thisLine = $thisLine.trim()
   
   if (($thisLine.startswith("HKLM")) -or ($thisLine.startswith("HKCU")))
   {
      #Just specifying the key path
      $thisKey = $thisLine
   }
   elseif (($thisLine.startswith("REG")))
   {
      #Create the reg add command for the new value, correcting for "" value and data fields
      $thisCommand = ($thisLine.trim()).split(" ")
      $regType = $thisCommand[0]
      $valueStartPos = $thisLine.IndexOf("[") + 1
      $valueStrLength = $thisLine.IndexOf("]") - $valueStartPos
      $regValue = "`"$($thisLine.Substring($valueStartPos,$valueStrLength))`""
      $regValue = $regValue -replace "`"`"`"`"", "`"`""
      $dataStartPos = $thisLine.IndexOf("(") + 1
      $dataStrLength = $thisLine.LastIndexOf(")") - $dataStartPos
      $regData = "`"$($thisLine.Substring($dataStartPos,$dataStrLength))`""
      $regData = $regData -replace "`"`"`"`"", "`"`""
      $regAdds += "reg add `"$thisKey`" /v $regValue /t $regType /d $regData /f"
   }
}
$regAdds

Comments

Popular posts from this blog

PowerShell Sorting by Multiple Columns

Clone a Standard vSwitch from one ESXi Host to Another

Deleting Orphaned (AKA Zombie) VMDK Files