P01 Error during creating connection groupThe operation failed because the settings for the packages in the connection group are not identical

 AppV 5.0 connection groups are causing a lot of issues. Sometimes you can add them, but not enable them. You receive an error message similar to this one.

 If you dig in the documentation you see that the COM objects need to be the same across all the applications that are a part of the connection group. You will have to check each deployment file and check it. If the connection group contains a lot of applications that is a hassle. So it is easier to have an overview of all the published applications on a computer. Then you see quickly which application needs to be modified.

Therefore, I created a PowerShell script that runs that inventory for you. You will get an overview of the following objects, including the package name, write mode, objects enabled, fonts enabled, COM Mode, In Process Enabled, Out of Process enabled and the connection group(s) where the application belongs to.

The details can be exported to a CSV file or HTML page.

While creating this PowerShell script I had some challenges.

Config files

I read the AppXManifest.xml file but not all the information was present. So I had to make sure that the information that was a part of the deployment XML file was included in this overview as well. On https://docs.microsoft.com/en-us/microsoft-desktop-optimization-pack/appv-v5/application-publishing-and-client-interaction51 I found that the various XML files are applied in this order:

  • AppXManifest.XML file
  • Manifest.xml and DeploymentConfiguration.xml (only if published globally)
  • UserManifest.xml and DynamicConfiguration.xml (depends on the boolean published globally).

But the question remains: where are these files stored?

The short answer is in the GetDynamicDeploymentConfigurationPath and GetDynamicUserConfigurationPath method of Get-AppVClientPackage.

And now in more detail. If you type the following...

Get-AppVClientPackage | Get-Member

... then you will get the following output:

   TypeName: Microsoft.AppV.AppvClientPowerShell.AppvClientPackage

Name                                  MemberType Definition
----                                  ---------- ----------
Add                                   Method     void Add(string path, string policy)
CancelMount                           Method     void CancelMount()
Equals                                Method     bool Equals(System.Object obj)
GetApplications                       Method     Microsoft.AppV.AppvClientPowerShell.AppvClientApplication[] GetAppl...
GetDynamicDeploymentConfigurationPath Method     string GetDynamicDeploymentConfigurationPath()
GetDynamicUserConfigurationPath       Method     string GetDynamicUserConfigurationPath(bool global)
GetHashCode                           Method     int GetHashCode()
GetType                               Method     type GetType()
Mount                                 Method     void Mount()
Publish                               Method     void Publish(Microsoft.AppV.AppvClientFacade.PublishScope scope, st...
Remove                                Method     void Remove(bool safeRemove)
Repair                                Method     void Repair(Microsoft.AppV.AppvClientFacade.PublishScope scope, boo...
Set                                   Method     void Set(string path, string policy)
Stop                                  Method     void Stop(bool global)
ToString                              Method     string ToString()
Unpublish                             Method     void Unpublish(Microsoft.AppV.AppvClientFacade.PublishScope scope, ...
GlobalPending                         Property   bool GlobalPending {get;}
HasAssetIntelligence                  Property   bool HasAssetIntelligence {get;}
InUse                                 Property   bool InUse {get;}
InUseByCurrentUser                    Property   bool InUseByCurrentUser {get;}
IsLoading                             Property   bool IsLoading {get;}
IsPublishedGlobally                   Property   bool IsPublishedGlobally {get;}
IsPublishedToUser                     Property   bool IsPublishedToUser {get;}
Name                                  Property   string Name {get;}
PackageId                             Property   guid PackageId {get;}
PackageSize                           Property   uint64 PackageSize {get;}
Path                                  Property   string Path {get;}
PercentLoaded                         Property   uint16 PercentLoaded {get;}
UserPending                           Property   bool UserPending {get;}
Version                               Property   string Version {get;}
VersionId                             Property   guid VersionId {get;}

You can retrieve the information as follows: 

(Get-AppVClientPackage -Name "AppV Package Name").GetDynamicDeploymentConfigurationPath()

If there is a result, then you can use that result. It is an XML file and you can read it with the Get-Content command.

The second one is a little bit more complicated.

(Get-AppvClientPackage -Name "AppV Package Name").GetDynamicUserConfigurationPath((Get-AppVClientPackage -Name "AppV Package Name").IsPublishedGlobally)


And read the content with the Get-Content as well.

Applications as a part of a connection group

The second challenge was about the packages that are a part of a connection group.

If you enter:

Get-AppVClientConnectionGroup | Get-Member

Then you will get the following output:

   TypeName: Microsoft.AppV.AppvClientPowerShell.AppvClientConnectionGroup

Name               MemberType Definition
----               ---------- ----------
Add                Method     void Add(string path)
Disable            Method     void Disable(Microsoft.AppV.AppvClientFacade.PublishScope scope, string userSID)
Enable             Method     void Enable(Microsoft.AppV.AppvClientFacade.PublishScope scope, string userSID)
Equals             Method     bool Equals(System.Object obj)
GetHashCode        Method     int GetHashCode()
GetPackages        Method     Microsoft.AppV.AppvClientPowerShell.AppvClientPackage[] GetPackages()
GetType            Method     type GetType()
Mount              Method     void Mount()
Remove             Method     void Remove()
Repair             Method     void Repair(Microsoft.AppV.AppvClientFacade.PublishScope scope, bool deleteUserState, ...
Stop               Method     void Stop(bool global)
ToString           Method     string ToString()
GlobalPending      Property   bool GlobalPending {get;}
GroupId            Property   guid GroupId {get;}
InUse              Property   bool InUse {get;}
InUseByCurrentUser Property   bool InUseByCurrentUser {get;}
IsEnabledGlobally  Property   bool IsEnabledGlobally {get;}
IsEnabledToUser    Property   bool IsEnabledToUser {get;}
Name               Property   string Name {get;}
PercentLoaded      Property   uint16 PercentLoaded {get;}
Priority           Property   uint32 Priority {get;}
UserPending        Property   bool UserPending {get;}
VersionId          Property   guid VersionId {get;}

Note: This only works if there are connection groups enabled.

The most important one is GetPackages. You will get an overview of all the packages that are a part of the connection group.

(Get-AppVClientConncectionGroup -Name "Some Name").GetPackages()

With that knowledge, it was easy for me to create the script.

The script has one requirement: a screen resolution of at least 1400 x 800 pixels. If this requirement is not met, the application will fall back in silent mode.

If you want to know all the command line options please run: 

Get-Help ".\InformationAboutLoadedAppVPackages_v03.ps1" -Detailed

The output:

NAME
    C:\AppV5\InformationAboutPublishedAppVPackages_v03.ps1
    
SYNOPSIS
    Displays information about published AppV packages in a grid.
    
    
SYNTAX
    C:\AppV5\InformationAboutPublishedAppVPackages_v03.ps1 [-Silent] [-LogPath <String>] [-DetailedLogging] 
    [-SaveAsHTMLPage] [-SaveAsCSVFile] [-Summary] [-Delimiter <String>] [<CommonParameters>]
    
    
DESCRIPTION
    It gives detailed information about loaded AppV packages that are published on a system in a grid.
    

PARAMETERS
    -Silent [<SwitchParameter>]
        
    -LogPath <String>
        
    -DetailedLogging [<SwitchParameter>]
        
    -SaveAsHTMLPage [<SwitchParameter>]
        
    -SaveAsCSVFile [<SwitchParameter>]
        
    -Summary [<SwitchParameter>]
        
    -Delimiter <String>
        
    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see 
        about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216). 
    
    -------------------------- EXAMPLE 1 --------------------------
    
    PS C:\>Start the application with a GUI.
    
    ."InformationAboutPublishedAppVPackages_v03.ps1"
    
    
    
    
    -------------------------- EXAMPLE 2 --------------------------
    
    PS C:\>Start the application with a GUI and detailed logging to c:\tmp
    
    ."InformationAboutPublishedAppVPackages_v03.ps1" -DetailedLogging -LogPath c:\tmp
    
    
    
    
    -------------------------- EXAMPLE 3 --------------------------
    
    PS C:\>Start the application with a GUI and verbose output
    
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Verbose
    
    
    
    
    -------------------------- EXAMPLE 4 --------------------------
    
    PS C:\>Start the application with silent and export the result to a CSV file.
    
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Silent -SaveAsCSVFile
    
    
    
    
    -------------------------- EXAMPLE 5 --------------------------
    
    PS C:\>Start the application with silent and export the result to a CSV file and use a comma as de delimiter
    
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Silent -SaveAsCSVFile -Delimiter ","
    
    
    
    
    -------------------------- EXAMPLE 6 --------------------------
    
    PS C:\>Start the application but only the following columns are shown:
    
    - Display Name
     - Package and version ID
     - Package Version
     - Published globally
     - Published to user
     - COM Mode
     - InProcess Enabled
     - Out of Process Enabled
     - Objects Enabled
     - Connection group
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Summary
    
    
    
    
REMARKS
    To see the examples, type: "get-help C:\AppV5\InformationAboutPublishedAppVPackages_v03.ps1 -examples".
    For more information, type: "get-help C:\AppV5\InformationAboutPublishedAppVPackages_v03.ps1 -detailed".
    For technical information, type: "get-help C:\AppV5\InformationAboutPublishedAppVPackages_v03.ps1 -full".

More background information:

P01 Error during creating connection group

PowerShell error message stating that the connection group could not be created as there is a mismatch with the virtual COM settings.

P02 Overview before creating the connection group

Check the COM Mode settings from the marked applications (with the summary parameter).

P03 Overview after creating the connection group

And now with the corrected deployment XML files used (with the summary parameter).

P05 Connection group information

Now, with detailed connection group information (with the summary parameter).

P06 HTML Overview of the applications and connection groups

And you can create an HTML overview (with the summary parameter). 

If you do not include the summary parameter, then you will get this overview:

(I played with the Edge Chromium 'zoom'-function to get all the columns in the overview)

Then you have a clear overview of the used XML files.  

The application failed to launch

If the connection group has been created successfully, you can get an error 'The application failed to launch.', followed by an error code while starting an application that is a part of the connection group. 

And the 2 characters before the hyphen sign in the error code are the key factor to the solution.

In this case, the 2 characters before the hyphen sign are 0A. In the table below you can find that the Virtual Subsystem is causing issues:

Hex Code Category Hex Code Category
01 Integration 0B Subsystem Controller
02 Orchestration 0C Streaming Manager
03 Client Service 0D ISV API
04 Virtualization Manager 0E Client Host
05 Shared Component 0F Client Configuration
06 Catalog 10 Scripting
07 Publishing 11 Client User Interface
08 Client Common 12 Sequencer
09 Policy 13 Reporting
0A Virtualization Subsystem 14 Manifest

You also see that in the Event Viewer:

Luckily, you can disable the virtual objects globally. How to do that is explained in this article Hidden App-V Registry Keys.

In this example the Virtual Objects subsystem has been disabled globally via the registry:

The globally disabled subsystems are also shown in the overview. The column that subsystem has been disabled globally has a grey background colour. You can disable more items if you like. But you will have to verify that all the applications are still working properly.

With the virtual objects globally disabled (with the summary parameter) (1/2)

With the virtual objects globally disabled (with the summary parameter) (2/2)

And now the script:

<#
.SYNOPSIS
    Displays information about published AppV packages in a grid.

.DESCRIPTION
    It gives detailed information about loaded AppV packages that are published on a system in a grid. 

.EXAMPLE
    Start the application with a GUI.
    ."InformationAboutPublishedAppVPackages_v03.ps1"

.EXAMPLE
    Start the application with a GUI and detailed logging to c:\tmp
    ."InformationAboutPublishedAppVPackages_v03.ps1" -DetailedLogging -LogPath c:\tmp

.EXAMPLE
    Start the application with a GUI and verbose output
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Verbose

.EXAMPLE
    Start the application with silent and export the result to a CSV file.
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Silent -SaveAsCSVFile

.EXAMPLE
    Start the application with silent and export the result to a CSV file and use a comma as de delimiter
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Silent -SaveAsCSVFile -Delimiter ","

.EXAMPLE
    Start the application but only the following columns are shown:
     - Display Name
     - Package and version ID
     - Package Version
     - Published globally
     - Published to user
     - COM Mode
     - InProcess Enabled
     - Out of Process Enabled
     - Objects Enabled
     - Connection group
    ."InformationAboutPublishedAppVPackages_v03.ps1" -Summary


.NOTES
    Author:  Willem-Jan Vroom
    Website: https://www.vroom.cc/
    Twitter: @TheStingPilot

v0.1:
   * Initial version.

v0.2:
   * Added:
      - Shortcuts             -> enabled (true or false)
      - FileTypeAssociations  -> enabled (true or false)
      - Registry              -> enabled (true or false)
      - FileSystem            -> enabled (true or false)
      - EnvironmentVariables  -> enabled (true or false)
      - Services              -> enabled (true or false)
      - DeploymentConfigFiles that are used.
   * Added the parameter:
      - Summary

   * Some coding improvements.
   * The inventory is run immediately after starting the GUI.

v0.3:
   * Added: an overview of the globally disabled items:
      - Integration
      - Virtual Fonts
      - Just-in-timeVirtualization
      - Virtual Registry
      - Virtual Filesystem
      - Virtual COM
      - Virtual Objects
      - Virtual Environment
      - Registry Staging
      - Virtual Services
      - Virtual Shell
   * Shortcuts instead of applications in the shortcut-column

#>

[CmdletBinding(DefaultParameterSetName = 'Default')]

Param
  (
   [Parameter(HelpMessage='Perform all the actions silently.')]
   [Parameter(Mandatory=$False,  ParameterSetName='Default')]
   [Switch]   $Silent,

   [Parameter(HelpMessage='Specify the log directory.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String]   $LogPath = "",

   [Parameter(HelpMessage='Enable detailed logging to a log file.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $DetailedLogging,

   [Parameter(HelpMessage='Save as an HTML file.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $SaveAsHTMLPage,

   [Parameter(HelpMessage='Save as an CSV file.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $SaveAsCSVFile,

   [Parameter(HelpMessage='Only show a limit set of columns in the HTML page or CSV file.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $Summary,

   [Parameter(HelpMessage='Specify the delimiter character. Default = ;')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String]   $Delimiter = ";"
  )

# =============================================================================================================================================
# Function block
# =============================================================================================================================================

  Function Write-CSVFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       06-September-2018 Modified on 27-April-2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Write-CSVFile
    =============================================================================================================================================
    .SYNOPSIS

    This function writes the content of a table to a CSV file.

    #>

    param
     (
      [String]   $CSVFileWithResults,
      [String]   $DelimChar            = ";"

     )

    If($Global:gblarrTable.Count -gt 0)
     {      
      $Global:gblarrTable  |  Export-Csv $CSVFileWithResults -NoTypeInformation -Delimiter $DelimChar
      Add-EntryToLogFile -Entry ">> Write-CSVFile: The file '$CSVFileWithResults' has been written."
      Write-Host "The file '$CSVFileWithResults' has been created."
     } 
      else
     {
      $ErrorMessage = "Something went wrong while writing the logfile '$CSVFileWithResults'. Maybe nothing to report..."
      Add-EntryToLogFile -Entry "[Error]: $ErrorMessage"
      Write-Error $ErrorMessage -Category CloseError 
     } 
   }

  Function Add-EntryToLogFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       17-May-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Add-EntryToLogFile
    =============================================================================================================================================
    .SYNOPSIS

    This function adds a line to a log file

    #>

    Param
     (
      [string] $Entry
     )
      
     Write-Verbose $Entry
     if($Global:gblDetailedLogging -and $Global:gblLogFile)
      {
       $Timestamp = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
       Add-Content $Global:gblLogFile -Value $($Timestamp + " " + $Entry) -Force -ErrorAction SilentlyContinue
      }
   }

  Function Create-Folder
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       03-August-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Create-Folder
    =============================================================================================================================================
    .SYNOPSIS

    This function creates the given folder.
    The function returns two results:
     1. A message.
     2. True or false (success or failure)

    #>
    
    param
     (
      [String] $FolderName
     )

   $bolResult     = $True
   $ResultMessage = ""

   if(-not(Test-Path $('FileSystem::' + $FolderName)))
    {
     New-Item -Path $FolderName -ItemType Directory | Out-Null
     Sleep 1
     if(test-path $('FileSystem::' + $FolderName))
      {
       $ResultMessage = "The folder '$FolderName' has been created."
      }
       else
      {
       $ResultMessage = "Something went wrong while creating the folder '$FolderName'. "
       $bolResult     = $false
      }
    }
     else
    {
     $ResultMessage = "The folder $FolderName already exists."
    }

    Return $ResultMessage,$bolResult 

   }

  Function Add-EntryToResultsFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       03-August-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Add-EntryToResultsFile
    =============================================================================================================================================
    .SYNOPSIS

    This function adds the success or failure information to the array that contains the information for the datagrid table
    information.

    #>

    Param
     (
      [String] $DisplayName                        = "",
      [String] $PackageAndVersionID                = "",
      [String] $PackageVersion                     = "",
      [String] $PackageDescription                 = "",
      [String] $PublishedGlobally                  = "",
      [String] $PublishedToUser                    = "",
      [String] $Shortcuts                          = "",
      [String] $WriteMode                          = "",
      [String] $ObjectsEnabled                     = "",
      [String] $FontsEnabled                       = "",
      [String] $COMMode                            = "-",
      [String] $COMInProcessEnabled                = "",
      [String] $COMOutOfProcessEnabled             = "",
      [String] $ConnectionGroup                    = "",
      [String] $ShortcutsEnabled                   = "",
      [String] $FTAEnabled                         = "",
      [String] $URLProtocolsEnabled                = "",
      [String] $RegistryEnabled                    = "",
      [String] $FSEnabled                          = "",
      [String] $EVEnabled                          = "",
      [String] $ServicesEnabled                    = "",
      [String] $DeploymentConfigFiles               = ""
     )

     $Record  = [ordered] @{"Display Name"                        = "";
                            "Package and version ID"              = "";
                            "Package Version"                     = "";
                            "Package Description"                 = "";
                            "Published globally"                  = "";
                            "Published to user"                   = "";
                            "Shortcuts"                           = "";
                            "Full VFS Write Mode"                 = "";
                            "Deployment config files"             = "";
                            "Shortcuts Enabled"                   = "";
                            "Filetype associatons Enabled"        = "";
                            "URLProtocols Enabled"                = "";
                            "COM Mode"                            = "";
                            "InProcess Enabled"                   = "";
                            "Out of Process Enabled"              = "";
                            "Objects Enabled"                     = "";
                            "Registry Enabled"                    = "";
                            "Filesystem Enabled"                  = "";
                            "Fonts Enabled"                       = "";
                            "Environment variables Enabled"       = "";
                            "Services Enabled"                    = "";                          
                            "Connection group"                    = "";
                           }

     $Record."Display Name"                  = $DisplayName
     $Record."Package and version ID"        = $PackageAndVersionID
     $Record."Package Version"               = $PackageVersion
     $Record."Package Description"           = $PackageDescription
     $Record."Published globally"            = $PublishedGlobally
     $Record."Published to user"             = $PublishedToUser
     $Record."Shortcuts"                     = $Shortcuts
     $Record."Full VFS Write Mode"           = $WriteMode
     $Record."Deployment config files"       = $DeploymentConfigFiles
     $Record."Shortcuts Enabled"             = $ShortcutsEnabled
     $Record."Filetype associatons Enabled"  = $FTAEnabled
     $Record."URLProtocols Enabled"          = $URLProtocolsEnabled
     $Record."COM Mode"                      = $COMMode
     $Record."InProcess Enabled"             = $COMInProcessEnabled
     $Record."Out of Process Enabled"        = $COMOutOfProcessEnabled
     $Record."Objects Enabled"               = $ObjectsEnabled
     $Record."Registry Enabled"              = $RegistryEnabled
     $Record."Filesystem Enabled"            = $FSEnabled
     $Record."Fonts Enabled"                 = $FontsEnabled
     $Record."Environment variables Enabled" = $EVEnabled
     $Record."Services Enabled"              = $ServicesEnabled          
     $Record."Connection group"              = $ConnectionGroup
 
     $objRecord                              = New-Object PSObject -Property $Record
     $Global:gblarrTable                    += $objRecord

     Add-EntryToLogFile -Entry "Display Name:                           $DisplayName"
     Add-EntryToLogFile -Entry "Package and version:                    $PackageAndVersionID"
     Add-EntryToLogFile -Entry "Package Version:                        $PackageVersion"
     Add-EntryToLogFile -Entry "Package Description:                    $PackageDescription"
     Add-EntryToLogFile -Entry "Published globally:                     $PublishedGlobally"
     Add-EntryToLogFile -Entry "Published to user:                      $PublishedToUser"
     Add-EntryToLogFile -Entry "Shortcuts:                              $Shortcuts"
     Add-EntryToLogFile -Entry "Full VFS Write Mode:                    $WriteMode"
     Add-EntryToLogFile -Entry "Deployment config files:                $DeploymentConfigFiles"
     Add-EntryToLogFile -Entry "Shortcuts Enabled:                      $ShortcutsEnabled"
     Add-EntryToLogFile -Entry "Filetype associatons Enabled:           $FTAEnabled"
     Add-EntryToLogFile -Entry "URLProtocols Enabled:                   $URLProtocolsEnabled"
     Add-EntryToLogFile -Entry "COM Mode:                               $COMMode"
     Add-EntryToLogFile -Entry "InProcess Enabled:                      $COMInProcessEnabled"
     Add-EntryToLogFile -Entry "Out of Process Enabled:                 $COMOutOfProcessEnabled"
     Add-EntryToLogFile -Entry "Objects Enabled:                        $ObjectsEnabled"
     Add-EntryToLogFile -Entry "Registry Enabled:                       $RegistryEnabled"
     Add-EntryToLogFile -Entry "Filesystem Enabled:                     $FSEnabled"
     Add-EntryToLogFile -Entry "Fonts Enabled:                          $FontsEnabled"
     Add-EntryToLogFile -Entry "Environment variables Enabled:          $EVEnabled"
     Add-EntryToLogFile -Entry "Services Enabled:                       $ServicesEnabled"     
     Add-EntryToLogFile -Entry "Connection group:                       $ConnectionGroup"
   }

  Function Add-EntryToConnectionGroupOverview
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       03-August-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Add-EntryToConnectionGroupOverview
    =============================================================================================================================================
    .SYNOPSIS

    This function adds an entry to the connection group overview.

    #>

    Param
     (
      [String] $ConnName,
      [String] $ConnPackages,
      [String] $ConnEnabledToUser,
      [String] $ConnEnabledGlobally,
      [String] $ConnInUse,
      [String] $ConnInUseByCurrentUser,
      [Int]    $ConnPriority
     )

     $Record = [ordered] @{"Connection group name"                      = "";
                           "Packages as a part of the connection group" = "";
                           "Enabled to User"                            = "";
                           "Enabled Globally"                           = "";
                           "In use"                                     = "";
                           "In use by current user"                     = "";
                           "Priority"                                   = "";
                           }

     $Record."Connection group name"                      = $ConnName
     $Record."Packages as a part of the connection group" = $ConnPackages
     $Record."Enabled to User"                            = $ConnEnabledToUser
     $Record."Enabled Globally"                           = $ConnEnabledGlobally
     $Record."In use"                                     = $ConnInUse
     $Record."In use by current user"                     = $ConnInUseByCurrentUser
     $Record."Priority"                                   = $ConnPriority

     $objRecord                                           = New-Object PSObject -Property $Record
     $Global:gblarrConnectionGroups                      += $objRecord

     Add-EntryToLogFile -Entry "Connection group name:                      $ConnName"
     Add-EntryToLogFile -Entry "Packages as a part of the connection group: $ConnPackages"
     Add-EntryToLogFile -Entry "Enabled to User:                            $ConnEnabledToUser"
     Add-EntryToLogFile -Entry "Enabled Globally:                           $ConnEnabledGlobally"
     Add-EntryToLogFile -Entry "In use:                                     $ConnInUse"
     Add-EntryToLogFile -Entry "In use by current user:                     $ConnInUseByCurrentUser"
     Add-EntryToLogFile -Entry "Priority:                                   $ConnPriority"

   }

  Function Add-EntryToGloballyEnabledOrDisabledItems
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       03-August-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Add-EntryToGloballyEnabledOrDisabledItems
    =============================================================================================================================================
    .SYNOPSIS

    This function adds an entry to the table with all the globally enabled or disabled items.

    #>

    Param
     (
      [String] $SubsystemName,
      [String] $Enabled,
      [String] $Disabled
     )

     $Record = [ordered] @{"Subsystem name"   = "";
                           "Enabled"          = "";
                           "Disabled"         = "";
                           }

     $Record."Subsystem name"        = $SubsystemName
     $Record."Enabled"               = $Enabled
     $Record."Disabled"              = $Disabled

     $objRecord                      = New-Object PSObject -Property $Record
     $Global:gblarrEnabledDisabled  += $objRecord

     Add-EntryToLogFile -Entry "Subsystem name:        $SubsystemName"
     Add-EntryToLogFile -Entry "Enabled:               $Enabled"
     Add-EntryToLogFile -Entry "Disabled:              $Disabled"
   }

  Function Write-HTMLFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       02-February-2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Write-HTMLFile
    =============================================================================================================================================
    .SYNOPSIS

    This function creates an HTML file. 

    #>

    param
     (
      [String] $HTMLFileToWrite
     )

  # =============================================================================================================================================
  # Define the CSS file.
  # =============================================================================================================================================
    
    $Header      = ""
    $CSS         = "<style type=$([char]34)text/css$([char]34)>`n"
    $CSS        += "table              {`n"
    $CSS        += "                    font-size:      16px;`n"
    $CSS        += "                    border:         1px solid #395870;`n"
    $CSS        += "                    font-family:    Arial, Helvetica, sans-serif;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "td                 {`n"
    $CSS        += "                    padding:        5px;`n"
    $CSS        += "                    margin:         0px;`n"
    $CSS        += "                    border:         1px solid #395870;`n"
    $CSS        += "                    max-width:      700px;`n"
    $CSS        += "                    vertical-align: top;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "th                 {`n"
    $CSS        += "                    background:     #395870;`n"
    $CSS        += "                    background:     linear-gradient(#49708f, #293f50);`n"
    $CSS        += "                    color:          #fff;`n"
    $CSS        += "                    font-size:      14px;`n"
    $CSS        += "                    padding:        10px 15px;`n"
    $CSS        += "                    vertical-align: top;`n"
    $CSS        += "                    border:         1px solid #395870;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "tr                 {`n"
    $CSS        += "                    width:          1000px;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "h1                 {`n"
    $CSS        += "                    font-family:    Arial, Helvetica, sans-serif;`n"
    $CSS        += "                    color:          #e68a00;`n"
    $CSS        += "                    font-size:      28px;`n"
    $CSS        += "                    text-align:     center;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "h2                 {`n"
    $CSS        += "                    font-family:    Arial, Helvetica, sans-serif;`n"
    $CSS        += "                    color:          #000099;`n"
    $CSS        += "                    font-size:      16px;`n"
    $CSS        += "                    text-align:     center;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "#Cred              {`n"
    $CSS        += "                    font-family:    Arial, Helvetica, sans-serif;`n"
    $CSS        += "                    color:          #0000ff;`n"
    $CSS        += "                    font-size:      12px;`n"
    $CSS        += "                    text-align:     left;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "tr:nth-child(even) {`n"
    $CSS        += "                    background:     #CCC;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "tr:nth-child(odd)  {`n"
    $CSS        += "                    background:     #FFF;`n"
    $CSS        += "                   }`n`n"
    $CSS        += "</style>"
    $CSS      += ""

  # =============================================================================================================================================
  # Replace the `n with <br> in various columns. So there is a proper table layout.
  # Do some cleanup afterwards.
  # =============================================================================================================================================

    ForEach ($Record in $Global:gblarrTable)
     {
      If($Record."Shortcuts")
       {
        $Record."Shortcuts" = $Record."Shortcuts" -replace "`n","<br><br>"
       }
      If($Record."Connection group")
       {
        $Record."Connection group" = $Record."Connection group" -replace "`n","<br><br>"
       }
      If($Record."Deployment config files")
       {
        $Record."Deployment config files" = $Record."Deployment config files" -replace "`n","<br><br>"
       }
      If($Record."Package and version ID")
       {
        $Record."Package and version ID" = $Record."Package and version ID" -replace "`n","<br><br>"
       }
     }

    ForEach ($Record in $Global:gblarrConnectionGroups)
     {
      If($Record."Packages as a part of the connection group")
       {
        $Record. "Packages as a part of the connection group" = $Record. "Packages as a part of the connection group" -replace "`n","<br><br>"
       }
     }
 
    $HTMLTable   = $Global:gblarrTable |Sort-Object -Property "Display Name" | ConvertTo-Html -Fragment -PreContent "<h2>Table</h2>"
    $HTMLTable   = [System.Web.HttpUtility]::HtmlDecode($HTMLTable)
   
    $Title       = "<h1>Overview of all the AppV Packages published on the computer $($Global:gblComputerName)</h1>"
    $Body        = "$Title $HTMLTable"

  # =============================================================================================================================================
  # If applicable: add information about the connection groups to the HTML page.
  # =============================================================================================================================================

    if($Global:gblarrConnectionGroups.Count -gt 0)
     {
      if($Global:gblarrConnectionGroups.Count -gt 1)
       {
        $Global:gblarrConnectionGroups = $Global:gblarrConnectionGroups | Sort-Object -Property Priority
       }
      $HTMLConnectionGroupOverview = $Global:gblarrConnectionGroups | ConvertTo-Html -Fragment
      $HTMLConnectionGroupOverview = [System.Web.HttpUtility]::HtmlDecode($HTMLConnectionGroupOverview)
      $Body +="<br><h2>Overview of the connection groups.</h2><br>$HTMLConnectionGroupOverview"
     }

  # =============================================================================================================================================
  # If applicable: add information about globally enabled or disabled subsystems to the HTML page.
  # =============================================================================================================================================

    if($Global:gblarrEnabledDisabled.Count -gt 0)
     {
      if($Global:gblarrEnabledDisabled.Count -gt 1)
       {
        $Global:gblarrEnabledDisabled = $Global:gblarrEnabledDisabled | Sort-Object -Property "Subsystem Name"
       }
      $HTMLEnabledOrDisabledSubsystems = $Global:gblarrEnabledDisabled | ConvertTo-Html -Fragment
      $HTMLEnabledOrDisabledSubsystems = [System.Web.HttpUtility]::HtmlDecode($HTMLEnabledOrDisabledSubsystems)
      $Body +="<br><h2>Overview of the disabled and enabled subsystems.</h2><br>$HTMLEnabledOrDisabledSubsystems"
     }

  # =============================================================================================================================================
  # If applicable: add information about the used parameters to the HTML page.
  # =============================================================================================================================================


    if($TableWithParameters.Count -gt 0)
     {
      $HTMLParameterstable = $TableWithParameters | ConvertTo-Html -Fragment
      $Body +="<br><h2>Used parameters for the script.</h2><br>$HTMLParameterstable"
     }

  # =============================================================================================================================================
  # The footer and create the HTML page. 
  # =============================================================================================================================================

    $Timestamp   = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
    $PostContent = "<p id=$([char]34)Cred$([char]34)>Creation Date: $Timestamp</p>"
    $Report      = ConvertTo-Html -Head $CSS -Body $Body -PostContent $PostContent 
    $Report | Out-File $HTMLFileToWrite

    $tmpLine = "The webpage '$HTMLFileToWrite' has been created."
    Add-EntryToLogFile -Entry $tmpLine
    Write-Host $tmpLine
   }
  
  Function Read-Registry
   {
    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       13-February-2021 / Modified 14-May-2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Read-Registry
    =============================================================================================================================================
    .SYNOPSIS

    This function reads a registry key and returns the value
    
    #>

    param
     (
      [Parameter(Mandatory=$True)] [String]$RegistryKey,
      [Parameter(Mandatory=$True)] [String]$ValueName
     )

    if(Test-Path ($RegistryKey))
     {
      $Value        = (Get-ItemProperty -Path $RegistryKey).$ValueName
      if(($Value -ne $null) -and ($Value.Length -ne 0))
       {
        Add-EntryToLogFile -Entry "The registrykey '$RegistryKey' with valuename '$ValueName' exists."
        $PropertyType = (Get-Item $RegistryKey).GetValueKind($ValueName)
        Add-EntryToLogFile -Entry "Hive:          $RegistryKey"
        Add-EntryToLogFile -Entry "  - ValueName: $ValueName"
        Add-EntryToLogFile -Entry "  - Type:      $PropertyType"
        Add-EntryToLogFile -Entry "  - Value:     $Value"
        if($PropertyType -eq "String")
         {
          Return $Value
         }
          elseif($PropertyType -eq "DWord")
         {
          if($Value -eq 1)
           {
            Return $True
           }
            else
           {
            Return $False
           }
         }
       }
     }
     Return [string]::Empty
   }

  Function Process-ShortcutsInAppVPackage
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       14-May-2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Process-ShortcutsInAppVPackage
    =============================================================================================================================================
    .SYNOPSIS

    This function processes all the shortcuts that are in an AppV package. 
    #>

    param
     (
      [xml]    $XMLContent,
      [Switch] $UserConfig
     )

     $AllShortcuts    = ""
     $ShortcutCounter = 0

     if($UserConfig)
      { 
       $Shortcuts = $XMLContent.UserConfiguration.Subsystems.Shortcuts.Extensions.Extension
      }
       else
      {
       $Shortcuts = $XMLContent.DeploymentConfiguration.UserConfiguration.Subsystems.Shortcuts.Extensions.Extension
      }
      
      Add-EntryToLogFile -Entry "There a $($Shortcuts) shortcuts found."

      ForEach ($Shortcut in $Shortcuts)
       {
        $SingleShortcut       = ""
        $tmpFile              = $Shortcuts[$ShortcutCounter].Shortcut.File
        $tmpTarget            = $Shortcuts[$ShortcutCounter].Shortcut.Target
        $tmpArguments         = $Shortcuts[$ShortcutCounter].Shortcut.Arguments
        $tmpWorkingDir        = $Shortcuts[$ShortcutCounter].Shortcut.WorkingDirectory

        Add-EntryToLogFile -Entry "   Shortcut details:"

        if($tmpFile)            
         {
          $tmpLine              = "File:        $tmpFile`n"
          Add-EntryToLogFile -Entry "       $tmpLine"
          $SingleShortcut      += $tmpLine
         }
        if($tmpTarget)
         {
          $tmpLine             = "Target:      $tmpTarget $tmpArguments`n"
          Add-EntryToLogFile -Entry  "       $tmpLine"
          $SingleShortcut      += $tmpLine
         }
        if($tmpWorkingDir)
         {
          $tmpLine              = "Working Dir: $tmpWorkingDir"
          Add-EntryToLogFile -Entry  "       $tmpLine"
          $SingleShortcut      += $tmpLine
         }

        if(-not($AllShortcuts))
         {
          $AllShortcuts  = $SingleShortcut 
         }
          else
         {
          Add-EntryToLogFile -Entry ""
          $AllShortcuts += "`n`n$SingleShortcut"
         }
         
        $ShortcutCounter++
       }

     Return $AllShortcuts
   }

  Function Process-AppVPackages
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       02-February-2021
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Process-AppVPackages
    =============================================================================================================================================
    .SYNOPSIS

    This function processes all published AppV Packages. 
    #>

    param
     (
      [Switch] $GUI
     )

    $ProgramDataFolder     = $env:ProgramData
    $PublishedAppVPackages = Get-AppvClientPackage
    $valCounter            = 1
    $valTotalAppVPackages  = $PublishedAppVPackages.Count
    $valConnectionGroups   = (Get-AppvClientConnectionGroup).Count

    if($GUI)
     {
      $lblAction.Text        = "Running an inventory on the installed App-V 5 packages."
      $btnCancel.Enabled     = $False
      $pgbProcessing.Step    = $valCounter / $valTotalAppVPackages * 100
     }

    ForEach($PublishedAppVPackage in $PublishedAppVPackages)
     {
      $tmpPackageID                  = ($PublishedAppVPackage.PackageID).ToString()
      $tmpVersionID                  = ($PublishedAppVPackage.VersionID).ToString()
      $tmpPackageVersion             = ($PublishedAppVPackage.Version).ToString()
      $tmpDisplayName                = ($PublishedAppVPackage.Name)
      $tmpPublishedGlobally          = ($PublishedAppVPackage.IsPublishedGlobally)
      $tmpPublishedToUser            = ($PublishedAppVPackage.IsPublishedToUser)
      $tmpDeploymentConfigFiles      = $null
      $tmpShortcutsEnabled           = $null
      $tmpFTAEnabled                 = $null
      $tmpObjectsEnabled             = $null
      $tmpFontsEnabled               = $null
      $tmpURLProtocolsEnabled        = $null
      $tmpRegistryEnabled            = $null
      $tmpFSEnabled                  = $null
      $tmpEVEnabled                  = $null
      $tmpServicesEnabled            = $null
      $tmpShortcuts                  = $null

      Add-EntryToLogFile -Entry "Found an AppV 5 application with the following details:"
      Add-EntryToLogFile -Entry "  -> Name:                     $tmpDisplayName"
      Add-EntryToLogFile -Entry "  -> Package and version ID:   $tmpPackageID $tmpVersionID"
      Add-EntryToLogFile -Entry "  -> Version:                  $tmpPackageVersion" 

      if($GUI)
       {
        [int] $Percentage = $valCounter / $valTotalAppVPackages * 100
        $lblAction.Text      = "Processing: $tmpDisplayName  (package $valCounter of $valTotalAppVPackages packages - $($Percentage)%)" 
        $pgbProcessing.PerformStep()
       }
        else
       {
        [int] $Percentage = $valCounter / $valTotalAppVPackages * 100
        Write-Progress -Id 1 -Activity "Processing all the installed App-V packages. (package $valCounter of $valTotalAppVPackages packages - $($Percentage)%)" -Status "Processing App-V package $tmpDisplayName" -PercentComplete $Percentage
       }

    # =============================================================================================================================================
    # Fist step: read the %ProgramData%\App-V\<PackageID>\<VersionID>\AppxManifest.xml
    # =============================================================================================================================================

      $AppxManifestXMLFile                       = $ProgramDataFolder + "\App-V\" + $tmpPackageID + "\" + $tmpVersionID + "\AppxManifest.xml"
      [xml]$AppxManifest                         = (Get-Content -Path $AppxManifestXMLFile)      
      $tmpWriteMode                              = $AppXManifest.Package.Properties.FullVFSWriteMode
      $tmpPackageDescription                     = $AppXManifest.Package.Properties.AppVPackageDescription
      $tmpDeploymentConfigFiles                  = $AppxManifestXMLFile

      if($tmpPublishedGlobally)
       {

      # =============================================================================================================================================
      # Second step: (part 1): Read the manifest.xml file that is used. It is in the same location as the deployment configuration xml file.
      # =============================================================================================================================================

        $tmpGlobalDeploymentConfigFilesDir     = Split-Path (($PublishedAppVPackage).GetDynamicDeploymentConfigurationPath())
        $tmpGlobalDeploymentConfigFiles        = $tmpGlobalDeploymentConfigFilesDir + "\Manifest.xml"
        $tmpDeploymentConfigFiles             += "`n" + $tmpGlobalDeploymentConfigFiles
        
        [xml]$DeploymentConfiguration         = (Get-Content -Path ((split-path $tmpGlobalDeploymentConfigFiles) + "\manifest.xml"))
        Add-EntryToLogFile -Entry "  -> Reading the file '$tmpGlobalDeploymentConfigFiles'."
        $tmpCOMMode                           = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.Mode
        $tmpCOMInProcessEnabled               = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.IntegratedCOMAttributes.InProcessEnabled
        $tmpCOMOutOfProcessEnabled            = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.IntegratedCOMAttributes.OutOfProcessEnabled
        $tmpGlobalDeploymentConfigFiles        = $tmpGlobalDeploymentConfigFilesDir + "\DeploymentConfiguration.xml"
        Add-EntryToLogFile -Entry "  -> Reading the file '$tmpGlobalDeploymentConfigFiles' for specific settings."
        
        [xml]$DeploymentConfiguration         = (Get-Content -Path $tmpGlobalDeploymentConfigFiles)
        if($DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.HasChildNodes)
         {
          
        # =============================================================================================================================================
        # Second step: (part 2): Read the global deployment config file only if there are settings applied. That is the case when the node
        # DeploymentConfiguration.UserConfiguration has child nodes.
        # =============================================================================================================================================
        
          Add-EntryToLogFile -Entry "  -> The file '$tmpGlobalDeploymentConfigFiles' is read. It contains settings."
          $tmpDeploymentConfigFiles              += "`n" + $tmpGlobalDeploymentConfigFiles
          $tmpCOMMode                            = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.COM.Mode
          $tmpCOMInProcessEnabled                = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.COM.IntegratedCOMAttributes.InProcessEnabled
          $tmpCOMOutOfProcessEnabled             = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.COM.IntegratedCOMAttributes.OutOfProcessEnabled
          $tmpObjectsEnabled                     = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.Objects.Enabled
          $tmpFontsEnabled                       = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.Fonts.Enabled

          $tmpShortcutsEnabled                   = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.Shortcuts.Enabled
          $tmpFTAEnabled                         = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.FileTypeAssociations.Enabled
          $tmpURLProtocolsEnabled                = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.URLProtocols.Enabled
          $tmpRegistryEnabled                    = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.Registry.Enabled
          $tmpFSEnabled                          = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.FileSystem.Enabled
          $tmpEVEnabled                          = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.EnvironmentVariables.Enabled
          $tmpServicesEnabled                    = $DeploymentConfiguration.DeploymentConfiguration.UserConfiguration.Subsystems.Services.Enabled
          $tmpShortcuts                          = Process-ShortcutsInAppVPackage -XMLContent $DeploymentConfiguration

         } 
       }

     if($tmpPublishedToUser)
       {

      # =============================================================================================================================================
      # Third step: (part 1): Read the UserManifest.xml file that is used. It is in the same location as the deployment configuration xml file.
      # =============================================================================================================================================
      
        $tmpUserDeploymentConfigFiles = ($PublishedAppVPackage).GetDynamicUserConfigurationPath($tmpPublishedGlobally)
        if($tmpUserDeploymentConfigFiles)
         {
          $tmpUserDeploymentConfigFilesDir = Split-Path $tmpUserDeploymentConfigFiles
          $tmpUserDeploymentConfigFiles    = $tmpUserDeploymentConfigFilesDir + "\UserManifest.xml"
          $tmpDeploymentConfigFiles       += "`n" + $tmpUserDeploymentConfigFiles
          Add-EntryToLogFile -Entry "  -> Reading the file '$tmpUserDeploymentConfigFiles'."
         
          [xml]$DeploymentConfiguration   = (Get-Content -Path $tmpUserDeploymentConfigFiles)
          $tmpCOMMode                     = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.Mode
          $tmpCOMInProcessEnabled         = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.IntegratedCOMAttributes.InProcessEnabled
          $tmpCOMOutOfProcessEnabled      = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.IntegratedCOMAttributes.OutOfProcessEnabled

          $tmpUserDeploymentConfigFiles        = ($PublishedAppVPackage).GetDynamicUserConfigurationPath($tmpPublishedGlobally)
          Add-EntryToLogFile -Entry "  -> Reading the file '$tmpUserDeploymentConfigFiles' for specific settings."
          [xml]$DynamicConfiguration   = (Get-Content -Path $tmpUserDeploymentConfigFiles)
          if($DynamicConfiguration.UserConfiguration.HasChildNodes)
           {

          # =============================================================================================================================================
          # Third step: (part 2): Read the user deployment config file only if there are settings applied. That is the case when the node
          # UserConfiguration has child nodes.
          # =============================================================================================================================================
          
            Add-EntryToLogFile -Entry "  -> The application is published to a user. Reading the file '$tmpUserDeploymentConfigFiles' for specific settings."
            $tmpDeploymentConfigFiles    += "`n" + $tmpUserDeploymentConfigFiles
            $tmpCOMMode                  = $DynamicConfiguration.UserConfiguration.Subsystems.COM.Mode
            $tmpCOMInProcessEnabled      = $DynamicConfiguration.UserConfiguration.Subsystems.COM.IntegratedCOMAttributes.InProcessEnabled
            $tmpCOMOutOfProcessEnabled   = $DynamicConfiguration.UserConfiguration.Subsystems.COM.IntegratedCOMAttributes.OutOfProcessEnabled
            $tmpObjectsEnabled           = $DynamicConfiguration.UserConfiguration.Subsystems.Objects.Enabled
            $tmpFontsEnabled             = $DynamicConfiguration.UserConfiguration.Subsystems.Fonts.Enabled

            $tmpShortcutsEnabled         = $DynamicConfiguration.UserConfiguration.Subsystems.Shortcuts.Enabled
            $tmpFTAEnabled               = $DynamicConfiguration.UserConfiguration.Subsystems.FileTypeAssociations.Enabled
            $tmpURLProtocolsEnabled      = $DynamicConfiguration.UserConfiguration.Subsystems.URLProtocols.Enabled
            $tmpRegistryEnabled          = $DynamicConfiguration.UserConfiguration.Subsystems.Registry.Enabled
            $tmpFSEnabled                = $DynamicConfiguration.UserConfiguration.Subsystems.FileSystem.Enabled
            $tmpEVEnabled                = $DynamicConfiguration.UserConfiguration.Subsystems.EnvironmentVariables.Enabled
            $tmpServicesEnabled          = $DynamicConfiguration.UserConfiguration.Subsystems.Services.Enabled
            $NumberOfShortcuts           = 0
            $NumberOfShortcuts           = $DynamicConfiguration.UserConfiguration.Subsystems.Shortcuts.Extensions.Extension.Count
            $tmpShortcuts                = Process-ShortcutsInAppVPackage -XMLContent $DynamicConfiguration -UserConfig
           }       
         }    
       }  
      
    # =============================================================================================================================================
    # Get all the connection groups where a application belongs to.
    # =============================================================================================================================================
            
      $ConnectionGroupNames = (Get-AppvClientConnectionGroup).Name
      $tmpConnectionGroups  = ""

      ForEach ($ConnectionGroupName in $ConnectionGroupNames)
       {
        Add-EntryToLogFile -Entry "  Processing connection group: $ConnectionGroupName"
        $bolFound = (Get-AppvClientConnectionGroup -Name $ConnectionGroupName).GetPackages() | Where {$_.PackageId -eq $tmpPackageID}
        if($bolFound)
         {
          Add-EntryToLogFile -Entry "  The package '$tmpDisplayName' is found in the connectiongroup '$ConnectionGroupName'"
          if(-not($tmpConnectionGroups))
           {
            $tmpConnectionGroups = $ConnectionGroupName
           }
            else
           {
            $tmpConnectionGroups += "`n$ConnectionGroupName"
           }
         }
       }


    # =============================================================================================================================================
    # Add the information to the results file.
    # =============================================================================================================================================

      Add-EntryToResultsFile -DisplayName                         $tmpDisplayName                        `
                             -PackageVersion                      $tmpPackageVersion                     `
                             -PackageAndVersionID                 $($tmpPackageID + "`n" + $tmpVersionID)`
                             -PublishedGlobally                   $tmpPublishedGlobally                  `
                             -PublishedToUser                     $tmpPublishedToUser                    `
                             -Shortcuts                           $tmpShortcuts                          `
                             -COMMode                             $tmpCOMMode                            `
                             -COMInProcessEnabled                 $tmpCOMInProcessEnabled                `
                             -COMOutOfProcessEnabled              $tmpCOMOutOfProcessEnabled             `
                             -ConnectionGroup                     $tmpConnectionGroups                   `
                             -PackageDescription                  $tmpPackageDescription                 `
                             -WriteMode                           $tmpWriteMode                          `
                             -ObjectsEnabled                      $tmpObjectsEnabled                     `
                             -FontsEnabled                        $tmpFontsEnabled                       `
                             -ShortcutsEnabled                    $tmpShortcutsEnabled                   `
                             -FTAEnabled                          $tmpFTAEnabled                         `
                             -URLProtocolsEnabled                 $tmpURLProtocolsEnabled                `
                             -RegistryEnabled                     $tmpRegistryEnabled                    `
                             -FSEnabled                           $tmpFSEnabled                          `
                             -EVEnabled                           $tmpEVEnabled                          `
                             -ServicesEnabled                     $tmpServicesEnabled                    `
                             -DeploymentConfigFiles               $tmpDeploymentConfigFiles
      Add-EntryToLogFile -Entry "#################################################################`n`n" 

      $valCounter ++

     }

    # =============================================================================================================================================
    # Find all the connection groups.
    # =============================================================================================================================================

    if($valConnectionGroups -gt 0)
     {
      ForEach ($ConnectionGroup in Get-AppvClientConnectionGroup)
       {
        $tmpConnName                        = $ConnectionGroup.Name
        $tmpConnEnabledToUser               = $ConnectionGroup.IsEnabledToUser
        $tmpConnEnabledGlobally             = $ConnectionGroup.IsEnabledGlobally
        $tmpConnInUse                       = $ConnectionGroup.InUse
        $tmpConnInUseByCurrentUser          = $ConnectionGroup.InUseByCurrentUser
        $tmpConnPriority                    = $ConnectionGroup.Priority
        $tmpPackages                        = ""
        ForEach ($PackageInConnectionGroup in $(($ConnectionGroup).GetPackages()))
         {
          $tmpLine = $PackageInConnectionGroup.Name + " (" + $PackageInConnectionGroup.Version + ")"
          if(-not($tmpPackages))
           {
            $tmpPackages = $tmpLine
           }
            else
           {
            $tmpPackages += "`n$tmpLine"
           }
         } 
        Add-EntryToConnectionGroupOverview -ConnName                  $tmpConnName               `
                                           -ConnEnabledToUser         $tmpConnEnabledToUser      `
                                           -ConnEnabledGlobally       $tmpConnEnabledGlobally    `
                                           -ConnInUse                 $tmpConnInUse              `
                                           -ConnInUseByCurrentUser    $tmpConnInUseByCurrentUser `
                                           -ConnPriority              $tmpConnPriority           `
                                           -ConnPackages              $tmpPackages
       }
     }

    # =============================================================================================================================================
    # Find all the globally enabled or disabled items
    # =============================================================================================================================================

      $SubsystemItems  = @("Integration","Virtual Fonts","Just-in-timeVirtualization","Virtual Registry","Virtual Filesystem","Virtual COM","Virtual Objects","Virtual Environment","Registry Staging","Virtual Services","Virtual Shell")
      $Regkey = "HKLM:SOFTWARE\Microsoft\AppV\Subsystem\Disabled"
      if(Test-Path -Path $Regkey)
       {
      ForEach ($SubsystemItem in $SubsystemItems)
       {
        $tmpEnabled       = ""
        $tmpDisabled      = ""
        $Result = Read-Registry -RegistryKey $Regkey -ValueName $SubsystemItem
        if($Result -eq $True)            {$tmpDisabled       = $True}
        elseif($Result -eq $False)       {$tmpEnabled        = $True}
        if($tmpEnabled -or $tmpDisabled) {Add-EntryToGloballyEnabledOrDisabledItems -SubsystemName $SubsystemItem -Enabled $tmpEnabled -Disabled $tmpDisabled}
       }
       }

    if($Global:gblSummary)
     {
      $Global:gblarrTable = $Global:gblarrTable | Select-Object -Property "Display Name"             ,`
                                                                          "Package and version ID"   ,`
                                                                          "Package Version"          ,`
                                                                          "Published globally"       ,`
                                                                          "Published to user"        ,`
                                                                          "COM Mode"                 ,`
                                                                          "InProcess Enabled"        ,`
                                                                          "Out of Process Enabled"   ,`
                                                                          "Objects Enabled"          ,`
                                                                          "Connection group"
     }

    if($GUI)
     {
      $lblAction.Visible     = $False
      $pgbProcessing.Visible = $False
      $btnCancel.Enabled     = $True
      if($valTotalAppVPackages -gt 0)
        {
         $btnExitAndSaveAsHTML.Enabled = $True
         $btnExitAndSaveAsCSV.Enabled  = $True
         if($valConnectionGroups -gt 0)
          {
           $btnConnGroup.Enabled = $True
          }
        }
      }

  }

# =============================================================================================================================================
# End function block
# =============================================================================================================================================

# =============================================================================================================================================
# Define the variables
# =============================================================================================================================================

  # Clear-Host
  $Global:gblLogFile             = ""  
  $Global:gblSilent              = $Silent
  $Global:gblNoProgressBar       = $NoProgressBar
  $Global:gblarrTable            = @()
  $Global:gblarrConnectionGroups = @()
  $Global:gblDetailedLogging     = $DetailedLogging
  $Global:gblLogPath             = $LogPath
  $Global:gblComputerName        = $env:COMPUTERNAME
  $Global:gblSummary             = $Summary
  $Global:gblarrEnabledDisabled  = @()
  $Results                       = @()
  $valCounter                    = 1
  $Message                       = ""
  $bolError                      = $false
  $MinimumWidth                  = 1400
  $MinimumHeight                 = 800
  $Header                        = "Information about published AppV Packages v03 (on the $Global:gblComputerName)"
  
  
  if(-not($Global:gblLogPath))
   {
    $Global:gblLogPath   = Split-Path -parent $MyInvocation.MyCommand.Definition
   }

  if(-not(test-path $Global:gblLogPath))
   {
    $Returntext, $bolResult = Create-Folder -FolderName $Global:gblLogPath
    if($bolResult)
     {
      if(-not($Message))
       {
        $Message = $Returntext
       }
        else
       {
        $Message = "`n$Returntext"
       }
     }
      else
     {
      Write-Error $Returntext -Category WriteError
      Exit 2
     }
   }

# =============================================================================================================================================
# Define the results file. This file contains all the results.
# =============================================================================================================================================
 
  $strLastPartOfFileName = " ($((Get-Date).ToString('G')))"
  $strLastPartOfFileName = $strLastPartOfFileName -replace ":","-"
  $strLastPartOfFileName = $strLastPartOfFileName -replace "/","-"
  $PreFixLogFile         = "Overview Published AppV 5 Applications (on $Global:gblComputerName)"
  $Global:gblLogFile     = $Global:gblLogPath + "\"+ $PreFixLogFile + $($strLastPartOfFileName + ".log")
   
  if($Global:gblDetailedLogging)
   {
    New-Item $Global:gblLogFile -ItemType File -Force | Out-Null
   }

  $AppVService = Get-Service AppVClient -ErrorAction SilentlyContinue
  if(-not $AppVService)
   {
    $bolError = $True
    $Returntext = "The AppV Service does not exists."
    if(-not($Message))
       {
        $Message = $Returntext
       }
        else
       {
        $Message = "`n$Returntext"
       }
   }
    elseif($AppVService.Status -eq "Stopped")
   {
    $bolError = $True
    $Returntext = "The AppV Service has as status 'Stopped'."
    if(-not($Message))
       {
        $Message = $Returntext
       }
        else
       {
        $Message = "`n$Returntext"
       }
   }

  if($Message)
   {
    if(-not($bolError))
     {
      Add-EntryToLogFile -Entry "[Warning]: $Message"
     }
      else
     {
      Add-EntryToLogFile -Entry "$Message"
      Add-EntryToLogFile -Entry "This script will now quit."
      Write-Error $Message -Category CloseError
      Exit 3
     }
   }

# =============================================================================================================================================
# Find all the arguments and put them in the log file
# Source: https://ss64.com/ps/psboundparameters.html
# =============================================================================================================================================

  $TableWithParameters  = @()
  $RecordWithParameters = [ordered] @{"Key"     = "";
                                      "Value"   = ""}
  
  ForEach($boundparam in $PSBoundParameters.GetEnumerator()) 
   {
    $tmpValue                     = $($boundparam.Value)
    $Value                        = ""
    if($tmpValue -is [array])
     {
      ForEach ($object in $tmpValue)
       {
        if(-not($value))
         {
          $Value = $object
         }
          else
         {
          $Value +=",$($object)"
         }
       }
     }
      else
     {
      $Value = $tmpValue
     }
    $RecordWithParameters."Key"   = $($boundparam.Key)
    $RecordWithParameters."Value" = $Value
    $objRecordWithParameters      = New-Object PSObject -Property $RecordWithParameters
    $TableWithParameters         += $objRecordWithParameters

    Add-EntryToLogFile -Entry "Key: $($boundparam.Key) Value: $Value" 
   }

# =============================================================================================================================================
# Add assemblies.
# =============================================================================================================================================

  Add-Type -AssemblyName System.Web
  Add-Type -AssemblyName System.Windows.Forms

# =============================================================================================================================================
# Check the screenwidth and screenheight. If too small than falling back to silent mode.
# Source: https://stackoverflow.com/questions/7967699/get-screen-resolution-using-wmi-powershell-in-windows-7
# =============================================================================================================================================

  $DetectedWidth  = ([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize).Width
  $DetectedHeight = ([System.Windows.Forms.SystemInformation]::PrimaryMonitorSize).Height

  if($DetectedWidth -le $MinimumWidth)
   {
    Add-EntryToLogFile -Entry "The screenwidth of $DetectedWidth is less than or equal to $MinimumWidth."
    Add-EntryToLogFile -Entry "Falling back to silent mode."
    $Silent = $True
   }

   if($DetectedHeight -le $MinimumHeight)
    {
     Add-EntryToLogFile -Entry "The screenheight of $DetectedHeight is less than or equal to $MinimumHeight."
     Add-EntryToLogFile -Entry "Falling back to silent mode."
     $Silent = $True  
    }

  if(-not($Silent))
   {
    
  # =============================================================================================================================================
  # Forms block (main form)
  # =============================================================================================================================================
        
   [System.Windows.Forms.Application]::EnableVisualStyles()
   $frmInformationAboutLoad                               = New-Object 'System.Windows.Forms.Form'
   $lblAction                                             = New-Object 'System.Windows.Forms.Label'
   $pgbProcessing                                         = New-Object 'System.Windows.Forms.ProgressBar'
   $btnExitAndSaveAsHTML                                  = New-Object 'System.Windows.Forms.Button'
   $btnExitAndSaveAsCSV                                   = New-Object 'System.Windows.Forms.Button'
   $btnExit                                               = New-Object 'System.Windows.Forms.Button'
   $btnCancel                                             = New-Object 'System.Windows.Forms.Button'
   $btnConnGroup                                          = New-Object 'System.Windows.Forms.Button'
   $btnShowGlobally                                       = New-Object 'System.Windows.Forms.Button'
   $datagridview1                                         = New-Object 'System.Windows.Forms.DataGridView'
   $InitialFormWindowState                                = New-Object 'System.Windows.Forms.FormWindowState'
   $ToolTips                                              = New-Object 'System.Windows.Forms.ToolTip'

   # ToolTips
   #
   $ToolTips.AutomaticDelay                               = 500
   $ToolTips.AutoPopDelay                                 = 5010
   $ToolTips.InitialDelay                                 = 500
   $ToolTips.IsBalloon                                    = $True
   $ToolTips.ReshowDelay                                  = 100
   $ToolTips.Tag                                          = 'Information'
   $ToolTips.ToolTipIcon                                  = 'Info'
   $ToolTips.ToolTipTitle                                 = 'Additonal information'

   # frmInformationAboutLoad
   #
   $frmInformationAboutLoad.Controls.Add($btnExitAndSaveAsHTML)
   $frmInformationAboutLoad.Controls.Add($btnExitAndSaveAsCSV)
   $frmInformationAboutLoad.Controls.Add($btnConnGroup)
   $frmInformationAboutLoad.Controls.Add($btnCancel)
   $frmInformationAboutLoad.Controls.Add($datagridview1)
   $frmInformationAboutLoad.Controls.Add($lblAction)
   $frmInformationAboutLoad.Controls.Add($pgbProcessing)
   $frmInformationAboutLoad.Controls.Add($btnShowGlobally)

   $frmInformationAboutLoad.AutoScaleDimensions           = New-Object System.Drawing.SizeF(6, 13)
   $frmInformationAboutLoad.AutoScaleMode                 = 'Font'
   $frmInformationAboutLoad.ClientSize                    = New-Object System.Drawing.Size(1384, 761)
   $frmInformationAboutLoad.FormBorderStyle               = 'Fixed3D'
   $frmInformationAboutLoad.Name                          = 'frmInformationAboutLoad'
   $frmInformationAboutLoad.StartPosition                 = 'CenterScreen'
   $frmInformationAboutLoad.Text                          = $Header
   $frmInformationAboutLoad.add_Shown({
                              Process-AppVPackages -GUI
                              $datagridview1.Rows.Clear()
                              if($Global:gblarrTable.Count -gt 0)
                               {
                                $datagridview1.Enabled       = $true


                                if($Global:gblarrTable.Count -gt 1)
                                 {                
                                  $Global:gblarrTable          = $Global:gblarrTable | Sort-Object -Property "Display Name"
                                 }
                                $datagridview1.DataSource    = $Null
                                $datagridview1.DataSource    = [System.Collections.ArrayList]$Global:gblarrTable

                                $DisabledItems               = $Global:gblarrEnabledDisabled | Where {($_."Disabled" -eq $True)}
                                if($DisabledItems."Subsystem name".Count -gt 0)
                                 {
                                  $ColumnNames = @()
                                  $btnShowGlobally.Enabled = $True
                                  ForEach ($DisabledItem in $DisabledItems)
                                   {
                                    if ($DisabledItem."Subsystem name" -eq "Integration")         {$ColumnNames += "Shortcuts Enabled"}       
                                    if ($DisabledItem."Subsystem name" -eq "Virtual Objects")     {$ColumnNames += "Objects Enabled"}
                                    if ($DisabledItem."Subsystem name" -eq "Virtual Fonts")       {$ColumnNames += "Fonts Enabled"}
                                    if ($DisabledItem."Subsystem name" -eq "Virtual FileSystem")  {$ColumnNames += "Filesystem Enabled"}
                                    if ($DisabledItem."Subsystem name" -eq "Virtual COM")         {$ColumnNames += "COM Mode"; $ColumnNames += "InProcess Enabled"; $ColumnNames += "Out of Process Enabled";}
                                    if ($DisabledItem."Subsystem name" -eq "Virtual Environment") {$ColumnNames += "Environment variables Enabled"}
                                    if ($DisabledItem."Subsystem name" -eq "Virtual Services")    {$ColumnNames += "Services Enabled"}
                                   }

                                  ForEach ($ColumnName in $ColumnNames)
                                   {
                                    $datagridview1.Columns[$ColumnName].DefaultCellStyle.BackColor = "LightGray"
                                    $datagridview1.Columns[$ColumnName].DefaultCellStyle.ForeColor = "Gray"
                                   }
                                 }

                               }
                           })

   # lblAction
   #
   $lblAction.AutoSize = $True
   $lblAction.Location = New-Object System.Drawing.Point(13, 706)
   $lblAction.Name = 'lblAction'
   $lblAction.Size = New-Object System.Drawing.Size(932, 13)
   $lblAction.TabIndex = 7

   # pgbProcessing
   #
   $pgbProcessing.Location = New-Object System.Drawing.Point(12, 730)
   $pgbProcessing.Name = 'pgbProcessing'
   $pgbProcessing.Size = New-Object System.Drawing.Size(932, 26)
   $pgbProcessing.Style = 'Continuous'
   $pgbProcessing.TabIndex = 0

   # btnExitAndSaveAsHTML
   #
   $btnExitAndSaveAsHTML.Location                         = New-Object System.Drawing.Point(1054, 706)
   $btnExitAndSaveAsHTML.Name                             = 'btnExitAndSaveAsHTML'
   $btnExitAndSaveAsHTML.Size                             = New-Object System.Drawing.Size(75, 50)
   $btnExitAndSaveAsHTML.TabIndex                         = 4
   $btnExitAndSaveAsHTML.Text                             = 'Save as HTML and exit'
   $btnExitAndSaveAsHTML.UseVisualStyleBackColor          = $True
   $btnExitAndSaveAsHTML.Enabled                          = $False
   $ToolTips.SetToolTip($btnExitAndSaveAsHTML, 'Save the results as an HTML file and exit.')

   # btnExitAndSaveAsCSV
   #
   $btnExitAndSaveAsCSV.Location                          = New-Object System.Drawing.Point(1135, 706)
   $btnExitAndSaveAsCSV.Name                              = 'btnExitAndSaveAsCSV'
   $btnExitAndSaveAsCSV.Size                              = New-Object System.Drawing.Size(75, 50)
   $btnExitAndSaveAsCSV.TabIndex                          = 3
   $btnExitAndSaveAsCSV.Text                              = 'Save as CSV and exit'
   $btnExitAndSaveAsCSV.UseVisualStyleBackColor           = $True
   $btnExitAndSaveAsCSV.Enabled                           = $False
   $ToolTips.SetToolTip($btnExitAndSaveAsCSV, 'Save the results as a CSV file and exit.')

   # btnConnGroup
   #
   $btnConnGroup.Location                                 = New-Object System.Drawing.Point(1216, 706)
   $btnConnGroup.Name                                     = 'btnConnGroup'
   $btnConnGroup.Size                                     = New-Object System.Drawing.Size(75, 50)
   $btnConnGroup.TabIndex                                 = 2
   $btnConnGroup.Text                                     = 'Connectiongroup information'
   $btnConnGroup.UseVisualStyleBackColor                  = $True
   $btnConnGroup.Enabled                                  = $False
   $ToolTips.SetToolTip($btnConnGroup, 'Show connectiongroup information.')

   # btnCancel
   #
   $btnCancel.Location                                    = New-Object System.Drawing.Point(1297, 706)
   $btnCancel.Name                                        = 'btnCancel'
   $btnCancel.Size                                        = New-Object System.Drawing.Size(75, 50)
   $btnCancel.TabIndex                                    = 1
   $btnCancel.Text                                        = 'Cancel'
   $btnCancel.UseVisualStyleBackColor                     = $True
   $ToolTips.SetToolTip($btnCancel, 'Exit and nothing is saved.')

   # btnShowGlobally
   #
   $btnShowGlobally.Location = New-Object System.Drawing.Point(973, 706)
   $btnShowGlobally.Name = 'btnShowGlobally'
   $btnShowGlobally.Size = New-Object System.Drawing.Size(75, 50)
   $btnShowGlobally.TabIndex = 5
   $btnShowGlobally.Text = 'Globally subsystems'
   $btnShowGlobally.UseVisualStyleBackColor = $True
   $btnShowGlobally.Enabled = $False
   $ToolTips.SetToolTip($btnShowGlobally, 'Shows information about globally disabled and enabled subsystems.')

   # datagridview1
   #
   $datagridview1.ColumnHeadersHeightSizeMode             = 'AutoSize'
   $datagridview1.Location                                = New-Object System.Drawing.Point(12, 12)
   $datagridview1.Name                                    = 'datagridview1'
   $datagridview1.Size                                    = New-Object System.Drawing.Size(1360, 677)
   $datagridview1.TabIndex                                = 0
   $DataGridViewCellStyle_1                               = New-Object 'System.Windows.Forms.DataGridViewCellStyle'
   $DataGridViewCellStyle_1.Alignment                     = 'TopLeft'
   $DataGridViewCellStyle_1.BackColor                     = [System.Drawing.SystemColors]::Window 
   $DataGridViewCellStyle_1.Font                          = [System.Drawing.Font]::new('Microsoft Sans Serif', '8.25')
   $DataGridViewCellStyle_1.ForeColor                     = [System.Drawing.SystemColors]::ControlText 
   $DataGridViewCellStyle_1.SelectionBackColor            = [System.Drawing.SystemColors]::Highlight 
   $DataGridViewCellStyle_1.SelectionForeColor            = [System.Drawing.SystemColors]::HighlightText 
   $DataGridViewCellStyle_1.WrapMode                      = 'True'
   $datagridview1.DefaultCellStyle                        = $DataGridViewCellStyle_1
   $datagridview1.ColumnHeadersHeightSizeMode             = 'AutoSize'
   $datagridview1.AutoSizeRowsMode                        = 'AllCells'
   $datagridview1.AutoSizeColumnsMode                     = 'AllCells'

   $btnCancel.add_Click({
                         $frmInformationAboutLoad.Close()
                         $frmInformationAboutLoad.Dispose
                       })

    $btnExitAndSaveAsHTML.add_Click({
                                    $HTMLPage = $Global:gblLogFile.Replace(".log",".html")
                                    Write-HTMLFile -HTMLFileToWrite $HTMLPage
                                    $frmInformationAboutLoad.Close()
                                    $frmInformationAboutLoad.Dispose
                                  })

   $btnExitAndSaveAsCSV.add_Click({
                                   $CSVFile = $Global:gblLogFile.Replace(".log",".csv")
                                   Write-CSVFile -CSVFileWithResults $CSVFile -DelimChar $Delimiter
                                   $frmInformationAboutLoad.Close()
                                   $frmInformationAboutLoad.Dispose
                                 })
   $btnConnGroup.add_Click({
                            [void]$frmInformationAboutConn.ShowDialog()
                           })
   
   $btnShowGlobally.add_Click({
                            [void]$frmDisabledSubsystems.ShowDialog()
                           })
   
  # =============================================================================================================================================
  # End forms block (main form)
  # =============================================================================================================================================

  # =============================================================================================================================================
  # Forms block (connection groups)
  # =============================================================================================================================================

    $frmInformationAboutConn                                      = New-Object 'System.Windows.Forms.Form'
    $btndgExit                                                    = New-Object 'System.Windows.Forms.Button'
    $dgvConnectionGroups                                          = New-Object 'System.Windows.Forms.DataGridView'

    # frmInformationAboutConn
    #
    $frmInformationAboutConn.Controls.Add($btndgExit)
    $frmInformationAboutConn.Controls.Add($dgvConnectionGroups)
    $frmInformationAboutConn.AutoScaleDimensions                  = New-Object System.Drawing.SizeF(6, 13)
    $frmInformationAboutConn.AutoScaleMode                        = 'Font'
    $frmInformationAboutConn.BackColor                            = [System.Drawing.SystemColors]::ButtonFace 
    $frmInformationAboutConn.ClientSize                           = New-Object System.Drawing.Size(797, 366)
    $frmInformationAboutConn.FormBorderStyle                      = 'Fixed3D'
    $frmInformationAboutConn.Name                                 = 'frmInformationAboutConn'
    $frmInformationAboutConn.StartPosition                        = 'CenterScreen'
    $frmInformationAboutConn.Text                                 = 'Information about connection groups'
    $frmInformationAboutConn.add_Load({
                                      $dgvConnectionGroups.Enabled = $True
                                      if($Global:gblarrConnectionGroups.Count -gt 1)
                                       {
                                        $Global:gblarrConnectionGroups = $Global:gblarrConnectionGroups | Sort-Object -Property Priority
                                       }
                                      $dgvConnectionGroups.DataSource = [System.Collections.ArrayList]$Global:gblarrConnectionGroups
                                      })

    # btndgExit
    #
    $btndgExit.BackColor                                          = [System.Drawing.SystemColors]::ButtonShadow 
    $btndgExit.Location                                           = New-Object System.Drawing.Point(714, 310)
    $btndgExit.Name                                               = 'btndgExit'
    $btndgExit.Size                                               = New-Object System.Drawing.Size(75, 50)
    $btndgExit.TabIndex                                           = 1
    $btndgExit.Text                                               = '&Exit'
    $btndgExit.UseVisualStyleBackColor                            = $False
    $btndgExit.add_Click({
                          $frmInformationAboutConn.Close()
                          $frmInformationAboutConn.Dispose
                         })

    
    # dgvConnectionGroups
    #
    $System_Windows_Forms_DataGridViewCellStyle_1                 = New-Object 'System.Windows.Forms.DataGridViewCellStyle'
    $System_Windows_Forms_DataGridViewCellStyle_1.Alignment       = 'TopLeft'
    $System_Windows_Forms_DataGridViewCellStyle_1.WrapMode        = 'True'
    $dgvConnectionGroups.AlternatingRowsDefaultCellStyle          = $System_Windows_Forms_DataGridViewCellStyle_1
    $dgvConnectionGroups.ColumnHeadersHeightSizeMode              = 'AutoSize'
    $dgvConnectionGroups.Location                                 = New-Object System.Drawing.Point(10, 11)
    $dgvConnectionGroups.Name                                     = 'dgvConnectionGroups'
    $dgvConnectionGroups.Size                                     = New-Object System.Drawing.Size(779, 293)
    $dgvConnectionGroups.TabIndex                                 = 0
    $dgvConnectionGroups.DefaultCellStyle                         = $System_Windows_Forms_DataGridViewCellStyle_1
    $dgvConnectionGroups.ColumnHeadersHeightSizeMode              = 'AutoSize'
    $dgvConnectionGroups.AutoSizeRowsMode                         = 'AllCells'
    $dgvConnectionGroups.AutoSizeColumnsMode                      = 'AllCells'

  # =============================================================================================================================================
  # End forms block (Connection Groups)
  # =============================================================================================================================================
  
  # =============================================================================================================================================
  # Forms block (Globally disabled and enabled subsystems)
  # =============================================================================================================================================

    $frmDisabledSubsystems                                                 = New-Object 'System.Windows.Forms.Form'
    $btnDIExit                                                             = New-Object 'System.Windows.Forms.Button'
    $dgvDisabledEnabledSubSystems                                          = New-Object 'System.Windows.Forms.DataGridView'

    $frmDisabledSubsystems.Controls.Add($btnDIExit)
    $frmDisabledSubsystems.Controls.Add($dgvDisabledEnabledSubSystems)
    $frmDisabledSubsystems.AutoScaleDimensions                             = New-Object System.Drawing.SizeF(6, 13)
    $frmDisabledSubsystems.AutoScaleMode                                   = 'Font'
    $frmDisabledSubsystems.BackColor                                       = [System.Drawing.SystemColors]::ButtonFace 
    $frmDisabledSubsystems.ClientSize                                      = New-Object System.Drawing.Size(530, 280)
    $frmDisabledSubsystems.FormBorderStyle                                 = 'Fixed3D'
    $frmDisabledSubsystems.Name                                            = 'frmDisabledSubsystems'
    $frmDisabledSubsystems.StartPosition                                   = 'CenterScreen'
    $frmDisabledSubsystems.Text                                            = 'Information about globally disabled and enabled subsystems'
    $frmDisabledSubsystems.add_Load({
                                      if($Global:gblarrConnectionGroups.Count -gt 1)
                                       {
                                        $Global:gblarrEnabledDisabled = $Global:gblarrEnabledDisabled | Sort-Object -Property "Subsystem name"
                                       }
                                      $dgvDisabledEnabledSubSystems.DataSource = [System.Collections.ArrayList]$Global:gblarrEnabledDisabled
                                      })

    # btnDIExit
    #
    $btnDIExit.BackColor                                                   = [System.Drawing.SystemColors]::ButtonShadow 
    $btnDIExit.Location                                                    = New-Object System.Drawing.Point(443, 222)
    $btnDIExit.Name                                                        = 'btnDIExit'
    $btnDIExit.Size                                                        = New-Object System.Drawing.Size(75, 50)
    $btnDIExit.TabIndex                                                    = 1
    $btnDIExit.Text                                                        = '&Exit'
    $btnDIExit.UseVisualStyleBackColor                                     = $False
    $btnDIExit.add_Click({
                          $frmDisabledSubsystems.Close()
                          $frmDisabledSubsystems.Dispose
                         })

    # dgvDisabledEnabledSubSystems
    #
    $System_Windows_Forms_DataGridViewCellStyle_2                          = New-Object 'System.Windows.Forms.DataGridViewCellStyle'
    $System_Windows_Forms_DataGridViewCellStyle_2.Alignment                = 'TopLeft'
    $System_Windows_Forms_DataGridViewCellStyle_2.WrapMode                 = 'True'
    $dgvDisabledEnabledSubSystems.DefaultCellStyle                         = $System_Windows_Forms_DataGridViewCellStyle_2
    $dgvDisabledEnabledSubSystems.AlternatingRowsDefaultCellStyle          = $System_Windows_Forms_DataGridViewCellStyle_2
    $dgvDisabledEnabledSubSystems.ColumnHeadersHeightSizeMode              = 'AutoSize'
    $dgvDisabledEnabledSubSystems.Location                                 = New-Object System.Drawing.Point(10, 11)
    $dgvDisabledEnabledSubSystems.Name                                     = 'dgvDisabledEnabledSubSystems'
    $dgvDisabledEnabledSubSystems.Size                                     = New-Object System.Drawing.Size(508, 205)
    $dgvDisabledEnabledSubSystems.TabIndex                                 = 0
    $dgvDisabledEnabledSubSystems.ColumnHeadersHeightSizeMode              = 'AutoSize'
    $dgvDisabledEnabledSubSystems.AutoSizeRowsMode                         = 'AllCells'
    $dgvDisabledEnabledSubSystems.AutoSizeColumnsMode                      = 'AllCells'

  # =============================================================================================================================================
  # End Forms block (Globally disabled and enabled items)
  # =============================================================================================================================================

    [void]$frmInformationAboutLoad.ShowDialog()

   }
    else
   {
    Process-AppVPackages
    if($SaveAsCSVFile -or (-not $SaveAsHTMLPage))
     {
      $CSVFile = $Global:gblLogFile.Replace(".log",".csv")
      Write-CSVFile -CSVFileWithResults $CSVFile -DelimChar $Delimiter
     }
    if($SaveAsHTMLPage)
     {
      $HTMLPage = $Global:gblLogFile.Replace(".log",".html")
      Write-HTMLFile -HTMLFileToWrite $HTMLPage
     }

   }