Script and AppV Repository
Script and AppV Repository
Script and AppV Repository

In some cases, it might be useful to have the Ivanti Workspace Control application building block data exported to a CSV file. Useful for further analysis, and checking for consistency. I wrote a PowerShell script to do that job for me. 
In this article, I will share the challenges I had and the solution. 

New in v0.4 is the command line option -SaveAsHTMLPage. The content will be saved as an HTML file. You can easily view it with Google Chrome, Microsoft Edge or Mozilla Firefox.

New in v0.5 is the extension of the parameter LookFor with Locations and Containers. Also, the function Get-XMLDetailsForWorkspaces has been updated to support multiple applications in one building block with no linked applications.

The most important step is to export all the application building blocks to a folder:

An Ivanti Building Block has the following layout (very simplified!):

<?xml version="1.0"?>
<!-- Workspace Control Building Block -->
<respowerfuse>
	<version>10.3.140.0</version>
	<buildingblock>
		<application required="yes">
			<appid>6276</appid>
			<guid>{AE1C49D1-20CD-4C1E-8A15-734DB701C050}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Microsoft Edge</title>
				<description>Microsoft Edge</description>
				<commandline>C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe</commandline>
				<workingdir>C:\Program Files (x86)\Microsoft\Edge\Application</workingdir>
				<parameters></parameters>
           </configuration>
        </application>
    </buildingblock>
</respowerfuse>

With PowerShell this is easy to read:

# =============================================================================================================================================
# Define the building block xml file.
# =============================================================================================================================================

$BuildingBlockDetails = [xml]@"
<?xml version="1.0"?>
<!-- Workspace Control Building Block -->
<respowerfuse>
	<version>10.3.140.0</version>
	<buildingblock>
		<application required="yes">
			<appid>6276</appid>
			<guid>{AE1C49D1-20CD-4C1E-8A15-734DB701C050}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Microsoft Edge</title>
				<description>Microsoft Edge</description>
				<commandline>C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe</commandline>
				<workingdir>C:\Program Files (x86)\Microsoft\Edge\Application</workingdir>
				<parameters></parameters>
           </configuration>
        </application>
    </buildingblock>
</respowerfuse>
"@

# =============================================================================================================================================
# Read the title and appid and write them to the host. 
# =============================================================================================================================================

$ApplicationTitle = $BuildingBlockDetails.respowerfuse.buildingblock.application.configuration.title
$ApplicationAppID = $BuildingBlockDetails.respowerfuse.buildingblock.application.appid

Write-Host "Title:  $ApplicationTitle"
Write-Host "AppID:  $ApplicationAppID"

The output looks like:

And now the challenge. An Ivanti application can have linked applications. So the settings/actions from the linked application are used. 

The same script, but with modified building block data:

# =============================================================================================================================================
# Define the building block xml file.
# =============================================================================================================================================

$BuildingBlockDetails = [xml]@"
<?xml version="1.0"?>
<!-- Workspace Control Building Block -->
<respowerfuse>
	<version>10.3.140.0</version>
	<buildingblock>
        <application required="yes">
			<appid>18</appid>
			<guid>{CACE91A7-7202-4CA2-92A3-0EB32FEB61CE}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Calculator</title>
				<description>Performs basic arithmetic tasks with an on-screen calculator.</description>
				<commandline>%SYSTEMROOT%\SYSTEM32\calc.exe</commandline>
				<workingdir>%SYSTEMROOT%\SYSTEM32</workingdir>
				<parameters></parameters>
            </configuration>
        </application>
		<application>
			<appid>6276</appid>
			<guid>{AE1C49D1-20CD-4C1E-8A15-734DB701C050}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Microsoft Edge - Application with linked action</title>
				<description>Microsoft Edge - Application with linked action</description>
				<commandline>C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe</commandline>
				<workingdir>C:\Program Files (x86)\Microsoft\Edge\Application</workingdir>
				<parameters></parameters>
           </configuration>
           <powerlaunch>
				<linked_actions>
					<description>Test</description>
					<linked_to_application>{CACE91A7-7202-4CA2-92A3-0EB32FEB61CE}</linked_to_application>
                </linked_actions>
            </powerlaunch>
        </application>
    </buildingblock>
</respowerfuse>
"@

# =============================================================================================================================================
# Read the title and appid and write them to the host. 
# =============================================================================================================================================

$ApplicationTitle = $BuildingBlockDetails.respowerfuse.buildingblock.application.configuration.title
$ApplicationAppID = $BuildingBlockDetails.respowerfuse.buildingblock.application.appid

Write-Host "Title:  $ApplicationTitle"
Write-Host "AppID:  $ApplicationAppID"

But the output looks different:

The title and appid are mixed up. It appears that the XML data respowerfuse.buildingblock.application.configuration.title and respowerfuse.buildingblock.application.appid is added together. 

The 'main' application has the following XML data added:

<respowerfuse>
   <buildingblock>
      </application>
           <powerlaunch>
		<linked_actions>
		       <description>Test</description>
			<linked_to_application>{CACE91A7-7202-4CA2-92A3-0EB32FEB61CE}</linked_to_application>
                </linked_actions>
            </powerlaunch>
        </application>
    </buildingblock>
</respowerfuse>

So only the data from the application block with linked_actions should be used. 

# =============================================================================================================================================
# Define the building block xml file.
# =============================================================================================================================================

$BuildingBlockDetails = [xml]@"
<?xml version="1.0"?>
<!-- Workspace Control Building Block -->
<respowerfuse>
	<version>10.3.140.0</version>
	<buildingblock>
        <application required="yes">
			<appid>18</appid>
			<guid>{CACE91A7-7202-4CA2-92A3-0EB32FEB61CE}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Calculator</title>
				<description>Performs basic arithmetic tasks with an on-screen calculator.</description>
				<commandline>%SYSTEMROOT%\SYSTEM32\calc.exe</commandline>
				<workingdir>%SYSTEMROOT%\SYSTEM32</workingdir>
				<parameters></parameters>
            </configuration>
        </application>
		<application>
			<appid>6276</appid>
			<guid>{AE1C49D1-20CD-4C1E-8A15-734DB701C050}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Microsoft Edge - Application with linked action</title>
				<description>Microsoft Edge - Application with linked action</description>
				<commandline>C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe</commandline>
				<workingdir>C:\Program Files (x86)\Microsoft\Edge\Application</workingdir>
				<parameters></parameters>
           </configuration>
           <powerlaunch>
				<linked_actions>
					<description>Test</description>
					<linked_to_application>{CACE91A7-7202-4CA2-92A3-0EB32FEB61CE}</linked_to_application>
                </linked_actions>
            </powerlaunch>
        </application>
    </buildingblock>
</respowerfuse>
"@

# =============================================================================================================================================
# Find the number of applications that are defined in the building block xml file. In this case there are 2 applications. 
# =============================================================================================================================================

$numApplications    = $BuildingBlockDetails.respowerfuse.buildingblock.application.Count
if(-not($numApplications))
 {
  $numApplications = 1
 }

$BuildingBlockContainsLinkedApplications = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
 {
  $BuildingBlockContainsLinkedApplications = $true
 }

Clear-Host
Write-Host "There are $numApplications applications defined in the building block XML." 

For($ApplicationCounter = 0; $ApplicationCounter -lt $numApplications; $ApplicationCounter++)
 {
  if($numApplications -eq 1)

  # =============================================================================================================================================
  # If there is one application then use $BuildingBlockDetails.respowerfuse.buildingblock.application
  # If there are more applications the use $BuildingBlockDetails.respowerfuse.buildingblock.application.Item(x)
  # =============================================================================================================================================

   {
    $ApplicationXML = $BuildingBlockDetails.respowerfuse.buildingblock.application
   }
    else
   {
    $ApplicationXML = $BuildingBlockDetails.respowerfuse.buildingblock.application.Item($ApplicationCounter)
   }
  
  # =============================================================================================================================================
  # Check if there is a linked application mentioned in this applicaton block. In that case only read the details for the linked application.
  # =============================================================================================================================================

   $ApplicationContainsLinkedActions = $false
   If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
    {
     $ApplicationContainsLinkedActions = $true
    }
  
  if($numApplications -ge 1 -and (-not $BuildingBlockContainsLinkedApplications -or $ApplicationContainsLinkedActions))
   {
    
    # =============================================================================================================================================
    # Read the details and write them to the host.
    # =============================================================================================================================================
    
    $ApplicationTitle = $ApplicationXML.configuration.title
    $ApplicationAppID = $ApplicationXML.appid
    Write-Host "Title:  $ApplicationTitle"
    Write-Host "AppID:  $ApplicationAppID"
   }
 }

And the output looks like:

And this code also works if there is only one application in the XML file defined:

# =============================================================================================================================================
# Define the building block xml file.
# =============================================================================================================================================

$BuildingBlockDetails = [xml]@"
<?xml version="1.0"?>
<!-- Workspace Control Building Block -->
<respowerfuse>
	<version>10.3.140.0</version>
	<buildingblock>
		<application required="yes">
			<appid>6276</appid>
			<guid>{AE1C49D1-20CD-4C1E-8A15-734DB701C050}</guid>
			<configuration>
				<menu>Start\Accessories</menu>
				<title>Microsoft Edge</title>
				<description>Microsoft Edge</description>
				<commandline>C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe</commandline>
				<workingdir>C:\Program Files (x86)\Microsoft\Edge\Application</workingdir>
				<parameters></parameters>
           </configuration>
        </application>
    </buildingblock>
</respowerfuse>
"@

# =============================================================================================================================================
# Find the number of applications that are defined in the building block xml file. In this case there are 2 applications. 
# =============================================================================================================================================

$numApplications    = $BuildingBlockDetails.respowerfuse.buildingblock.application.Count
if(-not($numApplications))
 {
  $numApplications = 1
 }

$BuildingBlockContainsLinkedApplications = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
 {
  $BuildingBlockContainsLinkedApplications = $true
 }

Write-Host "There are $numApplications applications defined in the building block XML." 

For($ApplicationCounter = 0; $ApplicationCounter -lt $numApplications; $ApplicationCounter++)
 {
  if($numApplications -eq 1)

  # =============================================================================================================================================
  # If there is one application then use $BuildingBlockDetails.respowerfuse.buildingblock.application
  # If there are more applications the use $BuildingBlockDetails.respowerfuse.buildingblock.application.Item(x)
  # =============================================================================================================================================

   {
    $ApplicationXML = $BuildingBlockDetails.respowerfuse.buildingblock.application
   }
    else
   {
    $ApplicationXML = $BuildingBlockDetails.respowerfuse.buildingblock.application.Item($ApplicationCounter)
   }
  
  # =============================================================================================================================================
  # Check if there is a linked application mentioned in this applicaton block. In that case only read the details for the linked application.
  # =============================================================================================================================================

   $ApplicationContainsLinkedActions = $false
   If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
    {
     $ApplicationContainsLinkedActions = $true
    }
  
  if($numApplications -ge 1 -and (-not $BuildingBlockContainsLinkedApplications -or $ApplicationContainsLinkedActions))
   {
    
    # =============================================================================================================================================
    # Read the details and write them to the host.
    # =============================================================================================================================================
    
    $ApplicationTitle = $ApplicationXML.configuration.title
    $ApplicationAppID = $ApplicationXML.appid
    Write-Host "Title:  $ApplicationTitle"
    Write-Host "AppID:  $ApplicationAppID"
   }
 }

With the following output:

In v0.5 the function Get-XMLDetailsForWorkspaces has been updated. I thought that all the containers are applied are in respowerfuse.buildingblock.workspaces.  That is not correct. The GUIDs are mentioned in respowerfuse.buildingblock.application.workspacecontrol and the mapping GUID <-> name is done in respowerfuse.buildingblock.workspaces. You can check the following example:

# =============================================================================================================================================
# Define the building block xml file.
# =============================================================================================================================================

$BuildingBlockDetails = [xml]@"
<?xml version="1.0"?>
<!-- Workspace Control Building Block -->
<respowerfuse>
	<version>10.3.140.0</version>
	<buildingblock>
		<application required="yes">
			<appid>6276</appid>
			<guid>{AE1C49D1-20CD-4C1E-8A15-734DB701C050}</guid>
			<configuration>
				<menu>Start\Exact Globe Next</menu>
				<title>Exact Globe Next (local install)</title>
				<description>Exact Globe Next</description>
				<commandline>%programfiles(x86)%\Exact Software\bin\e5shell.exe</commandline>
				<workingdir>%programfiles(x86)%\Exact Software\bin\</workingdir>
				<parameters></parameters>
           </configuration>
           <workspacecontrol>
				<workspace>{0456D5A9-0838-4FC6-AD7B-8519F03F943A}</workspace>
				<workspace>{B74EAA82-5725-4BFD-8428-85EF48C9CCF1}</workspace>
			</workspacecontrol>
        </application>
        <application>
			<appid>6382</appid>
			<guid>{A98D8558-4A16-4143-A17C-3987869A6345}</guid>
			<configuration>
				<menu>Start\Exact Globe Next</menu>
				<title>Exact Globe Next (APPV)</title>
				<description>Exact Globe Next</description>
				<commandline>APPVPACKAGEINSTALLATIONROOT%\32a5f07d-eda0-4360-83c1-50c25402da27\%APPVPACKAGECURRENTVERSION%\Root\bin\E5Shell.exe</commandline>
				<workingdir>%APPVPACKAGEINSTALLATIONROOT%\32a5f07d-eda0-4360-83c1-50c25402da27\%APPVPACKAGECURRENTVERSION%\Root\bin</workingdir>
				<parameters></parameters>
           </configuration>
           <workspacecontrol>
				<workspace>{FEAC8653-1611-4164-87E6-B64C091629A9}</workspace>
			</workspacecontrol>
        </application>
		<workspaces>
			<workspace required="yes">
				<name>Acceptation</name>
				<guid>{0456D5A9-0838-4FC6-AD7B-8519F03F943A}</guid>
				<enabled>yes</enabled>
			</workspace>
			<workspace required="yes">
				<name>Production</name>
				<guid>{B74EAA82-5725-4BFD-8428-85EF48C9CCF1}</guid>
				<enabled>yes</enabled>
			</workspace>
			<workspace required="yes">
				<name>Test AppV</name>
				<guid>{FEAC8653-1611-4164-87E6-B64C091629A9}</guid>
				<enabled>yes</enabled>
			</workspace>
		</workspaces>
    </buildingblock>
</respowerfuse>
"@

# =============================================================================================================================================
# Find the number of applications that are defined in the building block xml file. In this case there are 2 applications. 
# =============================================================================================================================================

Clear-Host

$numApplications    = $BuildingBlockDetails.respowerfuse.buildingblock.application.Count
if(-not($numApplications))
 {
  $numApplications = 1
 }

$BuildingBlockContainsLinkedApplications = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
 {
  $BuildingBlockContainsLinkedApplications = $true
 }

Write-Host "There are $numApplications applications defined in the building block XML." 

For($ApplicationCounter = 0; $ApplicationCounter -lt $numApplications; $ApplicationCounter++)
 {
  if($numApplications -eq 1)

  # =============================================================================================================================================
  # If there is one application then use $BuildingBlockDetails.respowerfuse.buildingblock.application
  # If there are more applications the use $BuildingBlockDetails.respowerfuse.buildingblock.application.Item(x)
  # =============================================================================================================================================

   {
    $ApplicationXML = $BuildingBlockDetails.respowerfuse.buildingblock.application
   }
    else
   {
    $ApplicationXML = $BuildingBlockDetails.respowerfuse.buildingblock.application.Item($ApplicationCounter)
   }
  
  # =============================================================================================================================================
  # Check if there is a linked application mentioned in this applicaton block. In that case only read the details for the linked application.
  # =============================================================================================================================================

     $ApplicationContainsLinkedActions = $false
     If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
      {
       $ApplicationContainsLinkedActions = $true
      }
  
  if($numApplications -ge 1 -and (-not $BuildingBlockContainsLinkedApplications -or $ApplicationContainsLinkedActions))
   {

    # =============================================================================================================================================
    # Read the details and write them to the host.
    # =============================================================================================================================================
    
    $tmpCounter = $ApplicationCounter + 1

    $ApplicationTitle = $ApplicationXML.configuration.title
    $ApplicationAppID = $ApplicationXML.appid

    Write-Host "Title:               $ApplicationTitle"
    Write-Host "AppID:               $ApplicationAppID"

    $XMLPath_WorkspaceControl = "respowerfuse.buildingblock.application[$tmpCounter].workspacecontrol"
    $XMLPath_Workspaces       = "respowerfuse.buildingblock.workspaces"
        
    $XMLPath1 = $XMLPath_WorkspaceControl.Replace(".","/")
    $XMLPath2 = $XMLPath_Workspaces.Replace(".","/")

    $WorkspaceGUIDs = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath1/workspace").Node."#text"

    $Workspaces     = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath2/workspace").Node

    # =============================================================================================================================================
    # The workspaces GUID
    # respowerfuse.buildingblock.application.workspacecontrol
    # The name that belongs to the GUID is stored in
    # respowerfuse.buildingblock.workspaces
    # =============================================================================================================================================
    
    Foreach ($WorkspaceGUID in $WorkspaceGUIDs)
     {
      ForEach ($Workspace in $Workspaces)
       {
        if($WorkspaceGUID -eq $Workspace.guid -and ($workspace.enabled -eq "yes"))
         {
          Write-Host "Workspace container: $($Workspace | Select-Object -ExpandProperty 'name')"
         }
       }
     }
     Write-Host "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
   }
 }

With the following output:

 

You can view some background information on YouTube:

The application ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1 has the following parameters:

  • Directory
    The directory with all the exported Ivanti building blocks.

  • IncludeSubFolders
    Include the subfolders as well.

  • DetailedLogging
    Enables detailed logging to a text file. 

  • NoProgressBar
    There is no progress bar while the script is running. It is running in a silent mode.
  • LogPath
    The location where the CSV file is written to. Default is the same location where the script is in. 

  • LookFor
    • InAppID
      Look for specific AppID's. Separate multiple entries with a comma.
    • InTitle
      Look for specific text in the title. Separate multiple entries with a comma.
    • InCommandLine
      Look for a specific command in the command line. Separate multiple entries with a comma.
    • InParameter
      Look for specific text in the parameter field.
    • InFileTypes
      Search for a specific filetype (file association). Separate multiple entries with a comma.  
    • InGroupOrUser
      Look for specific text in the user group name or user name. Separate multiple entries with a comma.
    • InLocations
      Look for specific locations (or PowerZones). Separate multiple entries with a comma.
    • InContainers
      Look for specific containers (or workspaces). Separate multiple entries with a comma.
    • CopyFiles
      • To
        Works with both InCommandLine and InTitle. Copy the building block xml file to the given location. 
  • Summary
    Only a limited set of columns is shown. 

  • SaveAsHTMLPage
    The results are saved as an HTML file. 

  • Delimiter
    If saved as a CSV file, this is used as a delimiter character. Default character is ;.

 

The output of the command Get-Help ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1 -Detailed

NAME
    C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1
    
SYNOPSIS
    Finds the Start Menu Items in Ivanti Workspace Control Building Blocks and export them to a CSV file.
    
    
SYNTAX
    C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1 [-Directory <String>] [-LogPath <String>] 
    [-IncludeSubFolders] [-DetailedLogging] [-NoProgressBar] [-LookFor] [-InAppID <String[]>] [-InTitle <String[]>] 
    [-InCommandLine <String[]>] [-InParameter <String[]>] [-InFileTypes <String[]>] [-InGroupOrUser <String[]>] 
    [-InLocations <String[]>] [-InContainers <String[]>] [-CopyFiles] [-Summary] [-SaveAsHTMLPage] [-To <String>] 
    [-Delimiter <String>] [<CommonParameters>]
    
    
DESCRIPTION
    An Ivanti Building Block contains all kind of information about a Start Menu item. This script exports the most 
    used details to a CSV file.
    

PARAMETERS
    -Directory <String>
        
    -LogPath <String>
        
    -IncludeSubFolders [<SwitchParameter>]
        
    -DetailedLogging [<SwitchParameter>]
        
    -NoProgressBar [<SwitchParameter>]
        
    -LookFor [<SwitchParameter>]
        
    -InAppID <String[]>
        
    -InTitle <String[]>
        
    -InCommandLine <String[]>
        
    -InParameter <String[]>
        
    -InFileTypes <String[]>
        
    -InGroupOrUser <String[]>
        
    -InLocations <String[]>
        
    -InContainers <String[]>
        
    -CopyFiles [<SwitchParameter>]
        
    -Summary [<SwitchParameter>]
        
    -SaveAsHTMLPage [<SwitchParameter>]
        
    -To <String>
        
    -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:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles
    
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles
    
    
    
    
    -------------------------- EXAMPLE 2 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles. Only show a limited 
    set of columns.
    
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -Summary
    
    
    
    
    -------------------------- EXAMPLE 3 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and its subfolders
    
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders
    
    
    
    
    -------------------------- EXAMPLE 4 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp
    
    
    
    
    -------------------------- EXAMPLE 5 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Do not show a progress bar.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -NoProgressBar
    
    
    
    
    -------------------------- EXAMPLE 6 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp.
    
    The delimiter character is ','
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -Delimiter ","
    
    
    
    
    -------------------------- EXAMPLE 7 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Check if the executable excel.exe or winword.exe is used in the commandline
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InCommandLine excel.exe,winword.exe
    
    
    
    
    -------------------------- EXAMPLE 8 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Check if Microsoft is used in the title.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InTitle Office
    
    
    
    
    -------------------------- EXAMPLE 9 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Check if Microsoft is used in the title. Use detailed logging to a log file.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InTitle Office -DetailedLogging
    
    
    
    
    -------------------------- EXAMPLE 10 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp for AppID 4321.
    
    Use detailed logging to a log file.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InAppID 4321 -DetailedLogging
    
    
    
    
    -------------------------- EXAMPLE 11 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Check if the group name 'Appl_Visio' is used.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InGroupName Appl_Visio
    
    
    
    
    -------------------------- EXAMPLE 12 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Check if one of the file types cmd, bat, jnlp or jar is used.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -InFileTypes cmd,bat,jnlp,jar
    
    
    
    
    -------------------------- EXAMPLE 13 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line to c:\tmp-internet
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -CopyFiles -To c:\tmp-internet
    
    
    
    
    -------------------------- EXAMPLE 14 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line to c:\tmp-internet
    Only show a limited set of columns and save it as a HTML page.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -CopyFiles -To c:\tmp-internet -Summary 
    -SaveAsHTMLPage
    
    
    
    
    -------------------------- EXAMPLE 15 --------------------------
    
    PS C:\>Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result 
    file in c:\tmp
    
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line and as parameter 
    www.google.com to c:\tmp-internet
    Only show a limited set of columns and save it as a HTML page.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders 
    -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -InParameter www.google.com -CopyFiles -To 
    c:\tmp-internet -Summary -SaveAsHTMLPage
    
    
    
    
REMARKS
    To see the examples, type: "get-help C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1 -examples".
    For more information, type: "get-help C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1 -detailed".
    For technical information, type: "get-help C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1 -full".

 

And the script:

<#
.SYNOPSIS
    Finds the Start Menu Items in Ivanti Workspace Control Building Blocks and export them to a CSV file.

.DESCRIPTION
    An Ivanti Building Block contains all kind of information about a Start Menu item. This script exports the most used details to a CSV file. 

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles. Only show a limited set of columns.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -Summary


.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and its subfolders
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Do not show a progress bar.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -NoProgressBar

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp.
    The delimiter character is ','
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -Delimiter ","

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Check if the executable excel.exe or winword.exe is used in the commandline
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InCommandLine excel.exe,winword.exe

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Check if Microsoft is used in the title.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InTitle Office

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Check if Microsoft is used in the title. Use detailed logging to a log file.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InTitle Office -DetailedLogging

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp for AppID 4321. 
    Use detailed logging to a log file.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InAppID 4321 -DetailedLogging

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Check if the group name 'Appl_Visio' is used.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InGroupName Appl_Visio

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Check if one of the file types cmd, bat, jnlp or jar is used.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -InFileTypes cmd,bat,jnlp,jar

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line to c:\tmp-internet
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -CopyFiles -To c:\tmp-internet

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line to c:\tmp-internet
    Only show a limited set of columns and save it as a HTML page.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -CopyFiles -To c:\tmp-internet -Summary -SaveAsHTMLPage

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and store the result file in c:\tmp
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line and as parameter www.google.com to c:\tmp-internet
    Only show a limited set of columns and save it as a HTML page.
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v10.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -InParameter www.google.com -CopyFiles -To c:\tmp-internet -Summary -SaveAsHTMLPage

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

v0.1:
   * Initial version.

v0.2:
   * Added parameters:
       - detailedlogging
       - lookfor
           - InTitle
           - incommandline
           - copyfiles
              - to

v0.3:
   * LookFor has been extended with 'GroupOrUser'.

v0.4:
   * Save as an HTML table

v0.5:
   * LookFor has been extended with 'Locations' and 'Containers'
   * Summary parameter has been introduced. Only the following columns are displayed
       - XML File Name
       - Start Menu location
       - Properties - General - ID
       - Properties - General - Title
       - Properties - General - Description
       - Properties - Settings - Application is enabled
       - Access Control - Identy - Type
       - Access Control - Identy - Selected users and/or groups
       - Access Control - Location and devices
       - Access Control - Workspace containers
       - Remark
   * The function Get-XMLDetailsForWorkspaces has been updated to support multiple applications in one building block with no linked applications. 

v0.6:
   * In the function FindInfoInBuildingBlock was an error. The combination with the linked items was not correct. That has been solved.

v0.7:
   * LookFor has been extended with 'InParameter' and 'InAppID'
   * Introduction NoProgressBar switch.
   * Some coding improvements.
   * Corrected some type errors.

v1.0 (First final version):
   * The Parameter 'GroupOrUser' has been replaced by 'InGroupOrUser'. 
   * The Parameter 'Locations' has been replaced by 'InLocations'. 
   * The Parameter 'Containers' has been replaced by 'InContainers'. 
   * Filetypes (file Associations) has been added to the table as a column.
   * LookFor has been extended with 'InFileTypes' for the file associations.
   * If the summary parameter is used, the following additional column is displayed:
       - Properties - FileTypes

#>

[CmdletBinding(DefaultParameterSetName = 'Default')]

Param
  (
   [Parameter(HelpMessage='Specify the directory that contains all the exported building blocks.')]
   [Parameter(Mandatory=$False,  ParameterSetName='Default')]
   [String]   $Directory = "",

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

   [Parameter(HelpMessage='Include subfolders for the directory that contains all the exported building blocks.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $IncludeSubFolders,

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

   [Parameter(HelpMessage='Disable the progress bar.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $NoProgressBar,

   [Parameter(HelpMessage='Enable lookfor.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $LookFor,

   [Parameter(HelpMessage='Specify each AppID to search for, may be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InAppID,

   [Parameter(HelpMessage='Specify the items to search for in the title, may be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InTitle,

   [Parameter(HelpMessage='Specify the items to search for in the command line, may be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InCommandLine,

   [Parameter(HelpMessage='Specify the items to search for in the parameter line, may be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InParameter,

   [Parameter(HelpMessage='Specify the items to search for in the file types (file associations), may be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InFileTypes,

   [Parameter(HelpMessage='Specify the groups or users to search for. May be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InGroupOrUser,

   [Parameter(HelpMessage='Specify the Locations and Devices to search for. May be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InLocations,

   [Parameter(HelpMessage='Specify the Workspace Containers to search for. May be seperated by a comma.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String[]] $InContainers,

   [Parameter(HelpMessage='Copy the files that are found with the LookFor parameter to a new location.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $CopyFiles,

   [Parameter(HelpMessage='Only display a limited set of columns.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $Summary,

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

   [Parameter(HelpMessage='The location where the files have to be copied to.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [String]   $To,

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

  )

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

  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:DetailedLogging)
      {
       $Timestamp = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
       Add-Content $Global:LogFile -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 log
    information.

    #>

    Param
     (
      [String]  $XMLFileName                       = "",
      [Int]     $NumberOfApplications              = -1,
      [String]  $StartMenu                         = "",
      [String]  $appid                             = "",
      [String]  $Title                             = "",
      [String]  $Description                       = "",
      [String]  $Commandline                       = "",
      [String]  $Workingdir                        = "",
      [String]  $Parameters                        = "",
      [String]  $appv5packagemode                  = "",
      [String]  $appv5packagefile                  = "",
      [String]  $appv5deploymentconfigurationfile  = "",
      [String]  $appv5userconfigurationfile        = "",
      [String]  $appv5packageupdate                = "",
      [String]  $appv5packageroot                  = "",
      [String]  $administrativenote                = "",
      [String]  $unmanagedshortcuts                = "",
      [String]  $createmenushortcut                = "",
      [String]  $allowmultipleshortcuts            = "",
      [String]  $Enabled                           = "",
      [String]  $hidefrommenu                      = "",
      [String]  $checkappexists                    = "",
      [String]  $checkfileexists                   = "",
      [string]  $FileTypesInTable                  = "",
      [String]  $accesstype                        = "",
      [String]  $GroupList                         = "",
      [String]  $PowerZones                        = "",
      [String]  $Workspaces                        = "",
      [String]  $LearningMode                      = "",
      [String]  $AppGuard                          = "",
      [String]  $ApplicationContainsLinkedActions  = "",
      [String]  $Remark                            = ""
     )

    $Record  = [ordered] @{"XML File Name"                                                           = "";
                           "Number of applications"                                                  = "";
                           "Start Menu location"                                                     = "";
                           "Properties - General - ID"                                               = "";
                           "Properties - General - Title"                                            = "";
                           "Properties - General - Description"                                      = "";
                           "Properties - General - Commandline"                                      = "";
                           "Properties - General - Working directory"                                = "";
                           "Properties - General - Parameters"                                       = "";
                           "Properties - General - AppV5 Package delivery mode"                      = "";
                           "Properties - General - AppV5 Package file"                               = "";
                           "Properties - General - AppV5 Deployment configuration file"              = "";
                           "Properties - General - AppV5 User configuration file"                    = "";
                           "Properties - General - AppV5 Always use latest version"                  = "";
                           "Properties - General - AppV5 Package root folder"                        = "";
                           "Properties - General - Administrative note"                              = "";
                           "Properties - Shortcuts - Replace existing unmanaged shortcuts"           = "";
                           "Properties - Shortcuts - Create Start Menu shortcut"                     = "";
                           "Properties - Shortcuts - Allow multiple shortcuts in Start Menu"         = "";
                           "Properties - Settings - Application is enabled"                          = "";
                           "Properties - Settings - Hide application"                                = "";
                           "Properties - Settings - Hide application if executable was not found"    = "";
                           "Properties - Settings - Hide application if file was not found"          = "";
                           "Properties - FileTypes"                                                  = "";
                           "Access Control - Identy - Type"                                          = "";
                           "Access Control - Identy - Selected users and/or groups"                  = "";
                           "Access Control - Location and devices"                                   = "";
                           "Access Control - Workspace containers"                                   = "";
                           "Security - Authorized Files - Run this application in learning mode"     = "";
                           "Security - Authorized Files - Authorized file"                           = "";
                           "Configuration - Actions - At application start contains linked actions"  = "";
                           "Remark"                                                                  = ""
                           }
                               
    $Record."XML File Name"                                                          = $XMLFileName
    $Record."Number of applications"                                                 = $NumberOfApplications
    $Record."Start Menu location"                                                    = $StartMenu
    $Record."Properties - General - ID"                                              = $appid
    $Record."Properties - General - Title"                                           = $Title
    $Record."Properties - General - Description"                                     = $Description
    $Record."Properties - General - Commandline"                                     = $Commandline
    $Record."Properties - General - Working directory"                               = $Workingdir
    $Record."Properties - General - Parameters"                                      = $Parameters
    $Record."Properties - General - AppV5 Package delivery mode"                     = $appv5packagemode
    $Record."Properties - General - AppV5 Package file"                              = $appv5packagefile
    $Record."Properties - General - AppV5 Deployment configuration file"             = $appv5deploymentconfigurationfile
    $Record."Properties - General - AppV5 User configuration file"                   = $appv5userconfigurationfile
    $Record."Properties - General - AppV5 Always use latest version"                 = $appv5packageupdate
    $Record."Properties - General - AppV5 Package root folder"                       = $appv5packageroot
    $Record."Properties - General - Administrative note"                             = $administrativenote
    $Record."Properties - Shortcuts - Replace existing unmanaged shortcuts"          = $unmanagedshortcuts
    $Record."Properties - Shortcuts - Create Start Menu shortcut"                    = $createmenushortcut
    $Record."Properties - Shortcuts - Allow multiple shortcuts in Start Menu"        = $allowmultipleshortcuts
    $Record."Properties - Settings - Application is enabled"                         = $Enabled
    $Record."Properties - Settings - Hide application"                               = $hidefrommenu
    $Record."Properties - Settings - Hide application if executable was not found"   = $checkappexists
    $Record."Properties - FileTypes"                                                 = $FileTypesInTable
    $Record."Access Control - Identy - Type"                                         = $accesstype
    $Record."Access Control - Identy - Selected users and/or groups"                 = $GroupList
    $Record."Access Control - Location and devices"                                  = $PowerZones
    $Record."Access Control - Workspace containers"                                  = $Workspaces
    $Record."Configuration - Actions - At application start contains linked actions" = $ApplicationContainsLinkedActions
    $Record."Security - Authorized Files - Run this application in learning mode"    = $LearningMode
    $Record."Security - Authorized Files - Authorized file"                          = $AppGuard
    $Record."Remark"                                                                 = $Remark

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

    Add-EntryToLogFile -Entry  "       XML File Name:                                                           $XMLFileName"
    Add-EntryToLogFile -Entry  "       Start Menu location:                                                     $StartMenu"
    Add-EntryToLogFile -Entry  "       Number of applications                                                   $NumberOfApplications"
    Add-EntryToLogFile -Entry  "       Properties - General - ID:                                               $appid"
    Add-EntryToLogFile -Entry  "       Properties - General - Title:                                            $Title"
    Add-EntryToLogFile -Entry  "       Properties - General - Description:                                      $Description"
    Add-EntryToLogFile -Entry  "       Properties - General - Commandline:                                      $Commandline"
    Add-EntryToLogFile -Entry  "       Properties - General - Working directory:                                $Workingdir"                      
    Add-EntryToLogFile -Entry  "       Properties - General - Parameters:                                       $Parameters"
    Add-EntryToLogFile -Entry  "       Properties - General - AppV5 Package delivery mode:                      $appv5packagemode"
    Add-EntryToLogFile -Entry  "       Properties - General - AppV5 Package file:                               $appv5packagefile"   
    Add-EntryToLogFile -Entry  "       Properties - General - AppV5 Deployment configuration file:              $appv5deploymentconfigurationfile"            
    Add-EntryToLogFile -Entry  "       Properties - General - AppV5 User configuration file:                    $appv5userconfigurationfile"                  
    Add-EntryToLogFile -Entry  "       Properties - General - AppV5 Always use latest version:                  $appv5packageupdate"
    Add-EntryToLogFile -Entry  "       Properties - General - AppV5 Package root folder:                        $appv5packageroot"                       
    Add-EntryToLogFile -Entry  "       Properties - General - Administrative note:                              $administrativenote"
    Add-EntryToLogFile -Entry  "       Properties - Shortcuts - Replace existing unmanaged shortcuts:           $unmanagedshortcuts"           
    Add-EntryToLogFile -Entry  "       Properties - Shortcuts - Create Start Menu shortcut:                     $createmenushortcut"
    Add-EntryToLogFile -Entry  "       Properties - Shortcuts - Allow multiple shortcuts in Start Menu:         $allowmultipleshortcuts"       
    Add-EntryToLogFile -Entry  "       Properties - Settings - Application is enabled:                          $Enabled"                         
    Add-EntryToLogFile -Entry  "       Properties - Settings - Hide application:                                $hidefrommenu"
    Add-EntryToLogFile -Entry  "       Properties - Settings - Hide application if executable was not found:    $checkappexists"   
    Add-EntryToLogFile -Entry  "       Properties - Settings - Hide application if file was not found:          $checkfileexists"
    Add-EntryToLogFile -Entry  "       Properties - FileTypes:                                                  $FileTypesInTable"
    Add-EntryToLogFile -Entry  "       Access Control - Identy - Type                                           $accesstype"
    Add-EntryToLogFile -Entry  "       Access Control - Identy - Selected users and/or groups:                  $GroupList"
    Add-EntryToLogFile -Entry  "       Access Control - Location and devices:                                   $PowerZones"                                   
    Add-EntryToLogFile -Entry  "       Access Control - Workspace containers:                                   $Workspaces"
    Add-EntryToLogFile -Entry  "       Configuration - Actions - At application start contains linked actions:  $ApplicationContainsLinkedActions"
    Add-EntryToLogFile -Entry  "       Security - Authorized Files - Run this application in learning mode:     $LearningMode"
    Add-EntryToLogFile -Entry  "       Security - Authorized Files - Authorized file:                           $AppGuard"
    Add-EntryToLogFile -Entry  "       Remark:                                                                  $Remark"
    Add-EntryToLogFile -Entry  ""
    Add-EntryToLogFile -Entry  "###############################################################################################################`n"
   }

  Function CheckXMLFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       06-September-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     CheckXMLFile
    =============================================================================================================================================
    .SYNOPSIS

    This function checks if the xml file is valid.

    #>

    param
     (
      [String]$XMLFile
     )

     $xml = New-Object System.Xml.XmlDocument

     Try
      {
       $xml.Load((Get-ChildItem -Path $XMLFile).FullName)
       Add-EntryToLogFile -Entry "------- The file $XMLFile is valid."
       Return $True
      }
       Catch
      {
       Add-EntryToLogFile -Entry "------- The file $XMLFile is not valid."
       Return $False
      }
   }

  Function Export-CSVOrHTMLFileWithResults
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       06-September-2018
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Export-CSVOrHTMLFileWithResults
    =============================================================================================================================================
    .SYNOPSIS

    This function writes the logfile content to a CSV file.

    #>

    If($Global:arrTable.Count -gt 0)
     {
      If($Global:Summary)
       {
        $Global:arrTable = $Global:arrTable | Select-Object -Property "XML File Name","Start Menu location","Properties - General - ID","Properties - General - Title","Properties - General - Description","Properties - General - Commandline","Properties - General - Parameters","Properties - Settings - Application is enabled","Properties - FileTypes","Access Control - Identy - Type","Access Control - Identy - Selected users and/or groups","Access Control - Location and devices","Access Control - Workspace containers","Remark"
       }
      
      $Global:arrTable | Select-Object | Sort-Object -Property "Start Menu location","Properties - General - Title","Properties - General - ID" | Export-Csv $CSVOrHTMLFileWithResults -NoTypeInformation -Delimiter $Global:Delimiter
      Add-EntryToLogFile -Entry ">> Export-CSVOrHTMLFileWithResults: The file '$CSVOrHTMLFileWithResults' has been written." 
     } 
      else
     {
      $ErrorMessage = "Something went wrong while writing the logfile '$CSVOrHTMLFileWithResults'. Maybe nothing to report..."
      Add-EntryToLogFile -Entry "[Error]: $ErrorMessage"
      Write-Error $ErrorMessage -Category CloseError 
     } 
   }

  Function Get-XMLDetailsForAccessInfo
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       26 April 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-XMLDetailsForAccessInfo
    =============================================================================================================================================
    .SYNOPSIS

    This function returns who has rights to use this application:
     - The users and groups
     - The application manager(s).
    #>
   
    Param
      (
       [xml]    $BuildingBlockDetails,
       [string] $XMLPath,
       [string] $accessmode,
       [string] $accesstype
      )
       
       $XMLPath = $XMLPath.Replace(".","/")
       $Return  = @()

     # =============================================================================================================================================
     # Users and groups
     # =============================================================================================================================================
       
       if ($accesstype -eq "group")
       
        {
         
        # =============================================================================================================================================
        # The users and groups are stored in 
        # respowerfuse.buildingblock.application.accesscontrol.grouplist.group
        # =============================================================================================================================================
         
         $GroupDetails  = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath/grouplist/group").Node
                  
         if($GroupDetails)
          {
           Add-EntryToLogFile -Entry " Group Details:"
           forEach ($GroupDetail in $GroupDetails)
            {
             if(-not($Return))
              {
               $Type = $GroupDetail | Select-Object -ExpandProperty 'type' -ErrorAction SilentlyContinue
               Add-EntryToLogFile -Entry "  -> Type:  $Type"

               $Name = $GroupDetail | Select-Object -ExpandProperty '#text'
               Add-EntryToLogFile -Entry "  -> Name:  $Name"
               $Return = "$Name   ($($Type))"
              }
               else
              {
               $Type = $GroupDetail | Select-Object -ExpandProperty 'type' -ErrorAction SilentlyContinue
               Add-EntryToLogFile -Entry "  -> Type:  $Type"

               $Name = $GroupDetail | Select-Object -ExpandProperty '#text'
               Add-EntryToLogFile -Entry "  -> Name:  $Name"
               $Return += "`n$($accessmode) $($Name)   ($($Type))"
             }
            }
          
           $NotGroupDetails  = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath/notgrouplist/group")
           if($NotGroupDetails)
            {
             $NotGroupDetails = ($NotGroupDetails).Node
             Add-EntryToLogFile -Entry " Not Group Details:"
             forEach ($NotGroupDetail in $NotGroupDetails)
              {
               $Type = $NotGroupDetail | Select-Object -ExpandProperty 'type'
               Add-EntryToLogFile -Entry "  -> Type:  $Type" 
               $Name = $NotGroupDetail | Select-Object -ExpandProperty '#text'
               Add-EntryToLogFile -Entry "  -> Name:  $Name"
               $Return += "`n    $($accessmode) NOT IN $($Name)   ($($Type))"
              }
            }
          }
       }

     # =============================================================================================================================================
     # Controlled by application managers.
     # =============================================================================================================================================

       elseif($accesstype -eq "delegated")
        {
        
       # =============================================================================================================================================
       # The controlled by application manager(s) are stored in 
       # respowerfuse.buildingblock.application.accesscontrol.appmanlist.appmanglobal
       # =============================================================================================================================================
               
         $AppplicationManagers = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath/appmanlist/appmanglobal").Node
         
         Add-EntryToLogFile -Entry " Group Details:" 

         forEach ($AppplicationManager in $AppplicationManagers)
          {
           if(-not($Return))
            {
             $Name = $AppplicationManager | Select-Object -ExpandProperty '#text'
             Add-EntryToLogFile -Entry "  -> Name:  $Name"
             $Return = "$Name"
            }
             else
            {
             $Name = $AppplicationManager | Select-Object -ExpandProperty '#text'
             Add-EntryToLogFile -Entry "  -> Name:  $Name"
             $Return += "`n$($accessmode) $($Name)"
           }
          }
        }

     Add-EntryToLogFile -Entry "(Function: Get-XMLDetailsForAccessInfo) The return value for $XMLPath is $Return."

     Return $Return
   }

  Function Get-XMLDetailsForAuthorizedFiles
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       26 April 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-XMLDetailsForAuthorizedFiles
    =============================================================================================================================================
    .SYNOPSIS

    This function returns the authorized files.
    #>
   
    Param
      (
       [xml]    $BuildingBlockDetails,
       [string] $XMLPath,
       [string] $CommandLine
      )
       
     Add-EntryToLogFile -Entry "--> In function: Get-XMLDetailsForAuthorizedFiles"

     $XMLPath = $XMLPath.Replace(".","/")
     $Return = @()
     
   # =============================================================================================================================================
   # At least the application executable is an authorized file.
   # =============================================================================================================================================
   
     if($CommandLine)
      {
       $Return += "$CommandLine    (Process: *)"
      }

   # =============================================================================================================================================
   # The authorized files are stored in 
   # respowerfuse.buildingblock.application.appguard.authorizedfiles.authfile
   # =============================================================================================================================================
   
     $AuthFilesDetails = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath").Node
            
     forEach ($AuthFilesDetail in $AuthFilesDetails)
      {
       $enabled = $AuthFilesDetail | Select-Object -ExpandProperty 'enabled'
       if($enabled -eq "yes")
        {
         $authorizedfile = $AuthFilesDetail | Select-Object -ExpandProperty 'authorizedfile'
         Add-EntryToLogFile -Entry "  -> authorizedfile:  $authorizedfile"
         $process        = $AuthFilesDetail | Select-Object -ExpandProperty 'process'
         Add-EntryToLogFile -Entry "  -> process:         $process"
         $Return += "`n$authorizedfile   (Process: $($process))"
        }
      }

     Add-EntryToLogFile -Entry "(Function: Get-XMLDetailsForAuthorizedFiles) The return value for $XMLPath is $Return." 

     Return $Return
   }

  Function Get-XMLDetailsForWorkspaces
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       26 April 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-XMLDetailsForWorkspaces
    =============================================================================================================================================
    .SYNOPSIS

    This function returns the authorized files.
    #>
   
    Param
      (
       [xml]    $BuildingBlockDetails,
       [string] $XMLPath_WorkspaceControl,
       [string] $XMLPath_Workspaces
      )
       
     Add-EntryToLogFile -Entry "--> In function: Get-XMLDetailsForWorkspaces"

     $XMLPath1 = $XMLPath_WorkspaceControl.Replace(".","/")
     $XMLPath2 = $XMLPath_Workspaces.Replace(".","/")
     $Return  = ""

   # =============================================================================================================================================
   # The workspaces GUID
   # respowerfuse.buildingblock.application.workspacecontrol
   # The name that belongs to the GUID is stored in
   # respowerfuse.buildingblock.workspaces
   # =============================================================================================================================================
 
     $WorkspaceGUIDs = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath1/workspace").Node."#text"
     $Workspaces     = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath2/workspace").Node
     Foreach ($WorkspaceGUID in $WorkspaceGUIDs)
      {
       ForEach ($Workspace in $Workspaces)
        {
         if($WorkspaceGUID -eq $Workspace.guid -and ($workspace.enabled -eq "yes"))
          {
           if(-not($Return))
            {
             $authorizedWorkspace = $Workspace | Select-Object -ExpandProperty 'name'
             Add-EntryToLogFile -Entry "  -> authorized workspace:  $authorizedWorkspace" 
             $Return = "$authorizedWorkspace"
            }
             else
            {
             $authorizedWorkspace = $Workspace | Select-Object -ExpandProperty 'name'
             Add-EntryToLogFile -Entry "  -> authorized workspace:  $authorizedWorkspace" 
             $Return += "`n$authorizedWorkspace"
            }

          }
        }       
      
      }

     Add-EntryToLogFile -Entry "(Function: Get-XMLDetailsForWorkspaces) The return value for $XMLPath is $Return." 
     Return $Return
   }

  Function Get-XMLDetailsForPowerZones
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       26 April 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-XMLDetailsForPowerZones
    =============================================================================================================================================
    .SYNOPSIS

    This function returns the authorized files.
    #>
   
    Param
      (
       [xml]    $BuildingBlockDetails,
       [string] $XMLPath
      )
       
     Add-EntryToLogFile -Entry "--> In function: Get-XMLDetailsForPowerZones"
     $XMLPath = $XMLPath.Replace(".","/")
     $Return = ""

   # =============================================================================================================================================
   # The powerzones are stored in 
   # respowerfuse.buildingblock.application.powerzones.powerzone
   # =============================================================================================================================================

     $PowerZones = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath").Node."#text"
       
     forEach ($PowerZone in $PowerZones)
      {
       if(-not($Return))
        {
         Add-EntryToLogFile -Entry "  -> authorized powerzone:  $PowerZone" 
         $Return = $PowerZone
        }
         else
        {
         Add-EntryToLogFile -Entry "  -> authorized powerzone:  $PowerZone" 
         $Return += "`n$PowerZone"
       }
      }

     Add-EntryToLogFile -Entry "(Function: Get-XMLDetailsForPowerZones) The return value for $XMLPath is $Return."
     Return $Return
   }

  Function Get-XMLDetailsForFileTypes
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       18 August 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-XMLDetailsForFileTypes
    =============================================================================================================================================
    .SYNOPSIS

    This function finds all the File Associations (File Types) in a building block.
    #>
   
    Param
      (
       [xml]    $BuildingBlockDetails,
       [string] $XMLPath
      )

     $XMLPath = $XMLPath.Replace(".","/")
     $Return  = @()

     $Associations  = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath").Node
     Add-EntryToLogFile -Entry "--> In function: Get-XMLDetailsForFileTypes"
     
     if ($Associations)
      {
       ForEach ($Association in $Associations)
        {
         if (($Association.Enabled -eq "yes") -and ($($Return -Split "`n") -notcontains $($Association.Extension)))        
          {
           if(-not($Return))
            {
             $Return = $($Association.Extension)
            }
             else
            {
             $Return += "`n$($Association.Extension)"
            }
          }
        }
      }
     Add-EntryToLogFile -Entry "(Function: Get-XMLDetailsForFileTypes) The return value for $XMLPath is $Return."
     Return $Return
   }

  Function Find-InArry
   {
    
    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       17-October-2018 Updated on 03-Aug-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Find-InArry
    =============================================================================================================================================
    .SYNOPSIS

    This function checks two arrays for content. 
    Based on https://stackoverflow.com/questions/25384346/find-common-items-in-two-powershell-arrays

    #>

    Param
     (
      [String[]] $SearchInArray,
      [String[]] $LookForInArray,
      [string]   $Suffix = "",
      [Switch]   $ExactMatch 
     )

    $tmpArray = @()
    
    ForEach ($objSearchInArray in $SearchInArray)
     {
      ForEach ($objLookForInArray in $LookForInArray)
       {
        $Condition = "*$($objLookForInArray)*"
        if($ExactMatch)
         {
          $Condition = "$($objLookForInArray)"
         }
        if($objSearchInArray -like "$Condition")
         {
          $tmpArray += $objLookForInArray             
          if(-not($Suffix))
           {
            $Entry    = "$objLookForInArray has been found in $objSearchInArray."
           }
            else
           {
            $Entry    = "$Suffix $objLookForInArray has been found in $objSearchInArray."
           }
          Add-EntryToLogFile -Entry $Entry
         }
       }
     } 
    Return $tmpArray
   }

  Function FindInfoInBuildingBlock
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       26 April 2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     FindInfoInBuildingBlock
    =============================================================================================================================================
    .SYNOPSIS

    This function finds all the information in the building block.
    #>

    Param
     (
      [xml]    $BuildingBlockDetails,
      [String] $Filename
     )

     $Commandline                         = ""
     $numApplications                     = $BuildingBlockDetails.respowerfuse.buildingblock.application.Count
     if(-not($numApplications))
      {
       $numApplications = 1
      }
     
     # =============================================================================================================================================
     # It is checked if there are somewhere linked actions in the building block. If so the variable $BuildingBlockContainsLinkedApplications is set
     # to true. Then each application is checked for linked actions. If a linked action is found, it is processed.
     # If there are no linked actions anywhere then all the applications are processed.
     # =============================================================================================================================================
         
     $BuildingBlockContainsLinkedApplications = $false
     if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
      {
       $BuildingBlockContainsLinkedApplications = $true
      }
           
     for($ApplicationCounter = 0; $ApplicationCounter -lt $numApplications; $ApplicationCounter++)
      {
       if($numApplications -eq 1)
        {
         $ApplicationXML                     = $BuildingBlockDetails.respowerfuse.buildingblock.application
        }
         else
        {
         $ApplicationXML                     = $BuildingBlockDetails.respowerfuse.buildingblock.application.Item($ApplicationCounter)
        }
       
     $ApplicationContainsLinkedActions = $false
     If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
      {
       $ApplicationContainsLinkedActions = $true
      }

     Add-EntryToLogFile -Entry "Number of applications:                      $numApplications"
     Add-EntryToLogFile -Entry "Building block contains linked applications: $BuildingBlockContainsLinkedApplications"
     Add-EntryToLogFile -Entry "Application contains linked applications:    $ApplicationContainsLinkedActions"
 
     if($numApplications -ge 1 -and (-not $BuildingBlockContainsLinkedApplications -or $ApplicationContainsLinkedActions))
      {         
       Add-EntryToLogFile -Entry "The following requirements are met:"
       if($numApplications -ge 1 -and -not $BuildingBlockContainsLinkedApplications)
        {
         Add-EntryToLogFile "There is one application ore more in the building block and the building block contains no linked applications"
        }
       elseif($numApplications -ge 1 -and $ApplicationContainsLinkedActions)
        {
         Add-EntryToLogFile "There is one application ore more in the building block and the application contains a linked action."
        } 
       
       $appid                               = $ApplicationXML.appid
       $Title                               = $ApplicationXML.configuration.title
       $StartMenu                           = $ApplicationXML.configuration.menu
       $Description                         = $ApplicationXML.configuration.description
       $Commandline                         = $ApplicationXML.configuration.commandline
       $accesstype                          = $ApplicationXML.accesscontrol.accesstype
       $AccessMode                          = $ApplicationXML.accesscontrol.access_mode
       $Parameters                          = $ApplicationXML.configuration.parameters
       $tmpCounter                          = $ApplicationCounter+1
       Switch ($accesstype)
            {
             "group"     {$GroupList                           = @(Get-XMLDetailsForAccessInfo -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].accesscontrol" -accessmode $AccessMode -accesstype $accesstype)
                          $accesstype = "Users and groups"
                          break
                         }
             "delegated" {$GroupList                           = @(Get-XMLDetailsForAccessInfo -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].accesscontrol" -accessmode $AccessMode -accesstype $accesstype)
                          $accesstype = "Controlled by application manager(s)"
                          break
                         }
             "ou"        {$accesstype = "OU membership"
                          break
                         }
             "all"       {$accesstype = "All users"
                          break
                         }
             "secrole"   {$accesstype = "Administrative roles"
                          break
                         }
             "orchestra" {$accesstype = "Identity Director Service"
                          break
                         }
              default    {$accesstype = "An invalid access type has been discovered."}
            }

       $PowerZones        = @(Get-XMLDetailsForPowerZones  -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].powerzones.powerzone")
       $Workspaces        = @(Get-XMLDetailsForWorkspaces  -BuildingBlockDetails $BuildingBlockDetails -XMLPath_WorkspaceControl "respowerfuse.buildingblock.application[$tmpCounter].workspacecontrol" -XMLPath_Workspaces "respowerfuse.buildingblock.workspaces")
       $FileTypes         = @(Get-XMLDetailsForFileTypes   -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].instantfileassociations.association")
         
       # =============================================================================================================================================
       # Check if LookFor is used. In that case check the title, commandline, groups, locations and containers.
       # =============================================================================================================================================
 
       $bolInAppID     = $false
       $boltitle       = $false
       $bolCommandLine = $false
       $bolParameter   = $false
       $bolFileTypes   = $false
       $bolGroupOrUser = $false
       $bolLocations   = $false
       $bolContainers  = $false
       $Remark         = ""

       if($Global:LookFor)
        {
         
         # Check the AppID
         if($appid)
          {
           $Suffix = "[AppID]"
           $Results = Find-InArry -SearchInArray $appID -LookForInArray $Global:InAppID -Suffix $Suffix -ExactMatch
           ForEach ($Result in $Results)
            {
             $bolInAppID = $true
             $Remark     = "$Suffix $Result"       
            }
          }

         # Check the title
         if($Title)
          {
           $Suffix = "[Title]"
           $Results = Find-InArry -SearchInArray $Title -LookForInArray $Global:InTitle -Suffix $Suffix 
           ForEach ($Result in $Results)
            {
             $boltitle = $true
             $Remark = "$Suffix $Result"       
            }
          }

         # Check the command line
         if($Commandline)
          {
           $Suffix = "[Command]"
           $Results = Find-InArry -SearchInArray $Commandline -LookForInArray $Global:InCommandLine -Suffix $Suffix 
           ForEach ($Result in $Results)
            {
             $bolCommandLine = $true
             if(-not ($Remark))
              {
               $Remark         = "$Suffix $Result"
              }
               else
              {
               $Remark        += "`n$Suffix $Result"
              }
            }
          }

         # Check the parameter line
         if($Parameters)
          {
           $Suffix  = "[Parameter]"  
           $Results = Find-InArry -SearchInArray $Parameters -LookForInArray $Global:InParameter -Suffix $Suffix
           ForEach ($Result in $Results)
            {
             $bolParameter = $true
             if(-not ($Remark))
              {
               $Remark         = "$Suffix $Result"
              }
               else
              {
               $Remark        += "`n$Suffix $Result"
              }
            }
          }

         # Check the file types
         if ($FileTypes)
          {
           $Suffix  = "[File types]"
           $Results = Find-InArry -SearchInArray $FileTypes -LookForInArray $Global:InFileTypes -Suffix $Suffix
           ForEach ($Result in $Results)
            {
             $bolFileTypes = $true
             if(-not ($Remark))
              {
               $Remark         = "$Suffix $Result"
              }
               else
              {
               $Remark        += "`n$Suffix $Result"
              }
            }
          }

         # Check the group or user
         if($accesstype = "Users and groups")
          {           
           $Suffix  = "[GroupOrUser]"
           $Results = Find-InArry -SearchInArray $($GroupList -split "`n") -LookForInArray $Global:InGroupOrUser -Suffix $Suffix
           ForEach ($Result in $Results)
            {
             $bolGroupOrUser = $true
             if(-not($Remark))
              {
               $Remark = "$Suffix $Result"
              }
               else
              {
               $Remark += "`n$Suffix $Result"
              }
            }
          }

         # Locations (also called PowerZones)
         if($PowerZones)
          {
           $Suffix  = "[Locations]"
           $Results = Find-InArry -SearchInArray $($PowerZones -split "`n") -LookForInArray $Global:InLocations -Suffix $Suffix -ExactMatch
           ForEach ($Result in $Results)
            {
             $bolLocations   = $true
             if(-not($Remark))
              {
               $Remark = "$Suffix $Result"
              }
               else
              {
               $Remark += "`n$Suffix $Result"
              }
            }
          }

         # Containers (also called Workspaces)
         if($Workspaces)
          { 
           $Suffix  = "[Containers]"
           $Results = Find-InArry -SearchInArray $($Workspaces -split "`n") -LookForInArray $Global:InContainers -Suffix $Suffix -ExactMatch
           ForEach ($Result in $Results)
            {
             $bolContainers = $true
             if(-not($Remark))
              {
               $Remark = "$Suffix $Result"
              }
               else
              {
               $Remark += "`n$Suffix $Result"
              }
            }
          }

         # =============================================================================================================================================
         # Check if all the conditions are met.
         # =============================================================================================================================================

         $bolAllConditionsAreMet = $true

         if($Global:InAppID)
          {
           if($bolInAppID)
            {
             $bolAllConditionsAreMet = $true
             Add-EntryToLogFile "--> InAppID:    All Conditions Are Met has been set to true."
            }
             else
            {
             $bolAllConditionsAreMet = $false
             Add-EntryToLogFile "--> InAppID:    All Conditions Are Met has been set to false."
            }
          }
         
         if($bolAllConditionsAreMet)
          {
           if($Global:InTitle)
            {
             if($boltitle)
              {
               $bolAllConditionsAreMet = $true
               Add-EntryToLogFile "--> InTitle:    All Conditions Are Met has been set to true."
              }
               else
              {
               $bolAllConditionsAreMet = $false
               Add-EntryToLogFile "--> InTitle:    All Conditions Are Met has been set to false."
              }
            }
          }

          if($bolAllConditionsAreMet)
           {
            if($Global:InCommandLine)
             {
              if($bolCommandLine)
               {
                $bolAllConditionsAreMet = $true
                Add-EntryToLogFile "--> InCommandline:    All Conditions Are Met has been set to true."
               }
                else
               {
                $bolAllConditionsAreMet = $false
                Add-EntryToLogFile "--> InCommandline:    All Conditions Are Met has been set to false."
               }
             }
           }

          if($bolAllConditionsAreMet)
           {
            if($Global:InParameter)
             {
              if($bolParameter)
               {
                $bolAllConditionsAreMet = $true
                Add-EntryToLogFile "--> Parameter:    All Conditions Are Met has been set to true."
               }
                else
               {
                $bolAllConditionsAreMet = $false
                Add-EntryToLogFile "--> Parameter:    All Conditions Are Met has been set to false."
               }
             }
           }

          if($bolAllConditionsAreMet)
           {
            if($Global:InFileTypes)
             {
              if($bolFileTypes)
               {
                $bolAllConditionsAreMet = $true
                Add-EntryToLogFile "--> Parameter:    All Conditions Are Met has been set to true."
               }
                else
               {
                $bolAllConditionsAreMet = $false
                Add-EntryToLogFile "--> Parameter:    All Conditions Are Met has been set to false."
               }
             }
           }

          if($bolAllConditionsAreMet)
           {
            if($Global:InGroupOrUser)
             {
              if($bolGroupOrUser)
               {
                $bolAllConditionsAreMet = $true
                Add-EntryToLogFile "--> GroupOrUser:    All Conditions Are Met has been set to true."
               }
                else
               {
                $bolAllConditionsAreMet = $false
                Add-EntryToLogFile "--> GroupOrUser:    All Conditions Are Met has been set to false."
               }
             }
           }

          if($bolAllConditionsAreMet)
           {
            if($Global:InLocations)
             {
              if($bolLocations)
               {
                $bolAllConditionsAreMet = $true
                Add-EntryToLogFile "--> Locations:    All Conditions Are Met has been set to true."
               }
                else
               {
                $bolAllConditionsAreMet = $false
                Add-EntryToLogFile "--> Locations:    All Conditions Are Met has been set to false."
               }
             }
           }

          if($bolAllConditionsAreMet)
           {
            if($Global:InContainers)
             {
              if($bolContainers)
               {
                $bolAllConditionsAreMet = $true
                Add-EntryToLogFile "--> Containers:    All Conditions Are Met has been set to true."
               }
                else
               {
                $bolAllConditionsAreMet = $false
                Add-EntryToLogFile "--> Containers:    All Conditions Are Met has been set to false."
               }
             }
           }

          Add-EntryToLogFile "After containers: All Conditions are met: $bolAllConditionsAreMet"

         }
         
         if((-not($Global:LookFor)) -or ($bolAllConditionsAreMet))
          {
           $Workingdir                          = $ApplicationXML.configuration.workingdir           
           $appv5packagemode                    = $ApplicationXML.configuration.appv5packagemode
           $appv5packagefile                    = $ApplicationXML.configuration.appv5packagefile
           $appv5deploymentconfigurationfile    = $ApplicationXML.configuration.appv5deploymentconfigurationfile
           $appv5userconfigurationfile          = $ApplicationXML.configuration.appv5userconfigurationfile
           $appv5packageupdate                  = $ApplicationXML.configuration.appv5packageupdate
           $appv5packageroot                    = $ApplicationXML.configuration.appv5packageroot
           $administrativenote                  = $ApplicationXML.configuration.administrativenote 
           $unmanagedshortcuts                  = $ApplicationXML.configuration.unmanagedshortcuts
           $createmenushortcut                  = $ApplicationXML.configuration.createmenushortcut
           $allowmultipleshortcuts              = $ApplicationXML.configuration.allowmultipleshortcuts

           $Enabled                             = $ApplicationXML.settings.enabled
           $hidefrommenu                        = $ApplicationXML.settings.hidefrommenu
           $checkappexists                      = $ApplicationXML.settings.checkappexists
           $checkfileexists                     = $ApplicationXML.settings.checkfileexists
                  
           $LearningMode                        = $ApplicationXML.appguard.learning     

           $AppGuard                            = Get-XMLDetailsForAuthorizedFiles  -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].appguard.authorizedfiles.authfile" -CommandLine $Commandline
                      
           $ApplicationContainsLinkedActions1 = "no"
           If($ApplicationContainsLinkedActions)
            {
             $ApplicationContainsLinkedActions1 = "yes"
            }
                                
           Add-EntryToResultsFile  -XMLFileName                      $Filename                           `
                                   -StartMenu                        $StartMenu                          `
                                   -appid                            $appid                              `
                                   -Title                            $Title                              `
                                   -Description                      $Description                        `
                                   -Commandline                      $Commandline                        `
                                   -Workingdir                       $Workingdir                         `
                                   -Parameters                       $Parameters                         `
                                   -appv5packagemode                 $appv5packagemode                   `
                                   -appv5packagefile                 $appv5packagefile                   `
                                   -appv5deploymentconfigurationfile $appv5deploymentconfigurationfile   `
                                   -appv5packageupdate               $appv5packageupdate                 `
                                   -appv5userconfigurationfile       $appv5userconfigurationfile         `
                                   -appv5packageroot                 $appv5packageroot                   `
                                   -administrativenote               $administrativenote                 `
                                   -unmanagedshortcuts               $unmanagedshortcuts                 `
                                   -createmenushortcut               $createmenushortcut                 `
                                   -allowmultipleshortcuts           $allowmultipleshortcuts             `
                                   -Enabled                          $Enabled                            `
                                   -hidefrommenu                     $hidefrommenu                       `
                                   -checkappexists                   $checkappexists                     `
                                   -checkfileexists                  $checkfileexists                    `
                                   -FileTypesInTable                 $FileTypes                          `
                                   -accesstype                       $accesstype                         `
                                   -GroupList                        $GroupList                          `
                                   -PowerZones                       $PowerZones                         `
                                   -Workspaces                       $Workspaces                         `
                                   -LearningMode                     $LearningMode                       `
                                   -AppGuard                         $AppGuard                           `
                                   -ApplicationContainsLinkedActions $ApplicationContainsLinkedActions1  `
                                   -Remark                           $Remark                             `
                                   -NumberOfApplications             $numApplications   
           if($Global:CopyFiles)
            {
             Copy-Item -Path $($Global:BuildingBlockFileName -replace ".xml",".*") -Destination $To -Force
             Add-EntryToLogFile "The file $($Global:BuildingBlockFileName) has been copied to $To."
            }
          }
           else
          {
           Add-EntryToLogFile -Entry "The search-item has not been found in the application $Title.`n"
          }                     
        }
      }
   }
 
# =============================================================================================================================================
# End function block
# =============================================================================================================================================

# =============================================================================================================================================
# Check if the parameter -LookFor has not been forgotten.
# =============================================================================================================================================

  Clear-Host

  $Message  = ""
  $bolError = $false

  # =============================================================================================================================================
  # Check if incorrect combination of parameters is used. If so, correct it or throw an error. 
  # Incorrect combinations are 
  #   - LookFor is used, but no InTitle, InCommand parameters, InParameter, InGroupOrUser Locations and Containers parameters
  #   - CopyFiles is used, but no InTitle, InCommand parameters, InParameter, InGroupOrUser Locations and Containers parameters
  #   - CopyFiles is used, but no To parameter
  #   - InTitle, InCommand parameters, InParameter, InGroupOrUser Locations or Containers parameters are used, but no LookFor parameter
  # =============================================================================================================================================

  if($LookFor -and (-not $InAppID -and -not $InTitle -and -not $InCommandLine -and -not $InParameter -and -not $InFileTypes -and -not $InGroupOrUser -and -not $InLocations -and -not $InContainers))
   {
    $bolError = $true
    $Message = "[Error] LookFor is used, but not InAppID, InTitle, InCommand, InParameter, File Types, Group or User, Locations or Containers. Please specify either the InTitle, InCommand, InParameter, InGroupOrUser, InLocations or InContainers parameter."
   }

  if(-not($LookFor) -and ($InAppID -or $InTitle -or $InCommandLine -or $InParameter -or $InFileTypes -or $InGroupOrUser -or $InLocations -or $InContainers))
   {
    $Message  = "[Warning] LookFor has been added."
    $LookFor  = $True
   }
   

  if($CopyFiles -and (-not $InAppID -and -not $InTitle -and -not $InCommandLine -and -not $InParameter -and -not $InFileTypes -and -not $InGroupOrUser -and -not $InLocations -and -not $InContainers))
   {
    $bolError = $true
    $Text     = "[Error] CopyFiles is used, but not InAppID, InTitle, InCommand, InParameter, File Types, Group or User, Locations or Containers. Please specify either the InTitle, InCommand, InParameter, InGroupOrUser InLocations or InContainers parameter."
    if(-not($Message))
     {
      $Message = $Text
     }
      else
     {
      $Message += "`n$text"
     }
    }

  if(-not($To) -and $CopyFiles)
   {
    $bolError = $true
    $Text     = "[Error] CopyFiles is used, but To has not been specified. Please specify the To location."
    if(-not($Message))
     {
      $Message = $Text
     }
      else
     {
      $Message += "`n$text"
     }
    }

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

  $Global:arrTable        = @()
  $Global:DetailedLogging = $DetailedLogging
  $Global:LogFile         = ""
  $Global:LookFor         = $LookFor
  $Global:InAppID         = $InAppID
  $Global:InTitle         = $InTitle
  $Global:InCommandLine   = $InCommandLine
  $Global:InParameter     = $InParameter
  $Global:InFileTypes     = $InFileTypes
  $Global:InGroupOrUser   = $InGroupOrUser
  $Global:InLocations     = $InLocations
  $Global:InContainers    = $InContainers
  $Global:CopyFiles       = $CopyFiles
  $Global:To              = $To
  $Global:Delimiter       = $Delimiter
  $Global:Summary         = $Summary
  $Results                = @()
  $valCounter             = 1
  $bolMaxComputers        = $False
  
  if($LogPath -eq "")
   {
    $LogPath   = Split-Path -parent $MyInvocation.MyCommand.Definition
   }
    else
   {
    $Returntext, $bolResult = Create-Folder -FolderName $LogPath
    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'))).csv"
  $strLastPartOfFileName = $strLastPartOfFileName -replace ":","-"
  $strLastPartOfFileName = $strLastPartOfFileName -replace "/","-"
  $PreFixLogFile         = "ExportIvantiBuildingBlock"

  if($SaveAsHTMLPage)
   {
    $strLastPartOfFileName = $strLastPartOfFileName -replace ".csv",".html"
   }

  $CSVOrHTMLFileWithResults   = $LogPath + "\"+ $PreFixLogFile + $strLastPartOfFileName

  if($Global:DetailedLogging)
   {
    if($SaveAsHTMLPage)
     {
      $Global:LogFile = $LogPath + "\"+ $PreFixLogFile + $($strLastPartOfFileName -replace ".html",".log")
     }
      else
     {
      $Global:LogFile = $LogPath + "\"+ $PreFixLogFile + $($strLastPartOfFileName -replace ".csv",".log")
     }
    New-Item $Global:LogFile -ItemType File -Force | Out-Null
   }

   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" 
   }
   
# =============================================================================================================================================
# Create the folder where all the files have to be copied to. Only if the To parameter is used.
# =============================================================================================================================================

  if($To)
   {
    $Returntext, $bolResult = Create-Folder -FolderName $To
    if($bolResult)
     {
      Add-EntryToLogFile -Entry "The folder $To has been created successfully."
     }
      else
     {
      $Text = "There was an error while creating the folder $To. The script will stop now."
      Add-EntryToLogFile -Entry $Text
      Write-Error $Text -Category WriteError
      Exit 4
     }
   }


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

  Add-Type -AssemblyName System.Web

# =============================================================================================================================================
# Read the directory with all the building blocks
# =============================================================================================================================================

  if(-not $Directory)
   {
    $Directory   = Split-Path -parent $MyInvocation.MyCommand.Definition
   }

  $BuildingBlockFileNames = @(Get-ChildItem -Path $Directory -Filter *.xml -Recurse:$IncludeSubFolders | Sort-Object -Property FullName)

  if($DetailedLogging)
   {
    Write-Host "Writing the xml file names to the log file..."
    Add-EntryToLogFile -Entry  "#####################################################################################################    OVERVIEUW QUEUED FILES    #####################################################################################################"
    $BuildingBlockFileNames | ForEach-Object {Add-EntryToLogFile -Entry "The file $($_.FullName) is queued for processing."}
    Add-EntryToLogFile -Entry  "##################################################################################################### END OF OVERVIEW QUEUED FILES #####################################################################################################"
    Clear-Host
   }
    
# =============================================================================================================================================
# Go through all the xml files.
# =============================================================================================================================================

  $TotalBuildingBlocks = $BuildingBlockFileNames.Count
  $valCounter          = 1

  ForEach ($BuildingBlockFileName in $BuildingBlockFileNames)
   {
    if(-not $NoProgressBar)
     {
      $Percentage = $valCounter / $TotalBuildingBlocks * 100
      Write-Progress -Id 1 -Activity "Processing all the exported building blocks. Building block $valCounter of $TotalBuildingBlocks buildingblocks ($([int]$Percentage)%)" -Status "Processing building block $BuildingBlockFileName" -PercentComplete $Percentage
     }
    if(test-path($BuildingBlockFileName.FullName))
     {
      $Global:BuildingBlockFileName = $BuildingBlockFileName.FullName
      Add-EntryToLogFile -Entry "Found: $Global:BuildingBlockFileName"
      Try
      {
      $BuildingBlockData = [xml](Get-Content -Path $Global:BuildingBlockFileName)
      if(($BuildingBlockData.respowerfuse.buildingblock.application.guid) -and (CheckXMLFile -XMLFile $Global:BuildingBlockFileName))
       {
        Add-EntryToLogFile -Entry "Processing: $Global:BuildingBlockFileName"
        FindInfoInBuildingBlock -BuildingBlockDetails $BuildingBlockData -Filename $BuildingBlockFileName
       }
        else
       {
        Add-EntryToLogFile -Entry "It seems that $Global:BuildingBlockFileName is not a real Ivanti application building block.`nThus skipping.`n"
       }
      }
      Catch
      {
       Add-EntryToLogFile -Entry ""
       Add-EntryToLogFile -Entry "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
       Add-EntryToLogFile -Entry ""
       Add-EntryToLogFile -Entry "There is an error in the xml file $Global:BuildingBlockFileName."
       Add-EntryToLogFile -Entry ""
       Add-EntryToLogFile -Entry "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
       Add-EntryToLogFile -Entry ""         
      }
     }
    $valCounter++
   } 

# =============================================================================================================================================
# Export the CSV or HTML file.
# Exit afterwards.
# =============================================================================================================================================

  if($SaveAsHTMLPage)
   {
    
  # =============================================================================================================================================
  # 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:arrTable)
     {
      $Record."Properties - FileTypes"                                 = $Record."Properties - FileTypes"                                 -replace "`n","<br>"
      $Record."Security - Authorized Files - Authorized file"          = $Record."Security - Authorized Files - Authorized file"          -replace "`n","<br>"
      $Record."Access Control - Identy - Selected users and/or groups" = $Record."Access Control - Identy - Selected users and/or groups" -Replace "`n","<br>"
      $Record."Access Control - Location and devices"                  = $Record."Access Control - Location and devices"                  -Replace "`n","<br>"
      $Record."Access Control - Workspace containers"                  = $Record."Access Control - Workspace containers"                  -Replace "`n","<br>"
      $Record."Remark"                                                 = $Record."Remark"                                                 -replace "`n","<br>"
     }
              
    If($Global:Summary)
     {
      $Global:arrTable = $Global:arrTable | Select-Object -Property "XML File Name","Start Menu location","Properties - General - ID","Properties - General - Title","Properties - General - Description","Properties - General - Commandline","Properties - General - Parameters","Properties - Settings - Application is enabled","Properties - FileTypes","Access Control - Identy - Type","Access Control - Identy - Selected users and/or groups","Access Control - Location and devices","Access Control - Workspace containers","Remark"
     }
       
    $HTMLTable   = $Global:arrTable | Sort-Object -Property "Start Menu location","Properties - General - Title","XML File Name","Properties - General - ID" | ConvertTo-Html -Fragment -PreContent "<h2>Table</h2>"
    $HTMLTable   = [System.Web.HttpUtility]::HtmlDecode($HTMLTable)
   
    $Title       = "<h1>Complete overview of the building blocks</h1>"
    $Body        = "$Title $HTMLTable"

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

    $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 $CSVOrHTMLFileWithResults
    Write-Host "The webpage '$CSVOrHTMLFileWithResults' has been created." 
   }
    else
   {
    Export-CSVOrHTMLFileWithResults
   }

Table

" $HTMLTable = [System.Web.HttpUtility]::HtmlDecode($HTMLTable) $Title = "

Complete overview of the building blocks

" $Timestamp = (Get-Date -UFormat "%a %e %b %Y %X").ToString() $PostContent = "

Creation Date: $Timestamp

" $Report = ConvertTo-Html -Head $CSS -Body "$Title $HTMLTable" -PostContent $PostContent $Report | Out-File $CSVOrHTMLFileWithResults Write-Host "The webpage '$CSVOrHTMLFileWithResults' has been created." } else { Export-CSVOrHTMLFileWithResults } 

 

 

And an example from the generated CSV file opened with Excel:

 

 

Add comment