Take part in the OS Deployment Automation Survey

RustyGears

At Citrix Synergy in Anaheim next month, I’ll have the opportunity to present a Geek Speak Live session – Hands Off My Gold Image! If you aren’t automating the creation of your gold images, there’s lots to learn in this session. Even if you are automating your gold images, perhaps there’s something new that I can still share with you. In this session, which will be demo heavy, I’ll show you some ways that you can deliver build automation with toolsets provided by Microsoft and Citrix.

I’m big on automation, especially when it comes to gold images. If you’re building images via a manual process, I contend that you cannot deliver the quality and consistency that is provided through an automated process. PVS, MCS/linked clones etc. are not a replacement for automation either. An open and repeatable build process improves the user experience and reduces the cost of support, because Windows is no longer a black box. Instead the entire process from start to finish, can be viewed, interrogated and understood by everyone.

In my role at Kelway, I get to talk many customers about how to better deliver and manage their physical and virtual desktop environments, but it’s still surprising to me that often automation is an afterthought.

So for this talk, I wanted to provide more than just anecdotal evidence, I’d like to back up my approach with some real data. That’s where I need 60 seconds of your time to contribute to a survey. Here’s a 5 question, anonymous survey designed to gather some details on OS automation in hosted desktop environments:

This survey will be available until at least Synergy in May, where I’ll present the results during my talk - Hands Off My Gold Image!

400 App-V Recipes!

400-episodes

With thanks to Nicke’s latest post, the App-V Recipes and Tips list has hit 400 links!

If you haven’t seen this list previously, this is the place to find recipes, tips, workaround and fixes for various applications that the community has built around Microsoft App-V. A big thanks to all those community members who have contributed to this list and shared their knowledge.

If you’d like to keep up to date, as links are added, there’s an RSS feed for the list, and the list itself is searchable (here’s an example for Firefox recipes).

Here’s to the next 400.

Retrieving a VM’s UUID from vSphere

While working on a PowerShell script to drive OS deployment through MDT, I’ve needed to obtain the UUID from a target virtual machine. Unfortunately this isn’t just a property of the VM that you get through Get-VM. Instead you’ll need jump through a few hoops to retrieve the right UUID.

I’ve haven’t had to re-invent the wheel on this one, as I’ve taken some tips from this VMware Community thread and a blog post by Ken Smith. I have simplified things a little by writing a function that you can use to return the UUID as a string from a virtual machine object (gathered from Get-VM) to the function.

To use the function, first ensure that PowerCLI is installed and that you’ve connected to a host or vCenter, so that a target VM can be returned and then passed to the function.

For example, I could use the following command to retrieve the UUID from a target VM:

PS C:\> Get-VM -VM "W7VM1" | Get-vSphereVMUUID
554c0342-c2c7-c3b7-8258-96eb00f62b0c

Code listing below:

#---------------------------------------------------------------------------
# Author: Aaron Parker
# Desc:   Function that uses retrieves the UUID from a specified VM and
#         transposes it into the right format for use with MDT/SCCM etc
# Date:   Mar 24, 2013
# Site:   http://stealthpuppy.com
#
# Original code snippets from:
# http://communities.vmware.com/thread/239735
# http://www.keithsmithonline.com/2013/02/powershell-show-vmware-vm-UUID.html
#---------------------------------------------------------------------------

Function Get-vSphereVMUUID {
    <#
        .SYNOPSIS
            Retrieves the UUID from a specified VM and formats it correctly for use with MDT/SCCM etc.

        .DESCRIPTION
            Retrieves the UUID from a specified VM and formats it correctly for use with MDT/SCCM etc. Returns the UUID as a string that can be passed to other functions.

            Requires that a VM object is passed to the function. That object will first have to be created before being passed to this function.

        .PARAMETER VM
            Specifies the VM to retrieve the UUID from.

        .EXAMPLE
            PS C:\> Get-vSphereVMUUID -VM "W7VM1"

            Retrieves the UUID from a VM named W7VM1.

        .EXAMPLE
            PS C:\> $VM | Get-vSphereVMUUID

            Retrieves the UUID from a VM piped to this function.

        .NOTES
            See http://stealthpuppy.com/ for support information.

        .LINK

http://stealthpuppy.com/code/retrieving-a-vms-uuid-from-vsphere/

     #>

    [CmdletBinding(SupportsShouldProcess=$True)]
    Param(
        [Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage="Specify the VM to retrive the UUID from.")]
        [System.Object]$VM
        )

    BEGIN {
    }

    PROCESS {
        # Retrive UUID from vSphere
        $UUID = $VM | %{(Get-View $_.Id).config.UUID}

        #Transpose UUID into expected format
        # Section 1
        $UUID11 = $UUID.Substring(0,2)
        $UUID12 = $UUID.Substring(2,2)
        $UUID13 = $UUID.Substring(4,2)
        $UUID14 = $UUID.Substring(6,2)

        # Section 2
        $UUID21 = $UUID.Substring(9,2)
        $UUID22 = $UUID.Substring(11,2)

        # Section 3
        $UUID31 = $UUID.Substring(14,2)
        $UUID32 = $UUID.Substring(16,2)

        # Section 4
        $UUID41 = $UUID.Substring(19,4)

        # Section 5
        $UUID51 = $UUID.Substring(24,12)

        # Piece the strings together
        [string]$UUIDa = "$UUID14$UUID13$UUID12$UUID11"
        [string]$UUIDb = "$UUID22$UUID21"
        [string]$UUIDc = "$UUID32$UUID31"
        [string]$UUIDd = "$UUID41"
        [string]$UUIDe = "$UUID51"
        [string]$UUIDfixed = "$UUIDa-$UUIDb-$UUIDc-$UUIDd-$UUIDe"
    }

    END {
        # Return the UUID
        Return $UUIDfixed
    }
}

Sequencing Mozilla Firefox with App-V 5.x

It’s a simple task to virtualize Firefox, as it lends itself well to application virtualization; however getting it right takes a little preparation. Before embarking on sequencing Firefox, please refer to this companion article – Prepare Mozilla Firefox for Enterprise Deployment and Virtualization – which covers configuring a Firefox installation for virtualizing. It’s important that Firefox is configured correctly for virtualization by disabling specific features.

User Experience

Typically, virtualizing an application changes the user experience due to the introduction of isolation. With App-V 5 there’s no such change to the way users might interact with Firefox. Users can even set a virtualized Firefox as their default browser.

Firefox features to disable

There are a couple of features that should be disabled when running Firefox under App-V 5:

  • Automatic updates for Firefox – Options / Advanced / Update / Firefox updates. Firefox updates should be delivered via new App-V packages. Updates for Add-ons and Search Engines should be OK as these are written to the user profile
  • Mozilla Maintenance ServiceFirefox installs an updater service that allows updating whilst avoiding UAC prompts. This service should be disabled or not installed

Read the article Prepare Mozilla Firefox for Enterprise Deployment and Virtualization for full details on removing these options during installation.

Managing the Firefox profile

Firefox stores preferences, extensions and other user data in:

  • %APPDATA%\Mozilla (preferences, bookmarks etc.); and
  • %LOCALAPPDATA%\Mozilla (browser cache)

The default behaviour of the App-V Sequencer is to exclude %LOCALAPPDATA% – this is a good thing and I don’t recommend removing this exclusion. %APPDATA% will be included by default and whether you leave this location included in the package will depend on your specific deployment requirements; however my recommendation is to exclude this location by adding [{AppData}]\Mozilla to the exclusion list in your sequence. On the client, Firefox will then create a new profile in the real file system when the user starts the browser for the first time.

Virtualizing the profile increases the complexity of upgrading Firefox packages especially challenging given Mozilla’s approach to Firefox releases. By storing the Firefox profile on the real file system, Firefox can be deployed via completely unrelated packages – no need to create upgrade versions. By excluding %APPDATA% and not virtualizing the user profile you will gain some flexibility with your Firefox deployment.

Sequencing Platform

Sequence Firefox on a clean Windows 7 SP1 x86 VM with all current updates and no other applications other than the App-V Sequencer. The Firefox version available from Mozilla is an x86 application, so I generally recommend sequencing Firefox on Windows 7 x86 virtual machine even though you may be deploying to 64-bit Windows. However confirm this in your own environment and re-sequence for 64-bit platforms if required.

Sequencer Configuration

Before sequencing, add the following recommended exclusions. :

  • [{AppData}]\Mozilla
  • [{Common AppData}]\Microsoft\RAC
  • REGISTRY\USER\ [{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Internet Settings

Download the following Sequencer Template as a starting point for your Firefox sequence:

App-V 5 Sequencer Template App-V 5 Sequencer Template

Installing Firefox

Download the Firefox installer in your target language from the Mozilla site. Sequence Firefox by following these high level steps:

  • Install Firefox
  • Configure profile defaults and preferences locking
  • Optionally add global add-ons and install plug-ins such as Adobe Flash Player (assuming you want this in the same package)

Automating this process as much as possible will create a cleaner package and make it faster to re-create a new Firefox package if required.

Before sequencing, copy all of the required files into the sequencing VM, which should like something like this:

AppVFirefoxSetupFolder

For a walkthrough of the sequencing process, using the installation script outlined in the Firefox deployment article, see the following screenshots:

First Run Tasks and Primary Feature Block

If the steps above have been followed for exclusions, installation and configuration of Firefox, there will be no first run tasks to complete. Additionally the resultant package will be reasonably small so there is no need to create the Primary Feature Block. Because you don’t need to complete first run tasks or create the Primary Feature Block, you could automate the entire end-to-end process of creating a Firefox package using the App-V 5 Sequencer PowerShell module.

Automating the Firefox sequence

With the provided script, sequencing Firefox with the App-V 5 PowerShell module is very simple. Use the PowerShell script below to create a Firefox package based on the steps outlined above.

Import-Module AppvSequencera
New-Item -Path C:\Packages\MozillaFirefox19 -ItemType Directory
CD C:\Packages\Firefox19
New-AppvSequencerPackage -Name "Mozilla Firefox 19" -TemplateFilePath .\AppV5SequencerTemplate.appvt -OutputPath C:\Packages -PrimaryVirtualApplicationDirectory C:\MozillaFirefox -Installer .\InstallFirefox.cmd

Finally

Save your package and deploy. With compression enabled, the package should be around 27Mb.

App-V 5 Sequencer Template

The App-V 5 Sequencer, just like version 4.6 SP1, includes support for Sequencer Templates. These are an ideal approach for ensuring the use of the same set of Sequencer settings and exclusions across all packages.

App-V 5 captures many additional locations that weren’t captured by the version 4 Sequencer. This isn’t generally an issue for packages; however excluding unneeded data means that data isn’t streamed to clients unnecessarily. Listed below is sequencer template that includes a few additional locations that I’d recommend excluding.

In the listing below, the highlighted line is a local folder into which all application installations are executed from (i.e. setup has been copied locally to the sequencing VM). This ensures that any files created by the application setup are not captured during installation.

Attached here is a downloadable copy of the template listing:

App-V 5 Sequencer Template App-V 5 Sequencer Template

<?xml version="1.0" encoding="utf-8"?>
<SequencerTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <AllowMU>true</AllowMU>
  <AppendPackageVersionToFilename>true</AppendPackageVersionToFilename>
  <AllowLocalInteractionToCom>false</AllowLocalInteractionToCom>
  <AllowLocalInteractionToObject>false</AllowLocalInteractionToObject>
  <FileExclusions>
    <string>[{Profile}]\NTUSER.DAT</string>
    <string>[{Local AppData}]Low</string>
    <string>[{AppVPackageDrive}]\Packages</string>
    <string>[{CryptoKeys}]</string>
    <string>[{Common AppData}]\Microsoft\Crypto</string>
    <string>[{Common AppData}]\Microsoft\Search\Data</string>
    <string>[{Cookies}]</string>
    <string>[{History}]</string>
    <string>[{Cache}]</string>
    <string>[{Local AppData}]</string>
    <string>[{LocalAppDataLow}]</string>
    <string>[{Personal}]</string>
    <string>[{Profile}]\Local Settings</string>
    <string>[{Profile}]\NTUSER.DAT.LOG1</string>
    <string>[{Profile}]\NTUSER.DAT.LOG2</string>
    <string>[{Recent}]</string>
    <string>[{Windows}]\Debug</string>
    <string>[{Windows}]\Logs\CBS</string>
    <string>[{Windows}]\Temp</string>
    <string>[{Windows}]\WinSxS\ManifestCache</string>
    <string>[{Windows}]\WindowsUpdate.log</string>
    <string>[{AppVPackageDrive}]\$Recycle.Bin</string>
    <string>[{AppVPackageDrive}]\System Volume Information</string>
    <string>[{AppData}]\Microsoft\AppV</string>
    <string>[{Local AppData}]\Temp</string>
    <string>[{ProgramFilesX86}]\Microsoft Application Virtualization\Sequencer</string>
    <string>[{AppVPackageDrive}]\Boot</string>
    <string>[{Windows}]\ServiceProfiles</string>
    <string>[{Windows}]\AppCompat</string>
    <string>[{Windows}]\Logs</string>
    <string>[{SystemX86}]\wbem</string>
    <string>[{SystemX86}]\config</string>
    <string>[{SystemX86}]\SMI</string>
  </FileExclusions>
  <RegExclusions>
    <string>REGISTRY\MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography</string>
    <string>REGISTRY\MACHINE\SOFTWARE\Microsoft\Cryptography</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Internet Settings</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Explorer\StreamMRU</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\StreamMRU</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\Windows\CurrentVersion\Explorer\Streams</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\Streams</string>
    <string>REGISTRY\MACHINE\SOFTWARE\Microsoft\AppV</string>
    <string>REGISTRY\MACHINE\SOFTWARE\Wow6432Node\Microsoft\AppV</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Microsoft\AppV</string>
    <string>REGISTRY\USER\[{AppVCurrentUserSID}]\Software\Wow6432Node\Microsoft\AppV</string>
  </RegExclusions>
  <TargetOSes />
</SequencerTemplate>