Connection Groups (or Dynamic Suite Composition v2) in App-V 5.0 are great for enabling separate App-V packages to talk to each other. Connection Groups are easy enough to deploy with the App-V Management Server or Configuration Manager 2012; however that isn’t the case for stand-alone scenarios or 3rd party ESDs.

Adding a Connection Group to the client, first requires creating a definition file in XML. Without the App-V Management Server or ConfigMgr (where the resulting file ends up on the client), you’ll need to do that manually. Crafting XML files from scratch using Notepad isn’t my idea of fun.

What’s in a Definition File?

A Connection Group definition file contains the details about the Connection Group and the member packages. Each Connection Group has it’s own group and version ID (GUIDs).

A typical definition file will look something like this:

[code language=”xml”]

[/code]

To create the file, we need to generate GUIDs for the group and version IDs, supply a Connection Group display name and priority, and then add the package and version IDs for each member package.

Enter PowerShell

To simplify the process of creating the definition file for a Connection Group, I’ve written a PowerShell function that will handle the heavy lifting for you. New-AppvConnectionGroupFile will create the definition file from a list of App-V packages passed to it.

The function will output the definition file to a specified path and then return that file as an object that you can do further processing with.

[code language=”ps”]#—————————————————————————
# Author: Aaron Parker
# Desc: Function that uses the App-V 5.0 client to create Connection
# Group description (XML) files for use with stand alone clients or
# test scenarios
# Date: Jan 06, 2013
# Site: http://stealthpuppy.com
#—————————————————————————

Function New-AppvConnectionGroupFile {
<#
.SYNOPSIS
Creates an App-V 5.0 Connection Group definition file.

.DESCRIPTION
Creates an XML-based Connection Group definition file from packages added to the current system.

Packages can be filtered before being passed to the function to control which packages are included in the Connection Group.

.PARAMETER DisplayName
Specifies the display name of the Connection Group.

.PARAMETER Priority
Specifies the priority of the Connection Group.

.PARAMETER Path
Specifies the App-V connection group definition file to output.

.PARAMETER Packages
The packages to include in the Connection Group.

.EXAMPLE
PS C:> New-AppvConnectionGroupFile -DisplayName “Internet Explorer Plugins” -Priority 0 -FilePath InternetExplorerPlugins.xml -Packages $Packages

Creates a Connection Group file named ‘InternetExplorerPlugins.xml’ with a display name of ‘Internet Explorer Plugins’ from packages contained within the array $Packages.

.EXAMPLE
PS C:> Get-AppvClientPackage -Name Adobe* | New-AppvConnectionGroupFile -DisplayName “Adobe Apps” -Priority 10 -FilePath AdobeApps.xml

Creates a Connection Group file named ‘AdobeApps.xml’ with a display name of ‘Adobe Apps’ from packages passed via the pipeline from Get-AppvClientPackage.

.NOTES
See / for support information.

.LINK
/code/creating-app-v-5-0-connection-groups-with-powershell/
#>

[CmdletBinding(SupportsShouldProcess=$True)]
Param(
[Parameter(Mandatory=$True, HelpMessage=”Connection Group descriptor XML file path”)]
[string]$Path,
[Parameter(Mandatory=$True, HelpMessage=”Display name of the Connection Group”)]
[string]$DisplayName,
[Parameter(Mandatory=$False, HelpMessage=”Connection Group priority”)]
[int]$Priority,
[Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage=”Packages to include in the Connection Group”)]
[System.Array]$Packages
)

BEGIN {

# Template XML for an App-V Connection Group description file. Easier than building from an XML object
$templateXML = @’

’@

# Write out the template XML to a file in the current directory
$templateXMLFile = $pwd.Path + “\ConnectionGroupTemplate.XML”
$templateXML | Out-File -FilePath $templateXMLFile -Encoding utf8 -Force

# Create a new XML object and read the template XML file into this object
$xml = New-Object XML
If ((Test-Path $templateXMLFile) -eq $True ) { $xml.Load($templateXMLFile) } Else { Write-Warning -Message “Unable to read template XML file.” }

# Apply the display name and GUIDs to the XML object
$xml.AppConnectionGroup.DisplayName = $DisplayName
$xml.AppConnectionGroup.AppConnectionGroupId = ([guid]::NewGuid()).ToString()
$xml.AppConnectionGroup.VersionId = ([guid]::NewGuid()).ToString()
$xml.AppConnectionGroup.Priority = $Priority.ToString()

# Clone the existing package entry to use for new entries
$newPackage = (@($xml.AppConnectionGroup.Packages.Package)[0]).Clone()
}

# Process each supplied App-V package into the XML object
PROCESS {
ForEach ( $Package in $Packages ) {
Write-Progress “Adding packages”

$newPackage = $newPackage.Clone()
$newPackage.DisplayName = $Package.Name
$newPackage.PackageId = ($Package.PackageId).ToString()
$newPackage.VersionId = ($Package.VersionId).ToString()

# Output appending the child XML entry to null to prevent displaying on screen
$xml.AppConnectionGroup.Packages.AppendChild($newPackage) > $null
}
}

END {

# Remove the template package entry from the XML
$xml.AppConnectionGroup.Packages.ChildNodes | Where-Object { $_.DisplayName -eq “Package1” } | ForEach-Object { [void]$xml.AppConnectionGroup.Packages.RemoveChild($_) }

# Save the completed XML to disk
$xml.Save($Path)

# Delete the template XML file from disk
If (Test-Path $templateXMLFile) { Remove-Item $templateXMLFile -Force -ErrorAction SilentlyContinue }

# Return the new Connection Group description XML file so that it might be processed by other functions
If (Test-Path $Path ) { Return Get-Item $Path } Else { Write-Warning “Failed to save Connection Group definition file.” }
}
}[/code]

Copy and paste the code above into a PowerShell window (or the ISE) to enable the function. You could also save code to a PowerShell module to make it more accessible.

Examples

The function includes help and examples, so that you can view them from within PowerShell (the PowerShell ISE makes that simple). Use the Get-Help cmdlet to view details.

Using the function requires supplying a Display Name and Priority for the Connection Group as well as the list of App-V packages to include in the group. To supply the packages, first ensure they have been added to the local client, so that they can be queried with Get-AppvClientPackage.

In this example, I’ve added the list of packages to the variable $Packages and then supplied that to the New-AppvConnectionGroupFile function. This results in the definition file AdobeApps.xml with any Adobe package included in it.

[code language=”ps”]$Packages = Get-AppvClientPackage -Name Adobe*
New-AppvConnectionGroupFile -Path C:\Packages\AdobeApps.xml -DisplayName “Adobe Apps” -Priority 2 -Packages $Packages[/code]

Taking this a step further, I can use a single line of PowerShell to query for a filtered list of packages on the local client, passing that to my function that will create the definition file. The Connection Group is then immediately added to the client and enabled.

[code language=”ps”]Get-AppvClientPackage -Name Adobe* New-AppvConnectionGroupFile -Path C:\Packages\AdobeApps.xml -DisplayName “Adobe Apps” -Priority 2 Add-AppvClientConnectionGroup Enable-AppvClientConnectionGroup -Global[/code]

Finally

This is version 1 of this function, so corrections and feedback are welcome. As always use at your own risk.