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. 

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
 }

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.
  # =============================================================================================================================================

  $ContainsLinkedActions = $false
  If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
   {
    $ContainsLinkedActions = $true
   }
  
  if(($numApplications -eq 1) -or ($numApplications -gt 1 -and $ContainsLinkedActions))
   {
    
    # =============================================================================================================================================
    # 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
 }

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.
  # =============================================================================================================================================

  $ContainsLinkedActions = $false
  If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
   {
    $ContainsLinkedActions = $true
   }
  
  if(($numApplications -eq 1) -or ($numApplications -gt 1 -and $ContainsLinkedActions))
   {
    
    # =============================================================================================================================================
    # 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:

You can view some background information on YouTube:

This technique is used in my 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_v02.ps1" -Directory \\server\path\to\xmlfiles

.EXAMPLE
    Run an inventory on all the building blocks in the folder \\server\path\to\xmlfiles and its subfolders
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v02.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_v02.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.
    The delimiter character is ','
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v02.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_v02.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_v02.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_v02.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
    Copy all the building block files that have msedge.exe or iexplore.exe in the command line to c:\tmp-internet
    ."ExportIvantiBuildingBlockStartMenuItemsToCSV_v02.ps1" -Directory \\server\path\to\xmlfiles -IncludeSubFolders -LogPath c:\tmp -LookFor -InCommandLine msedge.exe,iexplore.exe -CopyFiles -To c:\tmp-internet

.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

#>

[CmdletBinding(DefaultParameterSetName = 'Default')]

Param
  (
   [Parameter(HelpMessage='Specify the directory that contains all the exported building blocks.')]
   [Parameter(Mandatory=$True,  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='Enable lookfor.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $LookFor,

   [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='Copy the files that are found with the LookFor parameter to a new location.')]
   [Parameter(Mandatory=$False, ParameterSetName='Default')]
   [Switch]   $CopyFiles,

   [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)
      }
   }


  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                       = "",
      [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]  $accesstype                        = "",
      [String]  $GroupList                         = "",
      [String]  $PowerZones                        = "",
      [String]  $Workspaces                        = "",
      [String]  $LearningMode                      = "",
      [String]  $AppGuard                          = "",
      [String]  $ContainsLinkedActions             = "",
      [String]  $Remark                            = ""
     )

    $Record  = [ordered] @{"Timestamp"                                                               = "";
                           "XML File Name"                                                           = "";
                           "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"          = "";
                           "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"                                                                  = ""
                           }

    $Timestamp         = (Get-Date -UFormat "%a %e %b %Y %X").ToString()
    
    $Record."Timestamp"                                                              = $Timestamp
    $Record."XML File Name"                                                          = $XMLFileName
    $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."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" = $ContainsLinkedActions
    $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  "       Timestamp:                                                               $Timestamp"
    Add-EntryToLogFile -Entry  "       XML File Name:                                                           $XMLFileName"
    Add-EntryToLogFile -Entry  "       Start Menu location:                                                     $StartMenu"
    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  "       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:  $ContainsLinkedActions"
    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-ResultsLogFileToCSV
   {

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

    This function writes the logfile content to a CSV file.

    #>

    If($Global:arrTable.Count -gt 0)
     {
      $Global:arrTable | Sort-Object -Property TimeStamp | Export-Csv $strCSVLogFileSucces -NoTypeInformation -Delimiter $Global:Delimiter
      Add-EntryToLogFile -Entry ">> Export-ResultsLogFileToCSV: The file '$strCSVLogFileSucces' has been written." 
     } 
      else
     {
      $ErrorMessage = "Something went wrong while writing the logfile '$strCSVLogFileSucces'. 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")
         $GroupDetails = ($GroupDetails).Node
         Add-EntryToLogFile -Entry " Group Details:" 

         forEach ($GroupDetail in $GroupDetails)
          {
           if(-not($Return))
            {
             $Type = $GroupDetail | Select-Object -ExpandProperty 'type'
             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'
             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")
         $AppplicationManagers = ($AppplicationManagers).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 resturn 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")
     $AuthFilesDetails = ($AuthFilesDetails).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 resturn 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
      )
       
     Add-EntryToLogFile -Entry "--> In function: Get-XMLDetailsForWorkspaces"

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

   # =============================================================================================================================================
   # The workspaces are stored in 
   # respowerfuse.buildingblock.workspaces.workspace
   # =============================================================================================================================================
 
     $WorkspaceDetails = @($BuildingBlockDetails | Select-Xml -XPath "/$XMLPath")
     $WorkspaceDetails = ($WorkspaceDetails).Node
       
     forEach ($Workspace in $WorkspaceDetails)
      {
       $enabled = $Workspace | Select-Object -ExpandProperty 'enabled'
       if($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 resturn 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 resturn value for $XMLPath is $Return." 
     Return $Return
   }

  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,
      [String] $LogFile
     )

     $Commandline                         = ""
     $numApplications                     = $BuildingBlockDetails.respowerfuse.buildingblock.application.Count
     if(-not($numApplications))
      {
       $numApplications = 1
      }
           
     for($ApplicationCounter = 0; $ApplicationCounter -lt $numApplications; $ApplicationCounter++)
      {
     
       if($numApplications -eq 1)
        {
         $ApplicationXML                     = $BuildingBlockDetails.respowerfuse.buildingblock.application
        }
         else
        {
         $ApplicationXML                     = $BuildingBlockDetails.respowerfuse.buildingblock.application.Item($ApplicationCounter)
        }
      
       $ContainsLinkedActions = $false
       If($ApplicationXML.powerlaunch.linked_actions.linked_to_application)
        {
         $ContainsLinkedActions = $true
        }
       
       if(($numApplications -eq 1) -or ($numApplications -gt 1 -and $ContainsLinkedActions))
        {         
         $appid                               = $ApplicationXML.appid
         $Title                               = $ApplicationXML.configuration.title
         $StartMenu                           = $ApplicationXML.configuration.menu
         $Description                         = $ApplicationXML.configuration.description
         $Commandline                         = $ApplicationXML.configuration.commandline
         
         # =============================================================================================================================================
         # Check if LookFor is used. In that case check the title and commandline
         # =============================================================================================================================================
 
         $boltitle       = $false
         $bolCommandLine = $false
         $Remark         = ""

         if($Global:LookFor)
         {
          # Check the title
          ForEach ($objTitle in $Global:InTitle)
           {
            if($Title -match $objTitle)
             {
              $boltitle = $true
              Add-EntryToLogFile -Entry "$objTitle has been found in $Title."
              $Remark = "[Title] $objTitle has been found in $Title."
              Break
             }
           }
          # Check the command line
          ForEach ($objCommandLine in $Global:InCommandLine)
           {
            if($Commandline -match $objCommandLine)
             {
              $bolCommandLine = $true
              Add-EntryToLogFile -Entry "$objCommandLine has been found in $Commandline."
              if(-not($Remark))
               {
                $Remark = "[CommandLine] $objCommandLine has been found in $Commandline."
               }
                else
               {
                $Remark += "`n[CommandLine] $objCommandLine has been found in $Commandline."
               }
             }
           }
         }

         if((-not($Global:LookFor)) -or ($boltitle -or $bolCommandLine))
          {
           $Workingdir                          = $ApplicationXML.configuration.workingdir
           $Parameters                          = $ApplicationXML.configuration.parameters
           $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
                  
           $accesstype                          = $ApplicationXML.accesscontrol.accesstype
           $AccessMode                          = $ApplicationXML.accesscontrol.access_mode
           $LearningMode                        = $ApplicationXML.appguard.learning
                  
           $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."}
            }
           $AppGuard                            = Get-XMLDetailsForAuthorizedFiles -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].appguard.authorizedfiles.authfile" -CommandLine $Commandline 
           $PowerZones                          = Get-XMLDetailsForPowerZones      -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.application[$tmpCounter].powerzones.powerzone"
           $Workspaces                          = Get-XMLDetailsForWorkspaces      -BuildingBlockDetails $BuildingBlockDetails -XMLPath "respowerfuse.buildingblock.workspaces.workspace"
                  
           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                    `
                                   -accesstype                       $accesstype                         `
                                   -GroupList                        $GroupList                          `
                                   -PowerZones                       $PowerZones                         `
                                   -Workspaces                       $Workspaces                         `
                                   -LearningMode                     $LearningMode                       `
                                   -AppGuard                         $AppGuard                           `
                                   -ContainsLinkedActions            $ContainsLinkedActions              `
                                   -Remark                           $Remark   
           if($Global:CopyFiles)
            {
             Copy-Item -Path $($Global:BuildingBlockFileName) -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.
# Define the variables
# =============================================================================================================================================

  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 and InCommand parameters
  #   - CopyFiles is used, but no InTitle and InCommand parameters
  #   - CopyFiles is used, but no To parameter
  # =============================================================================================================================================

  if($LookFor -and (-not($InTitle) -and (-not $InCommandLine)))
   {
    $bolError = $true
    $Message = "[Error] LookFor is used, but not InTitle and InCommand. Please specify either the InTitle or InCommand parameter."
   }

  if($CopyFiles -and (-not($InTitle) -and (-not $InCommandLine)))
   {
    $bolError = $true
    $Text     = "[Error] CopyFiles is used, but not InTitle and InCommand. Please specify either the InTitle or InCommand 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"
     }
    }


  $Global:arrTable        = @()
  $Global:DetailedLogging = $DetailedLogging
  $Global:LogFile         = ""
  $Global:LookFor         = $LookFor
  $Global:InTitle         = $InTitle
  $Global:InCommandLine   = $InCommandLine
  $Global:CopyFiles       = $CopyFiles
  $Global:To              = $To
  $Global:Delimiter       = $Delimiter
  $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"

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

  if($Global:DetailedLogging)
   {
    $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
# =============================================================================================================================================

  ForEach($boundparam in $PSBoundParameters.GetEnumerator()) 
   {
    Add-EntryToLogFile -Entry "Key: $($boundparam.Key) Value: $($boundparam.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
     }
   }

# =============================================================================================================================================
# Read the directory with all the computer names
# =============================================================================================================================================

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

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

# =============================================================================================================================================
# Go through all the xml files.
# =============================================================================================================================================

  $TotalBuildingBlocks = $BuildingBlockFileNames.Count
  $valCounter          = 1

  ForEach ($BuildingBlockFileName in $BuildingBlockFileNames)
   {
  
    Write-Progress -Id 1 -Activity "Processing all the exported building blocks." -Status "Processing building block $BuildingBlockFileName" -PercentComplete ($valCounter / $TotalBuildingBlocks * 100)
    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 $($BuildingBlockFileName.FullName) 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 $($BuildingBlockFileName.FullName)."
       Add-EntryToLogFile -Entry ""
       Add-EntryToLogFile -Entry "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
       Add-EntryToLogFile -Entry ""         
      }
     }
    $valCounter++
   } 

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

  Export-ResultsLogFileToCSV

The application ExportIvantiBuildingBlockStartMenuItemsToCSV_v01.ps1 has the following parameters:

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

  • IncludeSubFolders
    Include the sub folders as well.

  • LogPath
    The location where the CSV file is written to. Default is the same location where the script is in. 

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

 

Add comment