The 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 into silent mode.
PowerShell ConstrainedLanguage e and FullLanguage Mode
During additional testing, I found that applocker can cause some issues. If there are script rules defined and the script is not run from %WINDIR% or %ProgramFiles% then the constrainedlanguage in PowerShell is effective. Then there is a limited set of commands available. That has been implemented.
Command line options
If you want to know all the command line options please run:
Get-Help ".\InformationAboutLoadedAppVPackages_v05.ps1" -Detailed
The output:
NAME
C:\AppV5\InformationAboutPublishedAppVPackages_v05.ps1
SYNOPSIS
Displays information about published AppV packages in a grid.
SYNTAX
C:\AppV5\InformationAboutPublishedAppVPackages_v05.ps1 [-Silent] [-LogPath <String>] [-DetailedLogging]
[-SaveAsHTMLPage] [-SaveAsCSVFile] [-SaveAsPDF] [-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>]
-SaveAsPDF [<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_v05.ps1"
-------------------------- EXAMPLE 2 --------------------------
PS C:\>Start the application with a GUI and detailed logging to c:\tmp
."InformationAboutPublishedAppVPackages_v05.ps1" -DetailedLogging -LogPath c:\tmp
-------------------------- EXAMPLE 3 --------------------------
PS C:\>Start the application with a GUI and verbose output
."InformationAboutPublishedAppVPackages_v05.ps1" -Verbose
-------------------------- EXAMPLE 4 --------------------------
PS C:\>Start the application with silent and export the result to a CSV file.
."InformationAboutPublishedAppVPackages_v05.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_v05.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_v05.ps1" -Summary
REMARKS
To see the examples, type: "get-help C:\AppV5\InformationAboutPublishedAppVPackages_v05.ps1 -examples".
For more information, type: "get-help C:\AppV5\InformationAboutPublishedAppVPackages_v05.ps1 -detailed".
For technical information, type: "get-help C:\AppV5\InformationAboutPublishedAppVPackages_v05.ps1 -full".
More background information:
PowerShell error message stating that the connection group could not be created as there is a mismatch with the virtual COM settings.
Check the COM Mode settings from the marked applications (with the summary parameter).
And now with the corrected deployment XML files used (with the summary parameter).
Now, with detailed connection group information (with the summary parameter).
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_v05.ps1"
.EXAMPLE
Start the application with a GUI and detailed logging to c:\tmp
."InformationAboutPublishedAppVPackages_v05.ps1" -DetailedLogging -LogPath c:\tmp
.EXAMPLE
Start the application with a GUI and verbose output
."InformationAboutPublishedAppVPackages_v05.ps1" -Verbose
.EXAMPLE
Start the application with silent and export the result to a CSV file.
."InformationAboutPublishedAppVPackages_v05.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_v05.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_v05.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
v0.4:
* Option to print to PDF with the swith 'SaveAsPDF'
* Messagebox for all the messages.
* The buttons 'Save as PDF and exit', 'Save as HTML and exit' and 'Save as CSV and exit' are replaced by a new button 'Save options'.
Then a new window will pop-up and the user can select the items to print.
The button 'Globally subsystems' has a new position, next to 'Connection group information'.
v0.5:
* Get-AppVClientPackage has been replaced by Get-AppVClientPackage -All in the function Process-AppVPackages.
* PowerShell LanguageMode is detected. Usefull when AppLocker is effective.
#>
[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='Save as a PDF file.')]
[Parameter(Mandatory=$False, ParameterSetName='Default')]
[Switch] $SaveAsPDF,
[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 Display-MessageBox
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 24-May-2021
Created by: Willem-Jan Vroom
Organization:
Functionname: Display-MessageBox
=============================================================================================================================================
.SYNOPSIS
This function displays a message box.
#>
param
(
[String] $Text,
[Switch] $GUI,
[Switch] $Error
)
if($GUI)
{
if($Error)
{
[System.Windows.MessageBox]::Show($Text,"Error","OK","Error")
}
else
{
[System.Windows.MessageBox]::Show($Text,"Information","OK","Asterisk")
}
}
else
{
Write-Host "$Text`n"
}
}
Function Test-Service
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 24-May-2021
Created by: Willem-Jan Vroom
Organization:
Functionname: Test-Service
=============================================================================================================================================
.SYNOPSIS
This function tests if the given service exists and in case yes, if running.
If the service does not exists or is not running, the function returns a false
#>
param
(
[String] $Name
)
Try
{
$ServiceDetails = Get-Service -Name $Name -ErrorAction SilentlyContinue
if ($ServiceDetails.Status -eq "Running")
{
Return $True
}
else
{
Return $False
}
}
Catch
{
Return $False
}
}
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 = ";",
[Switch] $GUI
)
If($Global:gblarrTable)
{
$Global:gblarrTable | Export-Csv $CSVFileWithResults -NoTypeInformation -Delimiter $DelimChar
$tmpLine = "The CSV file '$CSVFileWithResults' has been created."
Add-EntryToLogFile -Entry ">> Write-CSVFile: $tmpLine"
if($GUI)
{
Display-MessageBox -Text $tmpLine -GUI
}
else
{
Display-MessageBox -Text $tmpLine
}
}
else
{
$ErrorMessage = "Something went wrong while writing the CSV file '$CSVFileWithResults'. Maybe nothing to report..."
Add-EntryToLogFile -Entry "[Error]: $ErrorMessage"
if($GUI)
{
Display-MessageBox -Text $ErrorMessage -GUI -Error
}
else
{
Display-MessageBox -Text $ErrorMessage -Error
}
}
}
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,
[Switch] $SaveAsPDFFile,
[Switch] $GUI
)
# =============================================================================================================================================
# 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 = ""
if($SaveAsPDFFile)
{
$Global:gblarrTable = $Global:gblarrTable |Sort-Object -Property "Display Name"
ForEach ($Record in $Global:gblarrTable)
{
$HTMLTable += $Record | ConvertTo-Html -Fragment -As List
$HTMLTable += "<br>"
}
$A4Pixels = 595 * .9
$Table1_Width = $A4Pixels *.3
$Table1_Width = $A4Pixels *.7
$HTMLTable = $HTMLTable -replace ("<table>","<table width=$($A4Pixels)px>")
$HTMLTable = $HTMLTable -replace ("<tr><td>","<tr><td width=$($Table1_Width)px>")
$HTMLTable = $HTMLTable -replace ("</td><td>","</td><td width=$($Table1_Width)px>")
$HTMLTable = $HTMLTable -replace ("</table>","</table>`n")
}
else
{
$HTMLTable = $Global:gblarrTable |Sort-Object -Property "Display Name" | ConvertTo-Html -Fragment
}
$HTMLTable = [System.Web.HttpUtility]::HtmlDecode($HTMLTable)
$Title = "<h1>Overview of all the AppV Packages published on the computer $($Global:gblComputerName)</h1>"
$Body = "$Title<h2>Table</h2>$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
}
if($SaveAsPDFFile)
{
$HTMLConnectionGroupOverview = ""
ForEach ($Record in $Global:gblarrConnectionGroups)
{
$HTMLConnectionGroupOverview += $Record | ConvertTo-Html -Fragment -As List
$HTMLConnectionGroupOverview += "<br>"
}
}
else
{
$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"
}
if($SaveAsPDFFile)
{
$HTMLEnabledOrDisabledSubsystems = ""
ForEach ($Record in $Global:gblarrEnabledDisabled)
{
$HTMLEnabledOrDisabledSubsystems += $Record | ConvertTo-Html -As List -Fragment
$HTMLEnabledOrDisabledSubsystems += "<br>"
}
}
else
{
$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)
{
if($SaveAsPDFFile)
{
$HTMLParameterstable = ""
ForEach ($Record in $TableWithParameters)
{
$HTMLParameterstable += $Record | ConvertTo-Html -As List -Fragment
$HTMLParameterstable += "<br>"
}
}
else
{
$HTMLParameterstable = $TableWithParameters | ConvertTo-Html -Fragment
}
$Body +="<br><h2>Used parameters for the script.</h2><br>$HTMLParameterstable"
}
# =============================================================================================================================================
# Load all the DLL files that are needed for IText7 HTML To PDF
# See https://kb.itextsupport.com/home/it7kb/ebooks/itext-7-converting-html-to-pdf-with-pdfhtml for more information.
# For licensing issues the following files are not included in the zip package:
# - BouncyCastle.Crypto.dll
# - Common.Logging.Core.dll / .pdb / .xml
# - Common.Logging.dll / .pdb / .xml
# - itext.barcodes.dll / .xml
# - itext.forms.dll / .xml
# - itext.html2pdf.dll / .xml
# - itext.io.dll / .xml
# - itext.kernel.dll / .xml
# - itext.layout.dll / .xml
# - itext.pdfa.dll / .xml
# - itext.sign.dll / .xml
# - itext.styledxmlparser.dll / .xml
# - itext.svg.dll / .xml
# =============================================================================================================================================
$DLLFilesLoadedSuccessfully = $True
if($SaveAsPDFFile)
{
if($Global:gblDLLPathExists)
{
$DLLFiles = Get-ChildItem -Path $Global:gblDLLPath -Filter *.dll -File
ForEach ($DLLFile in $DLLFiles)
{
Try
{
Add-Type -Path $($DLLFile.FullName)
Add-EntryToLogFile "The DLL file '$($DLLFile.FullName)' has been loaded successfully."
}
Catch
{
$DLLFilesLoadedSuccessfully = $False
Add-EntryToLogFile "Failure while loading the DLL file '$($DLLFile.FullName)': $($_.Exception.Message)."
}
}
}
else
{
Add-EntryToLogFile -Entry "The path '$Global:gblDLLPath' does not exists. As these DLL's are needed, the PDF file cannot be created."
}
}
# =============================================================================================================================================
# 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
if($SaveAsPDFFile)
{
if($Global:gblDLLPathExists)
{
if($DLLFilesLoadedSuccessfully)
{
$PDFFileToWrite = [System.IO.FileInfo]::new($HTMLFileToWrite -replace("html","pdf"))
$HTMLFileToWrite = $env:TEMP + "\TempHTMLFile.html"
$Report | Out-File $HTMLFileToWrite
$HTMLInputFile = [System.IO.FileInfo]::new($HTMLFileToWrite)
[iText.Html2Pdf.HtmlConverter]::ConvertToPdf($HTMLInputFile, $PDFFileToWrite)
$tmpLine = "The PDF file '$PDFFileToWrite' has been created."
Add-EntryToLogFile -Entry $tmpLine
if($GUI)
{
Display-MessageBox -GUI -Text $tmpLine
}
else
{
Display-MessageBox -Text $tmpLine
}
Remove-Item -Path $HTMLFileToWrite
}
else
{
$tmpLine = "There where errors while loading the DLL files from '$Global:gblDLLPath'. So no PDF file is created."
Add-EntryToLogFile -Entry $tmpLine
if($GUI)
{
Display-MessageBox -GUI -Text $tmpLine
}
else
{
Display-MessageBox -Text $tmpLine
}
}
}
else
{
Add-EntryToLogFile -Entry "The path '$Global:gblDLLPath' does not exists. So the PDF file is not created as it needs files in that directory."
}
}
else
{
$Report | Out-File $HTMLFileToWrite
$tmpLine = "The webpage '$HTMLFileToWrite' has been created."
Add-EntryToLogFile -Entry $tmpLine
if($GUI)
{
Display-MessageBox -GUI -Text $tmpLine
}
else
{
Display-MessageBox -Text $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 / Modified on 10-Dec-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 -All
$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
}
else
{
Add-EntryToLogFile -Entry "The file '$tmpGlobalDeploymentConfigFiles' does not contain settings."
}
}
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.
# =============================================================================================================================================
if(-not($Global:bolConstrainedLanguage))
{
$tmpDynamicConfiguration = ($PublishedAppVPackage).GetDynamicUserConfigurationPath($tmpPublishedGlobally)
if($tmpDynamicConfiguration)
{
$tmpUserManifestDir = Split-Path $tmpDynamicConfiguration
$tmpUserManifest = $tmpUserManifestDir + "\UserManifest.xml"
$tmpDeploymentConfigFiles += "`n" + $tmpUserManifest
Add-EntryToLogFile -Entry " -> Reading the file '$tmpUserManifests'."
[xml]$DeploymentConfiguration = (Get-Content -Path $tmpUserManifest)
$tmpCOMMode = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.Mode
$tmpCOMInProcessEnabled = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.IntegratedCOMAttributes.InProcessEnabled
$tmpCOMOutOfProcessEnabled = $DeploymentConfiguration.Package.ExtensionsConfiguration.COM.IntegratedCOMAttributes.OutOfProcessEnabled
Add-EntryToLogFile -Entry " -> Reading the file '$tmpDynamicConfiguration' for specific settings."
[xml]$DynamicConfiguration = (Get-Content -Path $tmpDynamicConfiguration)
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 '$tmpDynamicConfiguration' for specific settings."
$tmpDeploymentConfigFiles += "`n" + $tmpDynamicConfiguration
$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
}
else
{
Add-EntryToLogFile -Entry "The file '$tmpDynamicConfiguration' does not contain settings."
}
}
}
}
# =============================================================================================================================================
# 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)
{
$btnShowSaveOptions.Enabled = $True
if($valConnectionGroups -gt 0)
{
$btnConnGroup.Enabled = $True
}
}
}
}
# =============================================================================================================================================
# End function block
# =============================================================================================================================================
# =============================================================================================================================================
# Functions, used in the forms blocks
# =============================================================================================================================================
Function InformationAboutLoad
{
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"
}
}
}
}
Function Cancel
{
$frmInformationAboutLoad.Close()
$frmInformationAboutLoad.Dispose
}
Function ShowSaveOptions
{
[void]$frmSaveOptions.ShowDialog()
$frmInformationAboutLoad.Close()
$frmInformationAboutLoad.Dispose
}
Function InformationAboutConn
{
$dgvConnectionGroups.Enabled = $True
if($Global:gblarrConnectionGroups.Count -gt 1)
{
$Global:gblarrConnectionGroups = $Global:gblarrConnectionGroups | Sort-Object -Property Priority
}
$dgvConnectionGroups.DataSource = [System.Collections.ArrayList]$Global:gblarrConnectionGroups
}
Function dgExit
{
$frmInformationAboutConn.Close()
$frmInformationAboutConn.Dispose
}
Function DisabledSubsystems
{
if($Global:gblarrConnectionGroups.Count -gt 1)
{
$Global:gblarrEnabledDisabled = $Global:gblarrEnabledDisabled | Sort-Object -Property "Subsystem name"
}
$dgvDisabledEnabledSubSystems.DataSource = [System.Collections.ArrayList]$Global:gblarrEnabledDisabled
}
Function DIExit
{
$frmDisabledSubsystems.Close()
$frmDisabledSubsystems.Dispose
}
Function SoExit
{
$chkSaveHTML.Enabled = $False
$chkSaveCSV.Enabled = $False
$chkSaveAsPDFFile.Enabled = $False
if($chkSaveCSV.Checked)
{
$CSVFile = $Global:gblLogFile.Replace(".log",".csv")
Write-CSVFile -CSVFileWithResults $CSVFile -DelimChar $Delimiter -GUI
}
if($chkSaveHTML.Checked)
{
$HTMLPage = $Global:gblLogFile.Replace(".log",".html")
Write-HTMLFile -HTMLFileToWrite $HTMLPage -GUI
}
if($chkSaveAsPDFFile.Checked)
{
$HTMLPage = $Global:gblLogFile.Replace(".log",".html")
Write-HTMLFile -HTMLFileToWrite $HTMLPage -SaveAsPDFFile -GUI
}
$frmSaveOptions.Close()
$frmSaveOptions.Dispose
}
# =============================================================================================================================================
# End functions, used in the forms blocks
# =============================================================================================================================================
# =============================================================================================================================================
# Define the variables
# =============================================================================================================================================
Clear-Host
$Global:gblLogFile = ""
$Global:gblNoProgressBar = $NoProgressBar
$Global:gblarrTable = @()
$Global:gblarrConnectionGroups = @()
$Global:gblDetailedLogging = $DetailedLogging
$Global:gblLogPath = $LogPath
$Global:gblComputerName = $env:COMPUTERNAME
$Global:gblSummary = $Summary
$Global:gblarrEnabledDisabled = @()
$Global:gblDLLPath = $(Split-Path $MyInvocation.MyCommand.Definition) + "\DLLFilesForItext7"
$Global:gblDLLPathExists = $False
$Global:bolConstrainedLanguage = $ExecutionContext.SessionState.LanguageMode -eq "ConstrainedLanguage"
$Results = @()
$valCounter = 1
$Message = ""
$bolError = $false
$MinimumWidth = 1400
$MinimumHeight = 800
$Header = "Information about published AppV Packages v05 (on the $Global:gblComputerName)"
$AppVServiceName = "AppVClient"
if(-not($Global:gblLogPath))
{
$Global:gblLogPath = Split-Path $MyInvocation.MyCommand.Definition
}
if(Test-Path $Global:gblDLLPath)
{
$Global:gblDLLPathExists = $True
}
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
}
if($Global:bolConstrainedLanguage)
{
Add-EntryToLogFile -Entry "PowerShell LanguageMode: ConstrainedLanguage. Possible cause: AppLocker."
Add-EntryToLogFile -Entry "Falling back to silent mode"
$Silent = $True
}
else
{
Add-EntryToLogFile -Entry "PowerShell LanguageMode: FullLanguage"
}
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
# =============================================================================================================================================
if(-not($Global:bolConstrainedLanguage))
{
$TableWithParameters = @()
$RecordWithParameters = [ordered] @{"Key" = "";
"Value" = ""}
Add-EntryToLogFile -Entry "***** Parameters part *****"
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
}
Add-EntryToLogFile -Entry "Key: $($boundparam.Key) Value: $Value"
}
Add-EntryToLogFile -Entry "***** End Parameters part *****`r`n"
}
else
{
Add-EntryToLogFile -Entry "The parameters are not written to the logfile due to PowerShell ConstrainedMode."
}
# =============================================================================================================================================
# Check if the AppVService exists and is running.
# =============================================================================================================================================
if(-not (Test-Service $AppVServiceName))
{
$tmpLine = "The AppV Service $AppVServiceName is not running or does not exists. Anyway, we cannot continue.`nThe script will quit now."
if($Silent)
{
Display-MessageBox -Text $tmpLine -Error
}
else
{
Display-MessageBox -Text $tmpLine -Error -GUI
}
Exit 1
}
# =============================================================================================================================================
# Add assemblies.
# =============================================================================================================================================
if(-not($Silent))
{
Add-Type -AssemblyName System.Web
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName PresentationFramework
# =============================================================================================================================================
# 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) -or ($DetectedHeight -le $MinimumHeight))
{
$tmpLine = ""
if($DetectedWidth -le $MinimumWidth)
{
$tmpLine = "The screenwidth of $DetectedWidth is less than or equal to $MinimumWidth."
Add-EntryToLogFile -Entry $tmpLine
Add-EntryToLogFile -Entry "Falling back to silent mode."
$Silent = $True
}
if($DetectedHeight -le $MinimumHeight)
{
$tmpLine1 = "The screenheight of $DetectedHeight is less than or equal to $MinimumHeight."
Add-EntryToLogFile -Entry $tmpLine1
Add-EntryToLogFile -Entry "Falling back to silent mode."
$Silent = $True
if(-not($tmpLine))
{
$tmpLine = $tmpLine1
}
else
{
$tmpLine += "`n$tmpLine1"
}
}
$tmpLine += "`nFalling back to silent mode."
Display-MessageBox -Text $tmpLine -GUI -Error
}
}
if($Silent)
{
# =============================================================================================================================================
# In the silent mode.
# =============================================================================================================================================
if($SaveAsPDF -and -not $Global:gblDLLPathExists)
{
$SaveAsPDF = $False
Add-EntryToLogFile -Entry "[WARNING]: The directory with all the DLL files for converting a HTML file to PDF is not found. Therefore, the option SaveAsPDF is disabled."
}
Process-AppVPackages
# =============================================================================================================================================
# If the ContrainedMode is used, then use only a limited set of columns.
# =============================================================================================================================================
if($Global:bolConstrainedLanguage)
{
$Global:gblarrTable = $Global:gblarrTable | Select-Object -Property "Display Name","Package and version ID","Package Version","Package Description","Published globally","Published to user","Shortcuts","Full VFS Write Mode","Deployment config files"
}
# =============================================================================================================================================
# Write the output files.
# =============================================================================================================================================
if($SaveAsCSVFile -or (-not $SaveAsHTMLPage -and -not $SaveAsPDF))
{
$CSVFile = $Global:gblLogFile.Replace(".log",".csv")
Write-CSVFile -CSVFileWithResults $CSVFile -DelimChar $Delimiter
}
if($SaveAsPDF)
{
$HTMLPage = $Global:gblLogFile.Replace(".log",".html")
Write-HTMLFile -HTMLFileToWrite $HTMLPage -SaveAsPDFFile
}
if($SaveAsHTMLPage)
{
$HTMLPage = $Global:gblLogFile.Replace(".log",".html")
Write-HTMLFile -HTMLFileToWrite $HTMLPage
}
}
else
{
# =============================================================================================================================================
# In the non-silent mode.
# =============================================================================================================================================
# =============================================================================================================================================
# 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'
$btnShowSaveOptions = 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($btnShowSaveOptions)
$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({InformationAboutLoad})
# lblAction
#
$lblAction.AutoSize = $True
$lblAction.Location = New-Object System.Drawing.Point(13, 706)
$lblAction.Name = 'lblAction'
$lblAction.Size = New-Object System.Drawing.Size(859, 26)
$lblAction.TabIndex = 7
# pgbProcessing
#
$pgbProcessing.Location = New-Object System.Drawing.Point(13, 730)
$pgbProcessing.Name = 'pgbProcessing'
$pgbProcessing.Size = New-Object System.Drawing.Size(859, 26)
$pgbProcessing.Style = 'Continuous'
$pgbProcessing.TabIndex = 0
# btnShowSaveOptions
#
$btnShowSaveOptions.Location = New-Object System.Drawing.Point(1054, 706)
$btnShowSaveOptions.Name = 'btnShowSaveOptions'
$btnShowSaveOptions.Size = New-Object System.Drawing.Size(75, 50)
$btnShowSaveOptions.TabIndex = 4
$btnShowSaveOptions.Text = 'Save options'
$btnShowSaveOptions.UseVisualStyleBackColor = $True
$btnShowSaveOptions.Enabled = $False
$ToolTips.SetToolTip($btnShowSaveOptions, 'Save the results as a PDF, HTML or CSV file.')
# 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(1135, 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({Cancel})
$btnShowSaveOptions.add_Click({ShowSaveOptions})
$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({InformationAboutConn})
# 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({dgExit})
# 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({DisabledSubsystems})
# 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({DIExit})
# 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)
# =============================================================================================================================================
# =============================================================================================================================================
# Forms block Save options
# =============================================================================================================================================
$frmSaveOptions = New-Object 'System.Windows.Forms.Form'
$chkSaveAsPDFFile = New-Object 'System.Windows.Forms.CheckBox'
$chkSaveHTML = New-Object 'System.Windows.Forms.CheckBox'
$chkSaveCSV = New-Object 'System.Windows.Forms.CheckBox'
$btnSOExit = New-Object 'System.Windows.Forms.Button'
$ToolTips = New-Object 'System.Windows.Forms.ToolTip'
# frmSaveOptions
#
$frmSaveOptions.Controls.Add($chkSaveAsPDFFile)
$frmSaveOptions.Controls.Add($chkSaveHTML)
$frmSaveOptions.Controls.Add($chkSaveCSV)
$frmSaveOptions.Controls.Add($btnSOExit)
$frmSaveOptions.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$frmSaveOptions.AutoScaleMode = 'Font'
$frmSaveOptions.BackColor = [System.Drawing.SystemColors]::ButtonFace
$frmSaveOptions.ClientSize = New-Object System.Drawing.Size(291, 132)
$frmSaveOptions.FormBorderStyle = 'Fixed3D'
$frmSaveOptions.Name = 'frmSaveOptions'
$frmSaveOptions.StartPosition = 'CenterScreen'
$frmSaveOptions.Text = 'Save options'
# checkboxSaveAsPDFFile
#
$chkSaveAsPDFFile.Location = New-Object System.Drawing.Point(12, 72)
$chkSaveAsPDFFile.Name = 'checkboxSaveAsPDFFile'
$chkSaveAsPDFFile.Size = New-Object System.Drawing.Size(171, 24)
$chkSaveAsPDFFile.TabIndex = 4
$chkSaveAsPDFFile.Text = 'Save as &PDF file'
$chkSaveAsPDFFile.UseVisualStyleBackColor = $True
$ToolTips.SetToolTip($chkSaveAsPDFFile, 'Select this option if you want to save the results as a PDF file. More options are possible.')
if(-not($Global:gblDLLPathExists))
{
$chkSaveAsPDFFile.Enabled = $False
}
# chkSaveHTML
#
$chkSaveHTML.Location = New-Object System.Drawing.Point(12, 42)
$chkSaveHTML.Name = 'chkSaveHTML'
$chkSaveHTML.Size = New-Object System.Drawing.Size(171, 24)
$chkSaveHTML.TabIndex = 3
$chkSaveHTML.Text = 'Save as &HTML page'
$chkSaveHTML.UseVisualStyleBackColor = $True
$ToolTips.SetToolTip($chkSaveHTML, 'Select this option if you want to save the results as a HTML page. More options are possible.')
# chkSaveCSV
#
$chkSaveCSV.Location = New-Object System.Drawing.Point(12, 12)
$chkSaveCSV.Name = 'chkSaveCSV'
$chkSaveCSV.Size = New-Object System.Drawing.Size(171, 24)
$chkSaveCSV.TabIndex = 2
$chkSaveCSV.Text = 'Save as &CSV file'
$chkSaveCSV.UseVisualStyleBackColor = $True
$ToolTips.SetToolTip($chkSaveCSV, 'Select this option if you want to save the results as a CSV file. More options are possible.')
# btnSOExit
#
$btnSOExit.BackColor = [System.Drawing.SystemColors]::ButtonShadow
$btnSOExit.Location = New-Object System.Drawing.Point(201, 72)
$btnSOExit.Name = 'btnSOExit'
$btnSOExit.Size = New-Object System.Drawing.Size(75, 50)
$btnSOExit.TabIndex = 1
$btnSOExit.Text = '&Exit'
$btnSOExit.UseVisualStyleBackColor = $False
$btnSoExit.add_Click({SoExit})
# =============================================================================================================================================
# End forms block Save options
# =============================================================================================================================================
[void]$frmInformationAboutLoad.ShowDialog()
}