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 (example 1):
# =============================================================================================================================================
# File example01.ps1: Example with 1 application.
# =============================================================================================================================================
# =============================================================================================================================================
# 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:
# =============================================================================================================================================
# File example02.ps1: Example linked application and wrong format.
# =============================================================================================================================================
# =============================================================================================================================================
# 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>
Or: as shown with XML Notepad:
So only the data from the application block with linked_actions should be used.
# =============================================================================================================================================
# File example04.ps1: 2 applications in the building block (extended 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>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
}
$BuildingBlockContainsLinkedStuff = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
{
$BuildingBlockContainsLinkedStuff = $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
}
$Condition1 = (-not $BuildingBlockContainsLinkedStuff)
$Condition2 = ($BuildingBlockContainsLinkedStuff -and $ApplicationContainsLinkedActions)
if($Condition1 -or $Condition2)
{
# =============================================================================================================================================
# Read the details and write them to the host.
# =============================================================================================================================================
if($Condition1)
{
Write-Host "CONDITION: The building block does not contain any linked stuff."
}
if($Condition2)
{
Write-Host "The building block contains a linked action and the application contains a linked action."
}
$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:
# =============================================================================================================================================
# File example03.ps1: 1 application in the building block (extended 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>
<appid>41</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
}
$BuildingBlockContainsLinkedStuff = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
{
$BuildingBlockContainsLinkedStuff = $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
}
$Condition1 = (-not $BuildingBlockContainsLinkedStuff)
$Condition2 = ($BuildingBlockContainsLinkedStuff -and $ApplicationContainsLinkedActions)
if($Condition1 -or $Condition2)
{
# =============================================================================================================================================
# Read the details and write them to the host.
# =============================================================================================================================================
if($Condition1)
{
Write-Host "CONDITION: The building block does not contain any linked stuff."
}
if($Condition2)
{
Write-Host "The building block contains a linked action and the application contains a linked action."
}
$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:
# =============================================================================================================================================
# File example05.ps1: 2 applications in the building block (extended example with workspace container)
# =============================================================================================================================================
# =============================================================================================================================================
# 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.
# =============================================================================================================================================
$numApplications = $BuildingBlockDetails.respowerfuse.buildingblock.application.Count
if(-not($numApplications))
{
$numApplications = 1
}
$BuildingBlockContainsLinkedStuff = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application)
{
$BuildingBlockContainsLinkedStuff = $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
}
$Condition1 = (-not $BuildingBlockContainsLinkedStuff)
$Condition2 = ($BuildingBlockContainsLinkedStuff -and $ApplicationContainsLinkedActions)
if($Condition1 -or $Condition2)
{
# =============================================================================================================================================
# Read the details and write them to the host.
# =============================================================================================================================================
if($Condition1)
{
Write-Host "CONDITION: The building block does not contain any linked stuff."
}
if($Condition2)
{
Write-Host "The building block contains a linked action and the application contains a linked action."
}
$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:
New in version 1.1 is the detection and working with the linked user settings:
Shown in XML Notepad:
# =============================================================================================================================================
# File example06.ps1: Example linked user preference settings
# =============================================================================================================================================
# =============================================================================================================================================
# 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>29</appid>
<guid>{11ADF1F2-D947-4098-AAD0-B2AC93F71BEE}</guid>
<configuration>
<menu>Start\Microsoft Office 365 (Office 2016)</menu>
<title>Microsoft Access</title>
<description>Microsoft Access</description>
<commandline>C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE</commandline>
<workingdir>C:\Program Files (x86)\Microsoft Office\root\Office16</workingdir>
<parameters></parameters>
</configuration>
</application>
<application>
<appid>6388</appid>
<guid>{89C47E54-E504-4FDC-9CE1-C98EC82F0811}</guid>
<configuration>
<menu>Start\Microsoft Office 365 (Office 2016)</menu>
<title>Microsoft Access (test user settings)</title>
<description>Microsoft Access</description>
<commandline>C:\Program Files (x86)\Microsoft Office\root\Office16\MSACCESS.EXE</commandline>
<workingdir>C:\Program Files (x86)\Microsoft Office\root\Office16</workingdir>
<parameters></parameters>
</configuration>
<userpreference_settings>
<linkeduserpreference>{11ADF1F2-D947-4098-AAD0-B2AC93F71BEE}</linkeduserpreference>
</userpreference_settings>
</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
}
$BuildingBlockContainsLinkedStuff = $false
if($BuildingBlockDetails.respowerfuse.buildingblock.application.userpreference_settings.linkeduserpreference)
{
$BuildingBlockContainsLinkedStuff = $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 user preference mentioned in this applicaton block. In that case only read the details for the linked user
# preference.
# =============================================================================================================================================
$ApplicationContainslinkeduserpreference = $false
If($ApplicationXML.userpreference_settings.linkeduserpreference)
{
$ApplicationContainslinkeduserpreference = $true
}
$Condition1 = (-not $BuildingBlockContainsLinkedStuff)
$Condition2 = ($BuildingBlockContainsLinkedStuff -and $ApplicationContainslinkeduserpreference)
if($Condition1 -or $Condition2)
{
# =============================================================================================================================================
# Read the details and write them to the host.
# =============================================================================================================================================
if($Condition1)
{
Write-Host "CONDITION: The building block does not contain any linked stuff."
}
if($Condition2)
{
Write-Host "The building block contains a linked action and the application contains a linked user setting."
}
$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:
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.
- To
- InAppID
- 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_v12.ps1 -Detailed
NAME
C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v12.ps1
SYNOPSIS
Finds the Start Menu Items in Ivanti Workspace Control Building Blocks and export them to a CSV file.
SYNTAX
C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.ps1 -examples".
For more information, type: "get-help C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v12.ps1 -detailed".
For technical information, type: "get-help C:\tmp\ExportIvantiBuildingBlockStartMenuItemsToCSV_v12.ps1 -full".
And the script (ExportIvantiBuildingBlockStartMenuItemsToCSV_v12.ps1)
<#
.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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_v12.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
v1.1:
* Applications with linked user preferences (linked user settings) where not shown properly. That has been corrected.
v1.2:
* The code regarding linked actions and linked user settings has been simplyfied.
#>
[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 = 9999,
[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] $ApplicationContainsLinkedSettings = "",
[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" = "";
"User settings - Properties contains user settings from other application"= "";
"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."User settings - Properties contains user settings from other application" = $ApplicationContainsLinkedSettings
$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 " User settings - Properties contains user settings from other application: $ApplicationContainsLinkedSettings"
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 or linked user preferences in the building block.
# If so the variable $BuildingBlockContainsLinkedApplications or $BuildingBlockContainsLinkedUserPreferences 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.
# =============================================================================================================================================
$BuildingBlockContainsLinkedStuff = $false
if(($BuildingBlockDetails.respowerfuse.buildingblock.application.powerlaunch.linked_actions.linked_to_application) -or ($BuildingBlockDetails.respowerfuse.buildingblock.application.userpreference_settings.linkeduserpreference))
{
$BuildingBlockContainsLinkedStuff = $true
}
Add-EntryToLogFile -Entry "Number of applications: $numApplications"
Add-EntryToLogFile -Entry "Building block contains linked stuff: $BuildingBlockContainsLinkedStuff"
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
}
$ApplicationContainslinkedUserPreference = $false
If($ApplicationXML.userpreference_settings.linkeduserpreference)
{
$ApplicationContainslinkedUserPreference = $true
}
$Condition1 = (-not $BuildingBlockContainsLinkedStuff)
$Condition2 = ($BuildingBlockContainsLinkedStuff -and ($ApplicationContainsLinkedActions -or $ApplicationContainslinkedUserPreference))
if ($Condition1 -or $Condition2)
{
Add-EntryToLogFile -Entry "Application contains linked applications: $ApplicationContainsLinkedActions"
Add-EntryToLogFile -Entry "Application contains linked user preferences: $ApplicationContainslinkedUserPreference"
Add-EntryToLogFile -Entry "The following conditions are met:"
if($Condition1)
{
Add-EntryToLogFile -Entry "CONDITION: The building block does not contain any linked stuff."
}
if($Condition2)
{
Add-EntryToLogFile -Entry "CONDITION: The building block contains linked actions and ..."
if($ApplicationContainsLinkedActions)
{
Add-EntryToLogFile -Entry " ... the application contains linked actions."
}
if($ApplicationContainslinkedUserPreference)
{
Add-EntryToLogFile -Entry " ... the application contains linked user settings."
}
}
$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"
$ApplicationContainsLinkedSettings1 = "no"
If($ApplicationContainsLinkedActions)
{
$ApplicationContainsLinkedActions1 = "yes"
}
if($ApplicationContainslinkedUserPreference)
{
$ApplicationContainsLinkedSettings1 = "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 `
-ApplicationContainsLinkedSettings $ApplicationContainsLinkedSettings1 `
-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: