Automatic Sequencing of App-V Applications with VMware ESX

This text describes how Microsoft App-V can be used to do a fully automated conversion of an entire collection of MSI packages to App-V packages.

The prerequisite for this is, alongside a functioning virtual sequencer, a VMware ESXi environment with vSphere and PowerCLI:

This example can easily be adapted for Hyper-V.

Microsoft offers the possibility to automate packet creation with Windows PowerShell on the sequencer. The use of this module is simple. However must ensure the sequencer is installed on the environment according to the best practice for the selected environment. As a rule the automated packaging will be controlled from the outside, so use a sequencer in a Hyper-V or VMware environment and reset it automatically before each use.

Import the sequencer PowerShell extension:

Import-Module AppvSequencer

With the command Expand-AppvSequencerPackage it is possible to expand an App-V package via a PowerShell command. This functions like an installation. Think of it as an automatic process that opens packages, exchanges a file and then packages again with the sequencer.

Expand-AppvSequencerPackage [-AppvPackagePath]  07.[ ]

 The command NewAppvSequencerPackage is the PowerShell call to create a new sequence. The actual package can be installed via a script for example. As a further parameter it is possible to designate a PVAD and also a template that automatically exclude directories from the sequencing. A package accelerator is however atypical.

New-AppvSequencerPackage [-Name]  [-Path]  [-Installer]  [[-PrimaryVirtualApplicationDirectory]  ] [-FullLoad] [-TemplateFilePath  ] [ ]

Parameter Set: ByPackageAcceleratorInstalledFilesParameter Set: ByPackageAcceleratorInstallMedia

New-AppvSequencerPackage [-Name]  [-Path]  [-AcceleratorFilePath]  [-InstallMediaPath]  [ ]

 The package creation proceeds thus:

New-AppvSequencerPackage -Name "MeinPaket" -TemplateFilePath "C:\MeinTemplate.appvt" -OutputPath "C:\MeinePakete" -Installer "C:\Installers\MyApp\setup.exe"

The instruction Update-AppvSequencerPackage is intended to apply a script or hotfix automatically to a previously installed package. Its entry is the source package and for -Installer enter a setup or script.

Update-AppvSequencerPackage [-InputPackagePath]  [-Name]  [-Path]  [-Installer]  [-FullLoad] [ ]

Automatic packaging with PowerShell in practice

To be able to package automatically one must first solve several problems. For one it's usually a complex process that is to be carried out on the intended system, for another the process should run as cleanly and as disruption-free as possible. In this chapter you will see how it is possible to repackage MSI packages into App-V packages. The disadvantage of doing so is that there is unfortunately almost no possible way to configure the packages. MSI packages can as a rule be installed silently with a “/q” parameter. Additionally the parameter “/norestart” suggests itself in order not to interrupt the sequencing process. The following picture shows the general process.
The nice thing about this solution is that it can be expanded upon as desired. It's possible to make the application start automatically in order to get a Feature-Block 1. There are businesses that offer more convenient solutions for automatic packaging, but the procedure is costly per package. The process discussed here costs nothing beyond the procurement cost, which is comparable to the price of buying a book. The automation assumes you have a VMware environment. To modify it for Hyper-V should however not be a problem.


Figure 1: Process for automatic packaging with Microsoft App-V

The basis is the VMware PowerCLI. As of the time the article was written, the current version can be found here:

The following procedures with Hyper-V can be similarly depicted. An example would be for automating the AppBot Citrix application in order to convert streaming packages to App-V. In illustrating this process, the errors that can occur will not be discussed. So use this only in a test environment.

Process for packaging with a VMware VirtualCenter:

1.    Login procedure to VirtualCenter via a Secure String. This can be saved completely on the hard drive.  Before you do you must however import the necessary components of VMware PowerCLI.


Add-PSSnapin VMware.VimAutomation.Core
Import-Module VMware.VimAutomation.Vds

$RootDirectory = $PSScriptRoot.ToString()

#Secure key for encription

[byte[]] $key = (1,2,3,4,5,6,7,8,9,1,2,3,4,5,1,1)

$vcenterUser = "administrator @ vsphere.local"
$vcenterServer = “MYVCENTERSERVER” #Or IP address$vc.

if(-not (test-Path $($RootDirectory + "\vcenterpass.txt") )){
    $SecurePass = read-host -AsSecureString "Password for VMware vSphere:" | ConvertFrom-SecureString -Key $key | Out-file $($RootDirectory+"\vcenterpass.txt")

$SecurePass = Get-Content ($RootDirectory + "\vcenterpass.txt") | ConvertTo-SecureString  -Key $key
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $vcenterUser, $SecurePass 

2.    Login to VMware VirtualCenter Server.

#Connect VCenter
$vc = Connect-VIServer -Server $vcenterServer -Credential $credentials -Verbose

3.    We want PowerShell Remoting to use for the sequencer and for the transfer of packages. PowerShell Remoting is an interface that allows the execution of commands on another computer. PowerShell Remoting functions after activating it in a domain with this command:

Enable-PSRemoting -Force

If the client, for example the sequencer, is not located in a domain, and this is not uncommon, then the controlling system must be enabled to use PowerShell Remoting on the remote stations (the sequencer). Thus we don't enable it on the device to be controlled which other systems are allowed to access, but rather we enable it on the device which will control the process.
For the following instructions it is possible to enter a comma-separated list with IP addresses and names. The asterisk is the wild card for all systems.

Set-Item wsman:\localhost\client\trustedhosts * -it

The connection can then be tested with the command Test-WsMan . A remote command can look like the following:

Invoke-Command -ComputerName COMPUTERNAME -ScriptBlock { MeinBefehl } -credential $credentials

4.    The login information for the sequencer is fed in over a Secure String just like the information for the VirtualCenter and can likewise be stored on the hard drive. The user must have administrative rights for the sequencer.

#Connection settings Sequencer
$vmuser='administrator' # Admin user on the virtuellen maschine use domain\administrator for a domain member
$sequencer = “seq2012r2en” #DNS name or IP address

if(-not (test-Path $($RootDirectory + "\vmpwasswordfile.txt") )){
   read-host -AsSecureString "Please enter the Password for the sequencer:" | ConvertFrom-SecureString -Key $key | Out-file $($RootDirectory + "\vmpwasswordfile.txt")

5.    Let us assume that all the MSI files to be packaged are found in a directory with this script. In this example, in “MSI-Files”. These MSI files can basically be packaged directly with PowerShell Remoting and the command New-AppvSequencerPackage. However, one may want to perform more complicated tasks. Therefore the actual packaging should be performed with a CMD file. In this file more complex processes can be performed.
6.    We must find all the MSI files in the directory and let them be packaged by the sequencer automatically. In preparation we take a sequencer without domain integration. A snapshot of the ongoing operation must be created for the sequencer. The snapshot in this example receives the name “NeutralOn”. The call to the sequencer via PowerShell Remoting causes problems. Unfortunately the PS-Remote call doesn't always function. These problems can be solved by using the command PSExec from the Sysinternals. Now the loop.

7.    At this point a loop browses the directory of MSI files, which must be located in the same folder as this script.

foreach ($msifile in Get-ChildItem "$RootDirectory\MSI-Files"){
  Write-Host $("Create appv file from the MSI " + $ `
       -ForegroundColor Yellow 

8.    Prior to the creation of every package one must set the snapshot to a neutral state. We will continue to wait on the VMware tools (they must be installed on the sequencer). Thus we can recognize whether the sequencer was completely reset.

  #reset Snapshot
  $vm=Get-vm -Server $vcenterServer -Name $sequencer
  Write-host "Set snapshot $SnapshotName on $sequencer"
  Set-VM -VM $vm -Snapshot $SnapshotName -Confirm:$false  | Wait-Tools

9.    The MSI must be copied onto the sequencer.
Figure 2: MSI packages in the package directory

#Copy MSI
Copy-Item  $msifile.FullName -destination `
$('\\' + $sequencer +'\c$\')

10.    The sequencing should actually run through PowerShell Remoting. Here though the process is divided into two parts. The one PowerShell Remoting function takes care of the preparations. The function prepares everything in order for the actual sequencing to start. In $appvname a name for the sequence is generated that is composed of alphanumeric symbols.

#Create sequence name
$appvname = $(($'.msi',''))
$appvname = $appvname -replace "[^a-zA-Z]",""
#Start Sequencing
Invoke-Command -ComputerName $sequencer -Authentication Default `
-Credential $vmcredentials -ScriptBlock {
  param([String] $MSIName,
  [String] $appvName

 11.    Under c:\Sequence.cmd a batch file is created that contains the actual task of creating the packages.

#Create Installation batch
"msiexec /q /norestart /i c:\$MSIName" | Set-Content -Encoding Ascii -Force C:\sequence.cmd

'timeout 3'  | Add-Content -Encoding Ascii c:\sequence.cmd

12.    A directory for issuing the packages on the server.

new-item "c:\sequence\" -Force -ItemType directory | out-null

 13.    Now a PowerShell script is created which carries out the actual sequencing. With sufficient rights it's possible at this point to start the sequencing command directly as well.

"Import-Module Appvsequencer" | Set-Content -Encoding Ascii -Force `

"New-AppvSequencerPackage -Installer c:\sequence.cmd -Name $appvName -OutputPath c:\sequence\  -ErrorAction SilentlyContinue" | Add-Content -Encoding Ascii C:\CreateSequence.ps1

#Create Sequence
  #New-AppvSequencerPackage -Installer c:\sequence.cmd  -Name $appvname -OutputPath "c:\sequence\"  -ErrorAction SilentlyContinue

 14.    The Invoke command can be closed. As an argument provide the name of the MSI and the name of the App-V package.

  } -ArgumentList $, $appvname

 15.    In this case, the Sysinternals tool PSExec should take over the call for the remote packaging:

An advantage of PSExec is that the rights for the sequencing don't play a role anymore. A disadvantage is the complexity of using the tool. Among other things, the sequencer password needs to be changed again to plain text. PSExec should be placed in the root directory of the script. It is also possible with PSExec to start a GUI through an auto-login. For some processes  it is mandatory to do so.

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR`
$ClearPassword =  [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

 16.    The actual process begins by defining the command line.

$Command = 'powershell.exe -ExecutionPolicy remotesigned -NonInteractive -Command  "& C:\CreateSequence.ps1 "' -f $appvname   
Write-Host "This will take longer. At least three minutes to sequence $appvname" -ForegroundColor Yellow
& $($RootDirectory + "\psexec.exe") \\$sequencer -accepteula "-u" $vmuser "-p" $ClearPassword CMD /C "$Command || EXIT /B 1" 2> $psExecErrorOutput


17.    To conclude the result can be copied to the controller system and the execution loop can be closed. 

#Copy the result back to the controler
  Write-Host "Copy Results"
  if(-not (Test-path $($RootDirectory + "\Output_AppV"))) {new-item $($RootDirectory + "\Output_AppV") -ItemType directory}
  copy $('\\' + $sequencer +'\c$\sequence\') -Destination  $($RootDirectory + "\Output_AppV\") -Recurse -Force

Write-Host "Finished packaging"
Disconnect-VIServer -Server $vc -Confirm:$false

18.    The packages are in the Output_AppV directory after the creation process.

19.    There the packages can be tested immediately with a short PowerShell command.

Get-ChildItem E:\Output_AppV\*.appv  -Recurse | Add-AppvClientPackage  | Publish-AppvClientPackage

 In any case, one needs to observe what works in the end. Because the converted packages are already configured, it is not always possible to say how they will function once they are converted.