RMS_Support_Tool.psm1

#Requires -Version 5.1

<# ╔═══════════════════════════════════════════════════════════════════════════╗
   ║ WARNING: DO NOT MODIFY OR DELETE ANY COMPONENT OF THE RMS_Support_Tool OR ║
   ║ THE RESULTING TRACE FILES, AS THIS WILL RESULT IN INCORRECT INFORMATION ║
   ║ WHEN ANALYZING YOUR ENVIRONMENT. ║
   ╚═══════════════════════════════════════════════════════════════════════════╝ #>


<# Defining global variables #>
[Version]$Global:strVersion = "1.3.0" <# Defining version #>
$Global:strWindowsEdition = (Get-CimInstance Win32_OperatingSystem).Caption <# Evaluating Windows version #>
$Global:strTempFolder = (Get-Item Env:"Temp").Value <# Defining user temp folder #>
$Global:strUserLogPath = New-Item -ItemType Directory -Force -Path $Global:strTempFolder"\RMS_Support_Tool\Logs" <# Defining default user log path #>
$Global:strDefaultWindowTitle = $Host.UI.RawUI.WindowTitle <# Caching window title #>
$Global:host.UI.RawUI.WindowTitle = "RMS_Support_Tool ($Global:strVersion)" <# Set window title #>
$Global:FormatEnumerationLimit = -1 <# Defining variable to show full Format-List for arrays #>
$Global:strUniqueLogFolder = $null <# Defining variable for unique user log folder; used in fncRecordProblem #>
$Global:MenuAnalyzeExtended = $false <# Defining variable for ANALYZE menu (expand/reduce) handling #>
$Global:MenuCollectExtended = $false <# Defining variable for COLLECTING menu (expand/reduce) handling #>
$Global:bolCommingFromMenu = $false <# Defining control variable for menu handling inside function calls #>

<# Predefine connection settings #>
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
[System.Net.WebRequest]::DefaultWebProxy = [System.Net.WebRequest]::GetSystemWebProxy()
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials

<# Core function definitions for script module #>
Function RMS_Support_Tool {

    <#
    .SYNOPSIS
        The 'RMS Support Tool' provides the functionality to reset all Microsoft® AIP/MIP/AD RMS services.
 
    .DESCRIPTION
        The 'RMS Support Tool' provides the functionality to reset all Microsoft® AIP/MIP/AD RMS services. Its main purpose is to delete the currently downloaded policies and reset the user settings for AIP/MIP/AD RMS service, and it can also be used to collect data for troubleshooting.
 
    .NOTES
        Please find more information on this website about how to use the RMS_Support_Tool:
 
        https://aka.ms/RMS_Support_Tool
 
        Note:
 
        - Please only run RMS_Support_Tool if you have been prompted to do so by a Microsoft® support technician.
        - It is recommended to test the RMS_Support_Tool with a test environment before executing it in a live environment.
        - Do not modify any component of the RMS_Support_Tool in any kind, as this will result in incorrect information in the analysis of your environment.
        - There is no support for the RMS_Support_Tool. Please see the disclaimer below.
        - Nomenclature:
            AIP = Azure Information Protection.
            MSIP/MIP = Microsoft® Information Protection.
            MSIPC = Microsoft® Information Protection Client.
            RMS = Rights Management Service.
            AD RMS = Active Directory Rights Management Service.
 
        MIT LICENSE
        Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 
        DISCLAIMER OF WARRANTY: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PLEASE DO UNDERSTAND THAT THERE IS NO GUARANTEE THAT THIS SOFTWARE WILL RUN WITH ANY GIVEN ENVIRONMENT OR CONFIGURATION. BY INSTALLING AND USING THE SOFTWARE YOU ACCEPT THIS DISCLAIMER OF WARRANTY. IF YOU DO NOT ACCEPT THE TERMS, DO NOT INSTALL OR USE THIS SOFTWARE.
         
        VERSION
        1.3.0
         
        CREATE DATE
        18/05/2020
 
        AUTHOR
        Claus Schiroky
        Customer Service & Support EMEA
        Microsoft Deutschland GmbH
 
        HOMEPAGE
        https://aka.ms/RMS_Support_Tool
 
        SPECIAL THANKS TO
        Matthias Meiling
        Information Protection - EMEA Security Team
        Microsoft Romania SRL
 
        PRIVACY STATEMENT
        https://privacy.microsoft.com/PrivacyStatement
 
        COPYRIGHT
        Copyright® 2020 Microsoft®. All rights reserved.
 
    .PARAMETER Information
        This parameter shows syntax and a description.
 
    .PARAMETER Disclaimer
        This paramter displays the disclaimer of warranty.
        Please read it carefully, and act accordingly.
 
    .PARAMETER Help
        This parameter opens the help file.
 
        Note:
 
        - If you do not have the help file on your local hard drive, it will automatically be downloaded from the internet.
 
    .PARAMETER Reset
        IMPORTANT: Before you proceed with any of the following reset options, close all applications that run or use Microsoft® 365 or AIP/MIP/AD RMS.
        This option removes all AIP/MIP/AD RMS certificates, policy templates and all corresponding registry keys.
 
        Note:
 
        - The default argument for reset via menu is "Client".
        - When any Azure Information Protection client is detected, the built-in labeling client is automatically disabled as a precaution.
        - When an Office 2013 installation is detected, modern authentication (ADAL) is automatically enabled as a precaution.
         
        Valid <String> arguments are: "Client", "Silent", or "Machine":
 
        Client:
 
        This argument removes all AIP/MIP/AD RMS certificates, policy templates and all corresponding user registry keys:
 
        PS C:\> RMS_Support_Tool -Reset Client
 
        This is the recommended argument to reset all Microsoft® AIP/MIP/AD RMS user client settings.
 
        Silent:
 
        This command line-parameter argument does the same as "-Reset Client", but does not print any output - unless an error occurs when attempting to reset:
 
        PS C:\> RMS_Support_Tool -Reset Silent
 
        If a silent reset triggers an error, you can use the additional parameter "-Verbose" to find out more about the cause of the error:
 
        PS C:\> RMS_Support_Tool -Reset Silent -Verbose
 
        You can also review the Script.log file for errors of silent reset.
 
        Machine:
 
        This argument does the same as "-Reset Client", but does also remove all AIP/MIP/AD RMS certificates, policy templates, custom configurations, and all corresponding machine registry keys:
 
        PS C:\> RMS_Support_Tool -Reset Machine
 
        Before, the RMS_Support_Tool creates a backup copy of existing custom configurations from the following registry key:
 
        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSIPC\ServiceLocation]
 
        The name of the backup file is ServiceLocationBackup.reg.
 
        Note:
 
        - You must run the RMS_Support_Tool with administrative permissions to proceed this option. Please request assistance from your administrator.
 
    .PARAMETER RecordProblem
        IMPORTANT: Close all applications that run or use Microsoft® 365 or AIP/MIP/AD RMS before you proceed with this option.
        In a first step, this parameter reset silent the client, then it activates the required logging, tracing or debugging mechanisms by implementing registry settings, and enabling some Windows event logs. This process will be reflected by a progress bar “Enable logging...".
 
        In a second step asks you to reproduce the problem. While you’re doing so, the RMS_Support_Tool collects and records data. Once you have reproduced the problem, all collected files will be stored into the default logs folder (%temp%\RMS_Support_Tool\Logs). Every time you call this option, a new unique subfolder will be created in the logs-folder that reflects the date and time when it was created, e.g. “200318-133005”. While the files are being cached, you will see a progress bar “Collecting logs...".
 
        In the last step, the RMS_Support_Tool resets all activated log, trace, and debug settings to their defaults. This process will be reflected by a progress bar “Disable logging...".
 
        You can then review the log files in the logs folder.
 
        Note:
 
        - You must run the RMS_Support_Tool with administrative permissions to proceed this option. Please request assistance from your administrator.
        - An additional tool from Windows® Sysinternals (DebugView) is required for logging. If you do not have this tool on your local hard drive, it will be automatically downloaded from the internet.
 
    .PARAMETER CollectAipConfig
        This parameter collects AIP service configuration information of your tenant, and AIP service template details.
        Please request assistance from your administrator to proceed this option.
 
        Results are written into the log files AipServiceConfiguration.log and AipServiceTemplates.log in the subfolder "Collect" of the Logs folder. 
 
        Note:
 
        - You must run the RMS_Support_Tool with administrative permissions to proceed this option.
        - You need to know your Microsoft® 365 global administrator account information to proceed with this option, as you will be asked for your credentials.
        - An additional tool from Windows® Sysinternals (DebugView) is required for logging. If you do not have this tool on your local hard drive, it will be automatically downloaded from the internet.
 
    .PARAMETER CollectLabelsAndPolicies
        This parameter collects the labels and policy definitions from your Office 365 Security & Compliance Center (SCC). Those with encryption and those with labeling only.
        Please request assistance from your administrator to proceed this option.
 
        Results are written into log file LabelsAndPolicies.log in the subfolder "Collect" of the Logs folder.
 
        Note:
        - You must run the RMS_Support_Tool with administrative permissions to proceed this option.
        - You need to know your Microsoft® 365 global administrator account information to proceed with this option, as you will be asked for your credentials.
        - The Microsoft® Exchange Online PowerShell V2 cmdlets are required to proceed this option. If you do not have this module installed, RMS_Support_Tool will try to install it from Powershell Gallery.
 
    .PARAMETER AnalyzeEndpointURLs
        This parameter analyzes important enpoint URLs.
        The URLs are taken from your local registry or your tenant's AIP service configuration information, and extended by additional relevant URLs.
 
        In a first step, this parameter is used to check whether you can access the URL.
 
        In a second step, the issuer of the corresponding certificate of the URL is validated.
        This process is represented by an output with the Tenant Id, Endpoint name, URL, Issuer, and the Status of the validation of the certificate issuer. For example:
 
        -----------------------------------------------
        Tenant Id: 48fc04bd-c84b-44ac-91b7-a4c5eefd5ac1
        -----------------------------------------------
 
        Endpoint: CertificationDistributionPointUrl
        URL: https://48fc04bd-c84b-44ac-91b7-a4c5eefd5ac1.rms.na.aadrm.com/_wmcs/certification
        Issuer: C=US, S=Washington, L=Redmond, O=Microsoft Corporation, CN=Microsoft Secure Server CA 2011
        Status: Ok (200)
 
        In addition, analyze results are written into log file EndpointURLs.log in the subfolder "Analyze" of the Logs folder.
 
        Note:
 
        - You must run the RMS_Support_Tool with administrative permissions to proceed this option, if the corresponding Microsoft® 365 desktop applicaiton is not bootstraped. Please request assistance from your administrator.
        - You need to know your Microsoft® 365 global administrator account information to proceed with this option, as you will be asked for your credentials.
 
    .PARAMETER AnalyzeProtection
        This option analyzes whether the current user is able to use protection.
 
        Therefore an ad-hoc protection policy for custom permissions is created, and used to validate the protection with a sample file (AnalyzeProtection.txt). The result is represented by an output with the status of that process. For example:
 
        License : {[Users, RMSSupToolEncrTest@microsoft.com], [Permissons, VIEWER]}
        File : C:\Users\<UserName>\AppData\Local\Temp\RMS_Support_Tool\Logs\Analyze\Protection.ptxt
        Verification : Successfull
 
        In addition, analyze results are written to the Protection.log file, and the resulting protected file (Protection.ptxt) is stored in the Logs folder.
 
        Note:
 
        - Please pay attention to point '1. Microsoft® Azure Information Protection cmdlets (optional)' of the requirements section of the help file.
 
    .PARAMETER CheckForUpdate
        This parameter checks if a new version is available for the RMS_Support_Tool.
 
        If you run the RMS_Support_Tool with administrative permissions, it automatically performs each new update.
 
        Note:
        - Under certain circumstances, you may need to run the RMS_Support_Tool with administrative permissions to perform an update. Please request assistance from your administrator.
        - If the RMS_Support_Tool was not installed via PowerShell Gallery, any older version must first be removed before an update or installation can be performed.
 
    .PARAMETER CompressLogs
        IMPORTANT: This command-line parameter should always be used at the very end of a scenario. Otherwise the compressed .zip file will not be created.
 
        This parameter compress all collected logs files into a .zip file, and the corresponding path and file name is displayed.
        In addition, the default logs folder (%temp%\RMS_Support_Tool\Logs) will be cleaned.
        After this step you can review the log files, and send the collected logs to Microsoft® support technician.
 
    .PARAMETER Menu
        This will start the RMS_Support_Tool with the default menu.
 
    .PARAMETER Version
        This parameter displays the version of the RMS_Support_Tool.
 
    .EXAMPLE
        RMS_Support_Tool -Information
        This shows syntax and description.
 
    .EXAMPLE
        RMS_Support_Tool -Disclaimer
        This displays the disclaimer of warranty.
        Please read it carefully, and act accordingly.
 
    .EXAMPLE
        RMS_Support_Tool -Help
        This parameter opens the help file.
 
    .EXAMPLE
        RMS_Support_Tool -Reset Client
        This parameter removes all AIP/MIP/AD RMS certificates, policy templates and all corresponding user registry keys.
 
    .EXAMPLE
        RMS_Support_Tool -Reset Silent
        This parameter removes all AIP/MIP/AD RMS certificates, policy templates and all corresponding user registry keys without any user output.
 
    .EXAMPLE
        RMS_Support_Tool -Reset Machine
        This parameter removes all AIP/MIP/AD RMS certificates, policy templates, custom configurations, and all corresponding machine registry keys.
 
    .EXAMPLE
        RMS_Support_Tool -RecordProblem
        This parameter enables logging and starts recording data.
 
    .EXAMPLE
        RMS_Support_Tool -CollectAipConfig
        This parameter collects AIP service configuration information of your tenant, and AIP service template details.
 
    .EXAMPLE
        RMS_Support_Tool -CollectLabelsAndPolicies
        This parameter collects the unified labels and policy definitions of your tenant.
 
    .EXAMPLE
        RMS_Support_Tool -AnalyzeEndpointURLs
        This parameter analyzes important enpoint URLs, and the results are written into a file.
        The corresponding path and file name is displayed.
         
    .EXAMPLE
        RMS_Support_Tool -AnalyzeProtection
        This option analyzes whether the current user is able to use protection.
 
    .EXAMPLE
        RMS_Support_Tool -CompressLogs
        This parameter compress all collected logs files into a .zip file, and the corresponding path and file name is displayed.
 
    .EXAMPLE
        RMS_Support_Tool -CheckForUpdate
        This parameter checks if a new version is available for the RMS_Support_Tool.
 
    .EXAMPLE
        RMS_Support_Tool -Reset Machine -RecordProblem -CompressLogs
        This parameter removes all AIP/MIP/AD RMS certificates, policy templates and all corresponding machine registry keys, starts recording data, and compress all collected logs files to a .zip file in the default log folder (%temp%\RMS_Support_Tool).
 
    .EXAMPLE
        RMS_Support_Tool -Menu
        This will start the RMS_Support_Tool with the default menu.
 
    .EXAMPLE
        RMS_Support_Tool -Version
        This parameter displays the version of the RMS_Support_Tool.
 
    .LINK
        https://aka.ms/RMS_Support_Tool
 
    #>


    <# Defining CmdletBinding attribut to define parameter settings #>
    [CmdletBinding (
        HelpURI = "https://aka.ms/RMS_Support_Tool", <# URL for help file; used with parameter Help #>
        PositionalBinding = $false, <# Parameters in the function are not positional #>
        DefaultParameterSetName = "Menu" <# If no parameter has been selected, this will be the default #>
    )]

    <# Parameter definitions #>
    Param (
        
        <# Parameter definition for Information #>
        [Alias("i")]
        [Parameter(ParameterSetName = "Information")]
        [switch]$Information,

        <# Parameter definition for Disclaimer #>
        [Alias("d")]
        [Parameter(ParameterSetName = "Disclaimer")]
        [switch]$Disclaimer,

        <# Parameter definition for Help #>
        [Alias("h")]
        [Parameter(ParameterSetName = "Help")]
        [switch]$Help,

        <# Parameter definition for Reset #>
        [Alias("r")]
        [Parameter(ParameterSetName = "Reset and logging")]
        [ValidateSet("Client", "Machine", "Silent")]
        [string]$Reset="Client",

        <# Parameter definition for RecordProblem #>
        [Alias("p")]
        [parameter(ParameterSetName = "Reset and logging")]
        [switch]$RecordProblem,

        <# Parameter definition for CollectAipConfig #>
        [Alias("a")]
        [Parameter(ParameterSetName = "Reset and logging")]
        [switch]$CollectAipConfig,

        <# Parameter definition for CollectLabelsAndPolicies #>
        [Alias("l")]
        [Parameter(ParameterSetName = "Reset and logging")]
        [switch]$CollectLabelsAndPolicies,

        <# Parameter definition for AnalyzeEndpointURLs #>
        [Alias("u")]
        [Parameter(ParameterSetName = "Reset and logging")]
        [switch]$AnalyzeEndpointURLs,

        <# Parameter definition for AnalyzeProtection #>
        [Alias("t")]
        [Parameter(ParameterSetName = "Reset and logging")]
        [switch]$AnalyzeProtection,

        <# Parameter definition for CheckForUpdate #>
        [Parameter(ParameterSetName = "Update")]
        [switch]$CheckForUpdate,

        <# Parameter definition for CompressLogs, with preset. #>
        [Alias("z")]
        [Parameter(ParameterSetName = "Reset and logging")]
        [switch]$CompressLogs,

        <# Parameter definition for Menu #>
        [Parameter(ParameterSetName = "Menu")]
        [switch]$Menu,

        <# Parameter definition for Version #>
        [Alias("v")]
        [Parameter(ParameterSetName = "Version")]
        [switch]$Version

    )

    <# Action if the parameter '-Information' has been selected #>
    If ($PsCmdlet.ParameterSetName -eq "Information") {

        <# Calling information function #>
        fncInformation

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Information" -strLogValue "Proceeded"

    } 

    <# Action if the parameter '-Disclaimer' has been selected #>
    If ($PSBoundParameters.ContainsKey("Disclaimer")) {
    
        <# Calling disclaimer function #>
        fncDisclaimer
    
        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Disclaimer" -strLogValue "Proceeded"

    }
    
    <# Action if the parameter '-Help' has been selected #>
    If ($PSBoundParameters.ContainsKey("Help")) {

        <# Calling disclaimer function #>
        fncHelp

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Help" -strLogValue "Proceeded"

    }

    <# Action if the parameter '-Reset' has been selected #>
    If ($PSBoundParameters.ContainsKey("Reset")) {

        <# Catching parameter selection #>
        Switch ($Reset) {
            
            "Client" { <# Reset client actions #>
            
                <# Verbose/Logging #>
                fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter Reset client" -strLogValue "Triggered"                

            }
            "Machine" { <# Reset machine actions #>

                <# Verbose/Logging #>
                fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter Reset machine" -strLogValue "Triggered"       

            }
            "Silent" { <# Reset silent actions #>

                 <# Verbose/Logging #>
                fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter Reset silent" -strLogValue "Triggered"

            }

        }

        <# Calling reset function #>
        fncReset -strResetMethod $Reset

    }

    <# Action if the parameter '-RecordProblem' has been selected #>
    If ($PSBoundParameters.ContainsKey("RecordProblem")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter RecordProblem" -strLogValue "Triggered"

        <# Calling record problem function #>
        fncRecordProblem

    }

    <# Action if the parameter '-CollectAipConfig' has been selected #>
    If ($PSBoundParameters.ContainsKey("CollectAipConfig")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter CollectAipConfig" -strLogValue "Triggered"

        <# Calling function to collect AIP configuration #>
        fncCollectAipConfig

    }

    <# Action if the parameter '-CollectLabelsAndPolicies' has been selected #>
    If ($PSBoundParameters.ContainsKey("CollectLabelsAndPolicies")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter CollectLabelsAndPolicies" -strLogValue "Triggered"

        <# Calling function to collect AIP configuration #>
        fncCollectLabelsAndPolicies

    }

    <# Action if the parameter '-AnalyzeEndpointURLs' has been selected #>
    If ($PSBoundParameters.ContainsKey("AnalyzeEndpointURLs")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter AnalyzeEndpointsURLs" -strLogValue "Triggered"

        <# Calling AnalyzeEndpoints function #>
        fncAnalyzeEndpointURLs

    }

    <# Action if the parameter '-AnalyzeProtection' has been selected #>
    If ($PSBoundParameters.ContainsKey("AnalyzeProtection")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter AnalyzeProtection" -strLogValue "Triggered"

        <# Calling AnalyzeProtection function #>
        fncAnalyzeProtection

    }

    <# Action if the parameter 'CheckForUpdate' has been selected #>
    If ($PSBoundParameters.ContainsKey("CheckForUpdate")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter CheckForUpdate" -strLogValue "Triggered"

        <# Calling CheckForUpdate function #>
        fncCheckForUpdate

    }

    <# Action if the parameter '-CompressLogs' has been selected #>
    If ($PSBoundParameters.ContainsKey("CompressLogs")) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Parameter CompressLogs" -strLogValue "Triggered"

        <# Calling function to compress all logs into zip file #>
        fncCompressLogs

        <# Set back window title to default #>
        $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

        <# Exit function #>
        Break

    }

    <# Action if the parameter '-Menu' has been selected; default without any parameter #>
    If ($PsCmdlet.ParameterSetName -eq "Menu") {

        <# Calling function to show menu #>
        fncShowMenu

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Menu" -strLogValue "Proceeded"

    }

    <# Action if the parameter '-Version' has been selected #>
    If ($PSBoundParameters.ContainsKey("Version")) {

        <# Calling function to display version information #>
        fncShowVersion

        <# Verbose/Logging #>
        fncLogging -strLogFunction "RMS_Support_Tool" -strLogDescription "Version" -strLogValue "Proceeded"

    }

}

<# Function that creates some default log enties #>
Function fncCreateDefaultLogEntries {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Script module version" -strLogValue $Global:strVersion <# Script module version #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Windows edition" -strLogValue $Global:strWindowsEdition <# Windows edition #>
    
    <# Verbose/Logging: Windows version #>
    If ((Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\" -Name ReleaseID -ErrorAction SilentlyContinue).ReleaseId) {

        <# Windows version and release ID #>
        fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Windows version" -strLogValue $([System.Environment]::OSVersion.Version) ($((Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\" -Name ReleaseID).ReleaseId))

    }
    Else {

        <# Windows version #>
        fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Windows version" -strLogValue $([System.Environment]::OSVersion.Version)

    }
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Windows architecture" -strLogValue $((Get-CimInstance Win32_OperatingSystem -Verbose:$false).OSArchitecture) <# Windows architecture #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Username" -strLogValue $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name) <# Username #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "Machine name" -strLogValue $([System.Environment]::MachineName) <# Machine name #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell host" -strLogValue $($Host.Name.ToString()) <# PowerShell host #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell version" -strLogValue $($Host.Version.ToString()) <# PowerShell version #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell edition" -strLogValue $($PSVersionTable.PSEdition.ToString()) <# PowerShell edition #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell build version" -strLogValue $($PSVersionTable.BuildVersion) <# PowerShell build version #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell current culture" -strLogValue $($Host.CurrentCulture.ToString()) <# PowerShell current culture #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell current UI culture" -strLogValue $($Host.CurrentUICulture.ToString()) <# PowerShell current UI culture #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell CLR version" -strLogValue $($PSVersionTable.CLRVersion.ToString()) <# PowerShell CRL version #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell WSManStack version" -strLogValue $($PSVersionTable.WSManStackVersion.ToString()) <# PowerShell WSManStack version #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell PSRemotingProtocol version" -strLogValue $($PSVersionTable.PSRemotingProtocolVersion.ToString()) <# PowerShell PSRemotingProtocol version #>
    fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "PowerShell Serialization version" -strLogValue $($PSVersionTable.SerializationVersion.ToString()) <# PowerShell Serialization version #>

    <# Verbose/Logging: AIP client version #>
    If (Get-Module -ListAvailable -Name AzureInformationProtection -Verbose:$false) {

        <# Logging: If AIP client is installed #>
        fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "AIP client version" -strLogValue $((Get-Module -ListAvailable -Name AzureInformationProtection -Verbose:$false).Version)

    }
    Else {

        <# Logging: If AIP client is not installed #>
        fncLogging -strLogFunction "fncCreateDefaultLogEntries" -strLogDescription "AIP client installed" -strLogValue $false

    }

}

<# Function for evaluating the used Windows version (Exit, if an unsupported version is found) #>
Function fncCheckWindowsVersion {

    <# Checking for supported OS versions #>
    If (-Not $Global:strWindowsEdition -Match "Windows 8" -Or
        -Not $Global:strWindowsEdition -Match "Windows 10" -Or
        -Not $Global:strWindowsEdition -Match "2012" -Or
        -Not $Global:strWindowsEdition -Match "Server 2016" -Or
        -Not $Global:strWindowsEdition -Match "Server 2019") {

        <# Clear global variables #>
        $Global:strWindowsEdition = $null

        <# Console output #>
        Write-Output (Write-Host "ATTENTION:`n`nRMS_Support_Tool does not support the operating system you're using.`n`nPlease ensure to use a supported operating system. The RMS_Support_Tool supports the following operating systems:`nMicrosoft® Windows 8, Windows 8.1, Windows 10, Windows Server 2012, Windows Server 2012 R2, Windows Server 2016 and Windows Server 2019.`n" -ForegroundColor Red)

        <# Signal sound #>
        [console]::beep(500,200)

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCheckWindowsVersion" -strLogDescription "Unsupported operating system" -strLogValue $true

        <# Set back window title to default #>
        $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

        <# Exit function #>
        Break

    }

}

<# Function responsable to check for new version #>
Function fncCheckForUpdate { <# Check for latest version of the script module #>

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Update" -strLogValue "Initiated"

    <# Console output #>
    Write-Output "CHECK FOR UPDATE:`n"
    Write-Output "Searching for new version..."

    <# Defining default message for outdated version #>
    $Private:strOutdatedVersionMessage = "ATTENTION:`n`nYou're using an outdated version of the RMS_Support_Tool!`nPlease update to the latest version by running the following command:`n`nPS C:\> Update-Module -Name RMS_Support_Tool -Force`n`nUnder certain circumstances, you may need to run the RMS_Support_Tool with administrative permissions to perform an update. Please request assistance from your administrator.`n`nNote:`n`n- If the RMS_Support_Tool was not installed via PowerShell Gallery, any older version must first be removed before an update or installation can be performed."

    <# Validating connection to PowerShell Gallery by Find-Module #>
    If (Find-Module -Name RMS_Support_Tool -Repository PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) { <# Actions, if PowerShell Gallery can be reached #>

        <# Filling variable with online version information #>
        [Version]$Private:strOnlineVersion = (Find-Module -Name RMS_Support_Tool -Repository PSGallery).Version

        # Comparing local version vs. latest (online) version #>
        If ([Version]::new($Private:strOnlineVersion.Major, $Private:strOnlineVersion.Minor, $Private:strOnlineVersion.Build) -gt [Version]::new($Global:strVersion.Major, $Global:strVersion.Minor, $Global:strVersion.Build) -eq $true) {

            <# Action, if running as administrator #>
            If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -eq $true) {

                <# Update module only if the existing version was installed by PowerShell Gallery #>
                If ((Get-InstalledModule -Name RMS_Support_Tool -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) -eq $true) {

                    <# Console output #>
                    Write-Output "A new version of the RMS_Support_Tool is available."
                    Write-Output "Updating RMS_Support_Tool, please wait..."

                    <# Updating RMS_Support_Tool #>
                    Update-Module -Name RMS_Support_Tool -Force

                    <# Internet availalbe: Console output #>
                    Write-Output (Write-Host "ATTENTION:`n`nA new version of the RMS_Support_Tool has been installed.`nThe RMS_Support_Tool is now terminated.`n`nPlease restart with a new PowerShell session/window." -ForegroundColor Red)

                    <# Verbose/Logging #>
                    fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Script module version" -strLogValue "Updated"

                }
                Else { <# Action, if module was not installed via PowerShell Gallery #>

                    <# Console output #>
                    Write-Output (Write-Host $Private:strOutdatedVersionMessage -ForegroundColor Red)

                    <# Verbose/Logging #>
                    fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Script module version" -strLogValue "Outdated"

                }

            }
            Else { <# Actions, if running without administrative permissions #>

                <# Console output #>
                Write-Output (Write-Host $Private:strOutdatedVersionMessage -ForegroundColor Red)

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Script module version" -strLogValue "Outdated"

            }

            <# Signal sound #>
            [console]::beep(500,200)

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Update" -strLogValue "Proceeded"
            fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Exit script module" -strLogValue $true

            <# Releasing private/global variables #>
            [Version]$Private:strOnlineVersion = $null
            $Global:strWindowsEdition = $null

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Console output #>
            Write-Output (Write-Host "CHECK FOR UPDATE: Proceeded.`n" -ForegroundColor Green)

            <# Exit function #>
            Break

        }
        Else {

            <# Console output #>
            Write-Output "You're using the latest version of the RMS_Support_Tool."

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Script module version" -strLogValue "Latest"

            <# Console output #>
            Write-Output (Write-Host "CHECK FOR UPDATE: Proceeded.`n" -ForegroundColor Green)

        }

    }
    Else { <# Actions, if PowerShell Gallery can not be reached (no internet connection) #>

        <# Console output #>
        Write-Output (Write-Host "ATTENTION:`n`nChecking for update could not be performed.`nEither the website cannot be reached or there is no internet connection.`n`nYou are using version: $Global:strVersion.`n`nPlease check on the following website if you are using the latest version of the RMS_Support_Tool, and update if necessary:`nhttps://aka.ms/RMS_Support_Tool/Latest" -ForegroundColor Red)

        <# Signal sound #>
        [console]::beep(500,200)

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Update" -strLogValue "No internet connection"

        <# Console output #>
        Write-Output (Write-Host "CHECK FOR UPDATE: Proceeded.`n" -ForegroundColor Green)

        <# Console output with pause #>
        fncPause

    }

    <# Signal sound #>
    [console]::beep(1000,200)

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCheckForUpdate" -strLogDescription "Update" -strLogValue "Proceeded"

    <# Releasing private variables #>
    [Version]$Private:strOnlineVersion = $null

}

<# Function that creates single log entries for log file and verbose output #>
Function fncLogging ($strLogFunction, $strLogDescription, $strLogValue) {

    <# Checking if path exist and create it if not #>
    If ($(Test-Path -Path $Global:strUserLogPath) -Eq $false) {

        New-Item -ItemType Directory -Force -Path $Global:strUserLogPath | Out-Null <# Defining default user log path #>

    }

    <# Verbose output #>
    Write-Verbose "$(Get-Date -UFormat "%Y-%m-%d"), $(Get-Date -UFormat "%H:%M"), $strLogFunction, $strLogDescription, $strLogValue"

    <# Write (append) verbose output to log file #>
    Write-Verbose "$(Get-Date -UFormat "%Y-%m-%d"), $(Get-Date -UFormat "%H:%M"), $strLogFunction, $strLogDescription, $strLogValue" -ErrorAction SilentlyContinue -Verbose 4>> $Global:strUserLogPath"\Script.log" 

}

<# Function to show information #>
Function fncInformation {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncInformation" -strLogDescription "Information" -strLogValue "Called"

    <# Action, if function was called from command-line #>
    If ($Global:bolCommingFromMenu -eq $false) {

        <# Call Information #>
        Get-Help -Verbose:$false RMS_Support_Tool

    }

    <# Action, if function was called from the menu #>
    If ($Global:bolCommingFromMenu -eq $true) {
    
        <# Console output #>
        Write-Output "NAME:`nRMS_Support_Tool`n`nDESCRIPTION:`nThe RMS_Support_Tool provides the functionality to reset all Microsoft® AIP/MIP/AD RMS services. Its main purpose is to delete the currently downloaded policies and reset the user settings for AIP/MIP/AD RMS service, and it can also be used to collect data for troubleshooting.`n`nVERSION:`n$Global:strVersion`n`nAUTHOR:`nClaus Schiroky`nCustomer Service & Support EMEA`nMicrosoft Deutschland GmbH`n`nHOMEPAGE:`nhttps://aka.ms/RMS_Support_Tool`n`nSPECIAL THANKS TO:`nMatthias Meiling`nInformation Protection - EMEA Security Team`nMicrosoft Romania SRL`n`nPRIVACY STATEMENT:`nhttps://privacy.microsoft.com/PrivacyStatement`n`nCOPYRIGHT:`nCopyright® 2020 Microsoft®. All rights reserved.`n"

    }

}

<# Function to show disclaimer #>
Function fncDisclaimer {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisclaimer" -strLogDescription "Disclaimer" -strLogValue "Called"

    <# Console output #>
    Write-Output (Write-Host "ATTENTION:`n`nDISCLAIMER OF WARRANTY: THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PLEASE DO UNDERSTAND THAT THERE IS NO GUARANTEE THAT THIS SOFTWARE WILL RUN WITH ANY GIVEN ENVIRONMENT OR CONFIGURATION. BY INSTALLING AND USING THE SOFTWARE YOU ACCEPT THIS DISCLAIMER OF WARRANTY. IF YOU DO NOT ACCEPT THE TERMS, DO NOT INSTALL OR USE THIS SOFTWARE.`n`nNote:`n`n- Please only run RMS_Support_Tool if you have been prompted to do so by a Microsoft® support technician.`n- It is recommended to test the RMS_Support_Tool with a test environment before executing it in a live environment.`n- Do not modify any component of the RMS_Support_Tool in any kind, as this will result in incorrect information in the analysis of your environment.`n- There is no support for the RMS_Support_Tool.`n- Before using the RMS_Support_Tool, please ensure to read its manual:`n https://aka.ms/RMS_Support_Tool`n" -ForegroundColor Red)

}

<# Function to show help file #>
Function fncHelp {

    <# Action, if help file can be found in script module folder #>
    If ($(Test-Path $Private:PSScriptRoot"\RMS_Support_Tool.htm") -Eq $true) {

        <# Open help file #>
        Invoke-Item $Private:PSScriptRoot"\RMS_Support_Tool.htm"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncHelp" -strLogDescription "Help" -strLogValue "Called"

    }

    <# Action, if help file can't be found in script module folder #>
    If ($(Test-Path $Private:PSScriptRoot"\RMS_Support_Tool.htm") -Eq $false) {

        <# Checking, internet connection is available #>
        If ($(fncTestInternetAccess "github.com") -Eq $true) {

            <# Call online help; Set by HelpURI in CmdletBinding #>
            Get-Help -Verbose:$false RMS_Support_Tool -Online        

            <# Internet availalbe: Download helpfile from URL #>
            Invoke-WebRequest -Uri "https://aka.ms/RMS_Support_Tool/Help" -OutFile "$Private:PSScriptRoot\RMS_Support_Tool.htm"

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncHelp" -strLogDescription "Help" -strLogValue "Downloaded"
            fncLogging -strLogFunction "fncHelp" -strLogDescription "Help" -strLogValue "Called"

        }
        Else { <# Action, if web site is not unavailable or if there's no internet connection #>

            <# Console output #>
            Write-Output (Write-Host "ATTENTION:`n`nThe help file (RMS_Support_Tool.htm) could not be downloaded.`nEither the website cannot be reached or there is no internet connection.`n`nNote:`n`n- If you’re working in an environment that does not have internet access, you must download the file manually, before proceeding the RMS_Support_Tool.`n- You must place the file to the location where you have stored the RMS_Support_Tool files.`n- Please download the file from the following hyperlink (from a machine where you have internet access):`n https://aka.ms/RMS_Support_Tool/Latest`n" -ForegroundColor Red)

            <# Signal sound #>
            [console]::beep(500,200)

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncHelp" -strLogDescription "Help" -strLogValue "No internet connection"

        }

    }

}

<# Function to check if script is running with administrative permissions #>
Function fncCheckForAdminPermissions ($Private:strOption) {

    <# Check, if running as admin #>
    If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -eq $false) {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCheckForAdminPermissions" -strLogDescription $Private:strOption -strLogValue "Failed"

        <# Console output #>
        Write-Output (Write-Host "ATTENTION: You must run the RMS_Support_Tool with administrative permissions to proceed this option!" -ForegroundColor Red)

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {

            <# Signal sound #>
            [console]::beep(500,200)

            <# Console output #>
            Write-Output (Write-Host "$Private:strOption Failed!`n" -ForegroundColor Red)

            <# Calling pause function #>
            fncPause
    
            <# Clearing console #>
            Clear-Host

            <# Calling show menu function #>
            fncShowMenu

        }

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {
    
            <# Signal sound #>
            [console]::beep(500,200)

            <# Console output #>
            Write-Output (Write-Host "$Private:strOption Failed!`n" -ForegroundColor Red)

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Interrupting, because of missing admin permissions #>
            Break

        }

    }

    <# Releasing private variable #>
    $Private:strOption = $null

}

<# Function to reset all Microsoft® AIP/MIP/AD RMS services for the current user #>
Function fncReset ($strResetMethod) {

    <# Checking if running as administrator for machine reset and quit if not #>
    If ($strResetMethod -eq "Machine") {

        <# Checking if running as administrator #>
        fncCheckForAdminPermissions("RESET:`n")

    }

    <# Action, if function was not called silent from command-line #>
    If ($strResetMethod -notmatch "Silent") {

        <# Console output #>
        Write-Output "RESET:`nResetting AIP/MIP/AD RMS services, please wait..."

    }
    Else { <# Action, if function was called with silent argument #>

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncReset" -strLogDescription "Reset silent" -strLogValue "Initiated"

    }

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncReset" -strLogDescription "Reset client" -strLogValue "Initiated"

    <# Additional actions to proceed machine reset #>
    If ($strResetMethod -eq "Machine") {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncReset" -strLogDescription "Reset machine" -strLogValue "Initiated"

        <# If "registry overrides" exist, create a backup copy #>
        If ($(Test-Path -Path "HKLM:\SOFTWARE\Microsoft\MSIPC\ServiceLocation") -Eq $true) {

            <# Backup registry settings to a reg file #>
            REG EXPORT "HKLM\SOFTWARE\Microsoft\MSIPC\ServiceLocation" $Private:PSScriptRoot\Logs\ServiceLocationBackup.reg /Y | Out-Null

            <# Console output #>
            Write-Output "Your ServiceLocation registry settings were stored to"$Private:PSScriptRoot\Logs\ServiceLocationBackup.reg

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncReset" -strLogDescription "Export ServiceLocation backup" -strLogValue "ServiceLocationBackup.reg"

        }

        # Deleting client registry keys #>
        fncDeleteItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSIPC"
        fncDeleteItem "HKLM:\SOFTWARE\Microsoft\MSIPC"
        fncDeleteItem "HKLM:\SOFTWARE\Microsoft\MSDRM"
        fncDeleteItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSDRM"
        fncDeleteItem "HKLM:\SOFTWARE\WOW6432Node\Microsoft\MSIP"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncReset" -strLogDescription "Reset machine" -strLogValue "Proceeded"

    }

    <# Deleting client user registry keys #>
    fncDeleteItem "HKCU:\SOFTWARE\Classes\Local Settings\Software\Microsoft\MSIPC"
    fncDeleteItem "HKCU:\SOFTWARE\Classes\Local Settings\Software\Microsoft\AIPMigration"
    fncDeleteItem "HKCU:\SOFTWARE\Classes\Microsoft.IPViewerChildMenu"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\14.0\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\XPSViewer\Common\DRM"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\MSIP"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL"

    <# Force update group policy settings #>
    Echo Y | gpupdate /force | Out-Null

    <# Deleting client classes registry keys #>
    fncDeleteItem "HKCR:\AllFilesystemObjects\shell\Microsoft.Azip.Inspect"
    fncDeleteItem "HKCR:\AllFilesystemObjects\shell\Microsoft.Azip.RightClick"

    <# Deleting/cleaning client folders in file system #>
    fncDeleteItem "\\?\$env:LOCALAPPDATA\Microsoft\MSIP"
    fncDeleteItem "\\?\$env:LOCALAPPDATA\Microsoft\MSIPC"
    fncDeleteItem "\\?\$env:LOCALAPPDATA\Microsoft\DRM"

    <# Checking for Office 2013, and enable modern authentication if installed #>
    If ($(fncCheckForOffice2013) -Eq $true) { 

        <# Check for Office 2013 registry key #>
        If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0") -Eq $true) {
    
            <# Create registry key (overwrite) #>
            New-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Identity" -ErrorAction SilentlyContinue | Out-Null
    
            <# Implement registry settings to enable modern authentication for Office 2013 #>
            New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Identity" -Name "EnableADAL" -Value 1 -PropertyType DWord -ErrorAction SilentlyContinue | Out-Null
            New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Identity" -Name "Version" -Value 1 -PropertyType DWord -ErrorAction SilentlyContinue | Out-Null
    
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncReset" -strLogDescription "ADAL for Office 2013" -strLogValue "Enabled"

        }

    }

    <# Detect any AIP client and disable built-in labeling functionality as precaution #>
    If (Get-Module -ListAvailable -Name AzureInformationProtection) {

        <# Checking if Microsoft® 365 is available #>
        If ($(Test-Path -Path "HKCU:\Software\Microsoft\Office") -Eq $true) {

            <# Checking for corresponding registry key #>
            If (-not (Get-ItemProperty -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Security\Labels" -Name "UseOfficeForLabelling" -ErrorAction SilentlyContinue).UseOfficeForLabelling) {

                <# Check if path exist, and create if not #>
                If ($(Test-Path -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Security\Labels") -Eq $false) {
    
                    <# Create registry key (overwrite) #>
                    New-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Security" -ErrorAction SilentlyContinue | Out-Null
                    New-Item -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Security\Labels" -ErrorAction SilentlyContinue | Out-Null

                }

                <# Set registry key to disable built-in labeling functionality #>
                New-ItemProperty -Path "HKCU:\Software\Microsoft\Office\16.0\Common\Security\Labels" -Name "UseOfficeForLabelling" -Value 0 -PropertyType DWord -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null

                <# Logging #>
                fncLogging -strLogFunction "fncReset" -strLogDescription "UseOfficeForLabelling" -strLogValue "Disabled"

            }

        }

    }

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncReset" -strLogDescription "Reset client" -strLogValue "Proceeded"

    <# Action, if function was not called silent from command-line #>
    If ($strResetMethod -notmatch "Silent") {

        <# Console output #>
        Write-Output (Write-Host "RESET: Proceeded`n" -ForegroundColor Green)

    }
    Else { <# Action, if function was called with silent argument #>

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncReset" -strLogDescription "Reset silent" -strLogValue "Proceeded"

    }

    <# Signal sound #>
    [console]::beep(1000,200)

}

<# Function to check, if Office 2013 is installed; used to enable ADAL at reset #>
Function fncCheckForOffice2013 {

    <# Looping through uninstall registry key to find any Office application #>
    Get-ChildItem -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall" -Name | ForEach-Object {

        <# Checking for Office applications/GUIDs #>
        If ($_.ToString() -like "*0000000FF1CE}") {

            <# Checking for major version '15' = Office 2013 #>
            If (Get-ItemProperty $_.PSPath | Where-Object {$_.VersionMajor -eq "15"}) {

                <# Returning 'true', if an Office 2013 applictation was found #>
                Return $true

                <# Set back window title to default #>
                $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle                

                <# Leaving ForEach loop #>
                Break

            }
            Else {

                <# Returning 'false', if no Office 2013 applictation was found #>
                Return $false

                <# Set back window title to default #>
                $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle
                
                <# Leaving ForEach loop #>
                Break

            }

        }

    }

}

<# Function to delete item/s or folders (with IO error handling); used in fncReset, and fncDisableLogging #>
Function fncDeleteItem ($Private:objItem) {

    Try {

        <# Checking if key, file or folder exist and proceed with related actions #>
        If ($(Test-Path -Path $Private:objItem) -Eq $true) {

            <# Deleting folder or registry key #>
            Remove-Item -Path $Private:objItem -Recurse -Force -ErrorAction Stop | Out-Null
           
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncDeleteItem" -strLogDescription "Item deleted" -strLogValue $Private:objItem.TrimStart("\\?\")

        }

    }
    Catch [System.IO.IOException] { <# Actions, if files or folders cannot be accessed, because they are locked/used by another process <#>

        <# Console output #>
        Write-Output (Write-Host "WARNING: Some items or folders are still used by another process.`nIMPORTANT: Close all applications that run or use Microsoft® 365 or AIP/MIP/AD RMS and try again." -ForegroundColor Red)

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncDeleteItem" -strLogDescription "Item locked" -strLogValue $Private:objItem.TrimStart("\\?\")
        fncLogging -strLogFunction "fncDeleteItem" -strLogDescription "Reset" -strLogValue "ERROR: Reset failed"

        <# Releasing private variable #>
        $Private:objItem = $null

        <# Action, if function was not called from the menu #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Console output #>
            Write-Output (Write-Host "RESET: Failed!`n" -ForegroundColor Red)

            <# Signal sound #>
            [console]::beep(500,200)

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Interrupting Reset #>
            Break

        }
        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {

            <# Console output #>
            Write-Output (Write-Host "RESET: Failed!`n" -ForegroundColor Red)

            <# Signal sound #>
            [console]::beep(500,200)

            <# Console output with pause #>
            fncPause

            <# Calling menu #>
            fncShowMenu

        }

    }

    <# Releasing private variable #>
    $Private:objItem = $null

}

<# Function to copy item/s (with error handler); used in fncCollectLogging #>
Function fncCopyItem ($Private:objItem, $Private:strDestination, $Private:strFileName) {

    Try {

        <# Checking if path exist and proceed with file copy #>
        If ($(Test-Path -Path $Private:objItem) -Eq $true) {

            <# Copy item/s #>
            Copy-Item -Path $Private:objItem -Destination $Private:strDestination -Recurse -Force -ErrorAction Stop | Out-Null
            
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCopyItem" -strLogDescription "Item copied" -strLogValue $Private:strFileName

        }

    }
    Catch [System.IO.IOException] { <# Action, if file cannot be accessed, because it's locked/used by another process <#>

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCopyItem" -strLogDescription "Item locked" -strLogValue "ERROR: "$Private:objItem

        <# Releasing private variable #>
        $Private:objItem = $null
        $Private:strDestination = $null

    }

    <# Releasing private variable #>
    $Private:objItem = $null
    $Private:strDestination = $null

}

<# Function to check for internet access #>
Function fncTestInternetAccess ($Private:strURL) {

    <# Checking, if internet access is available #>
    If ($(Test-Connection $Private:strURL -Count 1 -Quiet) -Eq $true) {

        <# Return true, if we have internet access #>
        Return $true
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncTestInternetAccess" -strLogDescription "Internet access" -strLogValue $true

    }
    Else {

        <# Return false, if we do not have internet access #>
        Return $false
       
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncTestInternetAccess" -strLogDescription "Internet access" -strLogValue $false

    }

    <# Releasing private variable #>
    $Private:strURL = $null

}

<# Function to record data/problem #>
Function fncRecordProblem {
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncRecordProblem" -strLogDescription "Record problem" -strLogValue "Initiated"

    <# Console output #>
    Write-Output "RECORD PROBLEM:"

    <# Console output #>
    Write-Output (Write-Host "ATTENTION: Before you proceed with this option, close all applications that run or use Microsoft® 365 or AIP/MIP/AD RMS!" -ForegroundColor Red)
    $Private:ReadHost = Read-Host "Only if the above is true, please press [Y]es to continue, or [N]o to cancel"

    <# Checking if running as administrator #>
    fncCheckForAdminPermissions("RECORD PROBLEM:")

    <# Actions, if yes was selected #>
    If ($Private:ReadHost -Eq "Y") {
    
        <# Console output #>
        Write-Output "Initializing, please wait..."

        <# Variables for unique log folder #>    
        $Private:strUniqueFolderName = (Get-Date -Verbose:$false -UFormat "%y%m%d-%H%M%S")
        $Global:strUniqueLogFolder = $Global:strUserLogPath.ToString() + "\" +  $Private:strUniqueFolderName.ToString()

        <# Create unique log folder #>
        New-Item -ItemType Directory -Force -Path $Global:strUniqueLogFolder | Out-Null
   
        <# Verbose/Logging #>
        fncLogging "fncRecordProblem" -strLogDescription "New log folder created" -strLogValue $Private:strUniqueFolderName

        <# Reset client to ensure to catch only problem scenario #>
        fncReset -strResetMethod Silent -ErrorAction SilentlyContinue -WarningAction SilentlyContinue

        <# Calling function to enable logging #>
        fncEnableLogging

        <# Console output #>
        Write-Output "Record problem enabled."
        Write-Output (Write-Host "IMPORTANT: Now start to reproduce your problem, but leave this window open." -ForegroundColor Red)
        Read-Host "After reproducing the problem, close all applications you have used for, then come back here and press enter to continue"

        <# Console output #>
        Write-Output "Collecting logs, please wait...`n"

        <# Calling function to collect log files #>
        fncCollectLogging
    
        <# Function to disable/rool back logging settings #>
        fncDisableLogging

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncRecordProblem" -strLogDescription "Record problem" -strLogValue "Proceeded" 

        <# Console output #>
        Write-Output "Log files: $Global:strUniqueLogFolder"
        Write-Output (Write-Host "RECORD PROBLEM: Proceeded.`n" -ForegroundColor Green)

        <# Releasing variable to to able to use again on n #>
        $Global:strUniqueLogFolder = $null

        <# Signal sound #>
        [console]::beep(1000,200)

    }
    <# Actions, if no (cancel) was selected #>
    ElseIf ($Private:ReadHost -eq "N") {

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {

            <# Clearing console #>
            Clear-Host

            <# Calling show menu function #>
            fncShowMenu    

        }

    }
    Else { <# Actions, if any other key was pressed #>

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {
 
            <# Clearing console #>
            Clear-Host
 
            <# Calling show menu function #>
            fncShowMenu    
 
        }

    }

    <# Releasing private variables #>
    $Private:ReadHost = $null

}

<# Function to initialize/enable logging #>
Function fncEnableLogging {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Enable logging" -strLogValue "Triggered"

    <# Progress bar #>
    Write-Progress -Activity " Enable logging..." -PercentComplete 0
    Write-Progress -Activity " Enable logging: Office logging..." -PercentComplete (100/11 * 1)

    <# Enable Office logging for 2013 (15.o), 2016 (16.o) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Logging") -Eq $false) { <# Check for registry key 'Logging' (2016) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Logging" -Force | Out-Null

    }

    <# Check for registry key 'Logging' (2013) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Logging") -Eq $false) { <# Check for registry key 'Logging' (2013) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Logging" -Force | Out-Null

    }

    <# Check for registry key 'Logging' (2016 x64) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\Logging") -Eq $false) { <# Check for registry key 'Logging' (2016 x64) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\Logging" -Force | Out-Null

    }

    <# Check for registry key 'Logging' (2013 x64) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\Logging") -Eq $false) { <# Check for registry key 'Logging' (2013 x64) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\Logging" -Force | Out-Null

    }

    <# Implementing registry settings to enable logging for the different Office versions #>
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Logging" -Name "EnableLogging" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Logging" -Name "MsoEtwTracingEnabled" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Logging" -Name "EnableLogging" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Logging" -Name "MsoEtwTracingEnabled" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\Logging" -Name "EnableLogging" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\Logging" -Name "MsoEtwTracingEnabled" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\Logging" -Name "EnableLogging" -Value 1 -PropertyType DWord -Force | Out-Null
    New-ItemProperty -Path "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\Logging" -Name "MsoEtwTracingEnabled" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Office Logging" -strLogValue "Enabled"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: Office TCOTrace logging..." -PercentComplete (100/11 * 2)

    <# Cleaning Office TCOTrace logs #>
    If ($(Test-Path $env:LOCALAPPDATA\Microsoft\Office\MsoLogs) -Eq $true) {

        <# Cleaning log file folder #>
        Remove-Item "\\?\$env:LOCALAPPDATA\Microsoft\Office\MsoLogs" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Cleaning Office logs" -strLogValue "Proceeded"

    }

    <# Enable Office TCOTrace logging for 2010 (14.0), 2013 (15.o), 2016 (16.o) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Debug") -Eq $false) { <# Check for registry key 'Debug' (2016) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Debug" -Force | Out-Null

    }
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Debug" -Name "TCOTrace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Check for registry key 'Debug' (2013) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Debug") -Eq $false) { <# Check for registry key 'Debug' (2013) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Debug" -Force | Out-Null

    }
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Debug" -Name "TCOTrace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Check for registry key 'Debug' (2010) #>
    If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\Office\14.0\Common\Debug") -Eq $false) { <# Check for registry key 'Debug' (2010) #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKCU:\SOFTWARE\Microsoft\Office\14.0\Common\Debug" -Force | Out-Null

    }
    New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Office\14.0\Common\Debug" -Name "TCOTrace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Office TCOTrace" -strLogValue "Enabled"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: Cleaning MSIP/MSIPC logs..." -PercentComplete (100/11 * 3)

    <# Cleaning MSIP/MSIPC/AIP v2 logs folder content #>
    If ($(Test-Path -Path $env:LOCALAPPDATA\Microsoft\MSIP\Logs) -Eq $true) { <# If foler exist #>

        <# Cleaning MSIP/AIP v1/2 log folder content #>
        Remove-Item -Path "\\?\$env:LOCALAPPDATA\Microsoft\MSIP\Logs" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIP log folder" -strLogValue "Cleared"

    }

    <# If foler exist #>
    If ($(Test-Path -Path $env:LOCALAPPDATA\Microsoft\MSIPC\Logs) -Eq $true) {

        <# Cleaning MSIPC log folder content #>
        Remove-Item -Path "\\?\$env:LOCALAPPDATA\Microsoft\MSIPC\Logs" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIPC log folder" -strLogValue "Cleared"

    }

    <# If foler exist #>
    If ($(Test-Path -Path $env:LOCALAPPDATA\Microsoft\MSIP\mip) -Eq $true) {

        <# Cleaning MIP SDK/AIP v2 log folder content #>
        Remove-Item -Path "\\?\$env:LOCALAPPDATA\Microsoft\MSIP\mip" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MIP log folder" -strLogValue "Cleared"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: CAPI2 event logging..." -PercentComplete (100/11 * 4)

    <# Enable CAPI2 event log #>
    Echo Y | wevtutil set-log Microsoft-Windows-CAPI2/Operational /enabled:True
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "CAPI2 event log" -strLogValue "Enabled"

    <# Clear CAPI2 event log #>
    wevtutil.exe clear-log Microsoft-Windows-CAPI2/Operational
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "CAPI2 event log" -strLogValue "Cleared"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: Flushing DNS..." -PercentComplete (100/11 * 5)

    <# Flush DNS #>
    ipconfig.exe /flushdns | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Flush DNS" -strLogValue "Called"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: Starting network trace..." -PercentComplete (100/11 * 6)

    <# Start network trace #>
    netsh.exe trace start capture=yes scenario=NetConnection,InternetClient sessionname="RMS_Support_Tool-Trace" report=disabled maxsize=1024, tracefile=$Global:strUniqueLogFolder"\NetMon.etl" | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Network trace" -strLogValue "Started"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: Starting PSR..." -PercentComplete (100/11 * 7)

    <# Start PSR #>
    psr.exe /gui 0 /start /output $Global:strUniqueLogFolder"\ProblemSteps.zip"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "PSR" -strLogValue "Started"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: MSIPC/MSIP logging..." -PercentComplete (100/11 * 8)

    <# Enable RMS-MSIPC event log #>
    If ([System.Diagnostics.EventLog]::Exists('Microsoft-RMS-MSIPC/Debug') -Eq $true) { <# Actions when RMS-MSIPC event log exist #>

        <# Ensure to have Microsoft-RMS-MSIPC/Debug event log enabled #>
        Echo Y | wevtutil set-log "Microsoft-RMS-MSIPC/Debug" /enabled:true /retention:false /maxsize:153600
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Microsoft-RMS-MSIPC/Debug logging" -strLogValue "Enabled"

    }

    <# Enable MSIPC/MSIP logging (DbgView) #>
    If ($(Test-Path -Path "HKLM:\SOFTWARE\Microsoft\MSIPC") -Eq $false) { <# Check for registry key #>

        <# Create registry key, if does not exist #>
        New-Item -Path "HKLM:\SOFTWARE\Microsoft\MSIPC" -Force | Out-Null

    }
    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSIPC" -Name "Trace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Check for registry key #>
    If ($(Test-Path -Path "HKLM:\SOFTWARE\Microsoft\MSDRM") -Eq $false) {

        <# Create registry key, if does not exist #>
       New-Item -Path "HKLM:\SOFTWARE\Microsoft\MSDRM" -Force | Out-Null

    }
    New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSDRM" -Name "Trace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Check for registry key #>
    If ($(Test-Path -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSIPC") -Eq $false) {

        <# Create registry key, if does not exist #>
        New-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSIPC" -Force | Out-Null

    }
    New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSIPC" -Name "Trace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Check for registry key #>
    If ($(Test-Path -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSDRM") -Eq $false) {

        <# Create registry key, if does not exist #>
        New-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSDRM" -Force | Out-Null

    }
    New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSDRM" -Name "Trace" -Value 1 -PropertyType DWord -Force | Out-Null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIPC/MSIP logging" -strLogValue "Enabled"

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: MSOIdentityCRL logging..." -PercentComplete (100/11 * 9)

    <# Enabling and activating MSOIdentityCRL (MSOIDSVC = Microsoft Online Services Sign-in Assistant) trace if service exist #>
    If (Get-Service "MSOIDSVC" -ErrorAction SilentlyContinue) { <# Checking if service exist #>

        <# Checking for Trace keys in registry and create keys if they do not exist #>
        If ($(Test-Path -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace") -Eq $false) { <# Check for registry key #>

            <# Create registry key #>
            New-Item -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Force | Out-Null

        }

        <# Check for registry key #>
        If ($(Test-Path -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace") -Eq $false) {

            <# Create registry key #>
            New-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Force | Out-Null

        }

        <# Check for registry key #>
        If ($(Test-Path -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace") -Eq $false) {

            <# Create registry key #>
            New-Item -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Force | Out-Null

        }

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSOIdentityCRL default registry keys" -strLogValue "Created"

        <# Checking if servcie is running and acting accordingly #>
        If ((Get-Service "MSOIDSVC").Status -Eq "Running") { <# Action, if service is running #>

            <# Stop service #>
            Stop-Service -Name "MSOIDSVC"
            
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSOIdentityCRL service" -strLogValue "Stopped"

        }

        <# Create trace registry keys/settings #>
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "Folder" -Value $Global:strUniqueLogFolder"\MSOTrace" -PropertyType String -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "Flags" -Value "1" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "level" -Value "99" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "maxsize" -Value "10485760" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Name "Folder" -Value $Global:strUniqueLogFolder"\MSOTrace" -PropertyType String -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Name "Flags" -Value "1" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Name "level" -Value "99" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Name "maxsize" -Value "10485760" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "Folder" -Value $Global:strUniqueLogFolder"\MSOTraceLite" -PropertyType String -Force | Out-Null
        New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "Flags" -Value "1" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "level" -Value "99" -PropertyType DWord -Force | Out-Null
        New-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Name "maxsize" -Value "10485760" -PropertyType DWord -Force | Out-Null

        <# Start service #>
        Start-Service -Name "MSOIDSVC"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSOIdentityCRL service" -strLogValue "Started"

    }
    Else { <# Action, if service is not available #>

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSOIdentityCRL service" -strLogValue "Not found"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Enable logging: Starting MSIPC/MSIP logging..." -PercentComplete (100/11 * 10)

    <# Starting MSIPC/MSIP logging (DbgView) #>
    If ($(Test-Path $Private:PSScriptRoot"\DebugView\Dbgview.exe") -Eq $true) { <# Action, if DebugView.exe can be found in script module folder #>

        <# Start executable #>
        Start-Process $Private:PSScriptRoot"\DebugView\Dbgview.exe" -ArgumentList "/g", "/t", "/l", "`"$Global:strUniqueLogFolder\MSIPC-DebugView.log"`
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIPC/MSIP logging: DebugView" -strLogValue "Started"

    }

    <# Action, if DebugView.exe can't be found in script module folder #>
    If ($(Test-Path $Private:PSScriptRoot"\DebugView\Dbgview.exe") -Eq $false) {

        <# Console output #>
        Write-Output "Downloading DebugView, please wait..."

        <# Checking, internet connection is available #>
        If ($(fncTestInternetAccess "download.sysinternals.com") -Eq $true) {
            
            <# Download DebugView from sysinternals #>
            Invoke-WebRequest -Uri "https://download.sysinternals.com/files/DebugView.zip" -OutFile "$Private:PSScriptRoot\DebugView.zip"
            
            <# Expand archive to needed subfolder #>
            Expand-Archive -Path $Private:PSScriptRoot\DebugView.zip -DestinationPath "$Private:PSScriptRoot\DebugView" -Force
            
            <# Remove downloaded file #>
            Remove-Item "\\?\$Private:PSScriptRoot\DebugView.zip" -Recurse -Force | Out-Null

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIPC/MSIP logging: DebugView" -strLogValue "Downloaded"

            <# Open executable file #>
            Start-Process $Private:PSScriptRoot"\DebugView\Dbgview.exe" -ArgumentList "/g", "/t", "/l", "`"$Global:strUniqueLogFolder\MSIPC-DebugView.log"`
            
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIPC/MSIP logging: DebugView" -strLogValue "Started"

        }
        Else { <# Action, if web site is not unavailable or if there's no internet connection #>

            <# Console output #>
            Write-Output (Write-Host "ATTENTION:`n`nThe tool 'DebugView' could not be downloaded.`nEither the website cannot be reached or there is no internet connection.`n`nIMPORTANT: If you’re working in an environment that does not have internet access, you must download the file manually, before proceeding the RMS_Support_Tool.`n`nThe file must be uncompressed into the subfolder 'DebugView' to the location where you have stored the RMS_Support_Tool files.`n`nPlease download the file from the following hyperlink (from a machine where you have internet access):`nhttps://download.sysinternals.com/files/DebugView.zip`n" -ForegroundColor Red)

            <# Signal sound #>
            [console]::beep(500,200)

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "MSIPC/MSIP logging: DebugView" -strLogValue "No internet connection"

            <# Function to disable/rool back all logging settings #>
            fncDisableLogging

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Logging" -strLogValue "Operation canceled"

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

    }

    <# Cleaning temp folder for office.log (TCOTrace) #>
    If ($(Test-Path $Global:strTempFolder"\office.log") -Eq $true) {
    
        <# Removing file office.log #>
        Remove-Item -Path "\\?\$Global:strTempFolder\office.log" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Office TCOTrace temp file" -strLogValue "Cleared"
    
    }

    <# Progress bar update #>
    Write-Progress -Activity " Logging enabled" -Completed

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncEnableLogging" -strLogDescription "Enable logging" -strLogValue "Proceeded" 

}

<# Function to disable/rool back all logging settings #>
Function fncDisableLogging {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "Disable logging" -strLogValue "Triggered" 

    <# Progress bar #>
    Write-Progress -Activity " Disable logging..." -PercentComplete 0

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: Office logging..." -PercentComplete (100/9 * 1)

    <# Disable Office logging for 2013 (15.o), 2016 (16.o) #>
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\15.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\Logging"
    fncDeleteItem "HKCU:\SOFTWARE\Wow6432Node\Microsoft\Office\16.0\Common\Logging"

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "Office Logging" -strLogValue "Disabled"

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: Office TCOTrace..." -PercentComplete (100/9 * 2)

    <# Disable Office TCOTrace logging for 2010 (14.0), 2013 (15.o), 2016 (16.o) #>
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Debug"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\15.0\Common\Debug"
    fncDeleteItem "HKCU:\SOFTWARE\Microsoft\Office\14.0\Common\Debug"

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "Office TCOTrace" -strLogValue "Disabled"

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: MSIPC/MSIP..." -PercentComplete (100/9 * 3)

    <# Disabling MSIPC/MSIP logging #>
    Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSIPC" -Name "Trace" -Force | Out-Null
    Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\MSDRM" -Name "Trace" -Force | Out-Null
    Remove-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSIPC" -Name "Trace" -Force | Out-Null
    Remove-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSDRM" -Name "Trace" -Force | Out-Null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "MSIPC/MSIP logging" -strLogValue "Disabled"

    <# Disable RMS-MSIPC event log #>
    If ([System.Diagnostics.EventLog]::Exists('Microsoft-RMS-MSIPC/Debug') -Eq $true) { <# Actions when RMS-MSIPC event log exist #>

        <# Enable Microsoft-RMS-MSIPC/Debug event log #>
        Echo Y | wevtutil.exe set-log "Microsoft-RMS-MSIPC/Debug" /enabled:true /retention:false /maxsize:153600 <# Set back to false #>
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "Microsoft-RMS-MSIPC/Debug logging" -strLogValue "Enabled"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: CAPI2 event log..." -PercentComplete (100/9 * 4) 

    <# Disable CAPI2 event log #>
    wevtutil.exe set-log Microsoft-Windows-CAPI2/Operational /enabled:false
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "CAPI2 event log" -strLogValue "Disabled"

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: Network trace..." -PercentComplete (100/9 * 5)

    <# Stopping network trace #>
    netsh.exe trace stop sessionname="RMS_Support_Tool-Trace" | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "Network trace" -strLogValue "Disabled"

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: PSR..." -PercentComplete (100/9 * 6)

    <# Stop PSR #>
    psr.exe /stop
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "PSR" -strLogValue "Disabled"

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: MSOIdentityCRL..." -PercentComplete (100/9 * 7)

    <# Disabling MSOIdentityCRL (MSOIDSVC = Microsoft® Online Services Sign-in Assistant) trace if service exist #>
    If (Get-Service "MSOIDSVC" -ErrorAction SilentlyContinue) { <# Checking if service exist #>

        <# Remove trace registry key #>
        Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Recurse -Force -ErrorAction SilentlyContinue

        <# Start service #>
        Start-Service -Name "MSOIDSVC"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "MSOIdentityCRL logging" -strLogValue "Disabled"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Disable logging: MSIPC/MSIP..." -PercentComplete (100/9 * 8)

    <# Disable MSIPC/MSIP logging #>
    Start-Process taskkill.exe -ArgumentList "/IM", "dbgview.exe" | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "MSIPC/MSIP logging" -strLogValue "Disabled"

    <# Progress bar update #>
    Write-Progress -Activity " Logging disabled" -Completed

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncDisableLogging" -strLogDescription "Disable logging" -strLogValue "Proceeded" 

}

<# Function to finalize logging (collecting/exporting data) #>
Function fncCollectLogging {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Collecting logs" -strLogValue "Triggered" 

    <# Progress bar #>
    Write-Progress -Activity " Collecting logs..." -PercentComplete 0

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: MSIPC/MSIP log files..." -PercentComplete (100/26 * 1)

    <# Export MSIPC/MSIP logging #>
    Start-Process taskkill.exe -ArgumentList "/IM", "dbgview.exe" | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSIPC/MSIP log" -strLogValue "MSIPC-DebugView.log"

    <# Export RMS-MSIPC event log #>
    If ([System.Diagnostics.EventLog]::Exists('Microsoft-RMS-MSIPC/Debug') -Eq $true) { <# Actions when RMS-MSIPC event log exist #>

        <# Disable Microsoft-RMS-MSIPC/Debug event log #>
        wevtutil.exe set-log "Microsoft-RMS-MSIPC/Debug" /Enabled:False
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Microsoft-RMS-MSIPC/Debug logging" -strLogValue "Disabled"

        <# Export Microsoft-RMS-MSIPC/Debug event log #>
        wevtutil.exe export-log Microsoft-RMS-MSIPC/Debug $Global:strUniqueLogFolder"\MSIPC.evtx" /overwrite:true
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Microsoft-RMS-MSIPC/Debug event log" -strLogValue "MSIPC.evtx"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: CAPI2 event log..." -PercentComplete (100/26 * 2)

    <# Export CAPI2 event log #>
    wevtutil.exe export-log Microsoft-Windows-CAPI2/Operational $Global:strUniqueLogFolder"\CAPI2.evtx" /overwrite:true
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export CAPI2 event log" -strLogValue "CAPI2.evtx"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: AIP event log..." -PercentComplete (100/26 * 3)

    <# Actions when AIP event log exist #>
    If ([System.Diagnostics.EventLog]::Exists('Azure Information Protection') -Eq $true) {

        <# Export AIP event log #>
        wevtutil.exe export-log "Azure Information Protection" $Global:strUniqueLogFolder"\AIP.evtx" /overwrite:true
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export AIP event log" -strLogValue "AIP.evtx"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Network trace..." -PercentComplete (100/26 * 4)

    <# Stopping network trace #>
    netsh.exe trace stop sessionname="RMS_Support_Tool-Trace" | Out-Null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Network trace" -strLogValue "Stopped"
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export network trace" -strLogValue "NetMon.etl"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: PSR recording..." -PercentComplete (100/26 * 5)

    <# Stop PSR #>
    psr.exe /stop

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "PSR" -strLogValue "Stopped"
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export PSR" -strLogValue "ProblemSteps.zip"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Application event log..." -PercentComplete (100/26 * 6)

    <# Export Application event log #>
    wevtutil.exe export-log Application $Global:strUniqueLogFolder"\Application.evtx" /overwrite:true
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Application event log" -strLogValue "Application.evtx"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: System event log..." -PercentComplete (100/26 * 7)

    <# Export System event log #>
    wevtutil.exe export-log System $Global:strUniqueLogFolder"\System.evtx" /overwrite:true
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export System event log" -strLogValue "System.evtx"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Office log file..." -PercentComplete (100/26 * 8)

    <# Copy office.log (TCOTrace) file from temp folder to logs folder #>
    fncCopyItem $Global:strTempFolder"\office.log" $Global:strUniqueLogFolder"\office.log" "office.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Office TCOTrace" -strLogValue "office.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Office TCOTrace log files..." -PercentComplete (100/26 * 9)

    <# Copy Office logging files for 2013 (15.o), 2016 (16.o) to logs folder #>
    fncCopyItem $env:LOCALAPPDATA\Microsoft\Office\MsoLogs $Global:strUniqueLogFolder"\MsoLogs" "MsoLogs\*"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Office logs" -strLogValue "\MsoLogs"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: MSOIdentityCRL logs..." -PercentComplete (100/26 * 10)

    <# Disabling MSOIdentityCRL (MSOIDSVC = Microsoft® Online Services Sign-in Assistant) trace if service exist #>
    If (Get-Service "MSOIDSVC" -ErrorAction SilentlyContinue) { <# Checking if service exist #>

        <# Remove trace registry key #>
        Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSOIdentityCRL\Trace" -Recurse -Force -ErrorAction SilentlyContinue
        Remove-Item -Path "HKCU:\SOFTWARE\Microsoft\MSOIdentityCRL\Trace" -Recurse -Force -ErrorAction SilentlyContinue

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "MSOIdentityCRL logging" -strLogValue "Stopped"

        <# Start service #>
        Start-Service -Name "MSOIDSVC"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSOIdentityCRL logs" -strLogValue "\MsoTrace"
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSOIdentityCRL trace" -strLogValue "\MsoTracLite"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: AIP/MIP/RMS logs..." -PercentComplete (100/26 * 11)

    <# Export MSIP/MSIPC folders (and more) to logs folder #>
    If (Get-Module -ListAvailable -Name AzureInformationProtection) { <# Checking for AIP client and collecting folder content #>

        <# Feeding variable with AIP client version information #>
        $strAIPClientVersion = $((Get-Module -ListAvailable -Name AzureInformationProtection).Version).ToString()

        <# Action with AIPv1 client #>
        If ($strAIPClientVersion.StartsWith("1") -eq $true) {
            
            <# Export MSIP/MSIPC content to logs folder #>
            fncCopyItem $env:LOCALAPPDATA\Microsoft\MSIP $Global:strUniqueLogFolder"\MSIP" "MSIP\*"

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSIP content" -strLogValue "\MSIP"

            <# Copy files to logs folder #>
            fncCopyItem $env:LOCALAPPDATA\Microsoft\MSIPC $Global:strUniqueLogFolder"\MSIPC" "MSIPC\*"

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSIPC content" -strLogValue "\MSIPC"

        }
        <# Action with AIPv2 client #>
        ElseIf ($strAIPClientVersion.StartsWith("2") -eq $true) {

            <# Remember default progress bar status: "Continue" #>
            $Private:strOriginalPreference = $Global:ProgressPreference 
            $Global:ProgressPreference = "SilentlyContinue" <# Hiding progress bar #>
            
            <# Exporting AIP log folders #>
            Export-AIPLogs -FileName "$Global:strUniqueLogFolder\AIPLogs.zip" | Out-Null

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export AIP Logs" -strLogValue $true

            <# Set back progress bar to previous default #>
            $Global:ProgressPreference = $Private:strOriginalPreference

        }

    }
    Else {<# Action without any AIP client #>
    
        <# Export MSIP/MSIPC content to logs folder #>
        fncCopyItem $env:LOCALAPPDATA\Microsoft\MSIP $Global:strUniqueLogFolder"\MSIP" "MSIP\*"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSIP content" -strLogValue "\MSIP"

        <# Copy files to logs folder #>
        fncCopyItem $env:LOCALAPPDATA\Microsoft\MSIPC $Global:strUniqueLogFolder"\MSIPC" "MSIPC\*"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export MSIPC content" -strLogValue "\MSIPC"

    }

    <# Copy files to logs folder #>
    fncCopyItem $env:LOCALAPPDATA\Microsoft\DRM $Global:strUniqueLogFolder"\DRM" "DRM\*"

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export DRM content" -strLogValue "\DRM"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: WinHTTP..." -PercentComplete (100/26 * 12)

    <# Export WinHTTP #>
    netsh.exe winhttp show proxy > $Global:strUniqueLogFolder"\WinHTTP.log"
    
    <# Verbose/Logging #>
    fncLOgging -strLogFunction "fncCollectLogging" -strLogDescription "Export WinHTTP" -strLogValue "WinHTTP.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: WinHTTP (WoW6432)..." -PercentComplete (100/26 * 13)

    <# Export WinHTTP_WoW6432, if 64-bit OS #>
    If ((Get-CimInstance Win32_OperatingSystem  -Verbose:$false).OSArchitecture -eq "64-bit") {

        & $env:WINDIR\SysWOW64\netsh.exe winhttp show proxy > $Global:strUniqueLogFolder"\WinHTTP_WoW6432.log"
       
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export WinHTTP_WoW6432" -strLogValue "WinHTTP_WoW6432.log"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Machine certificates..." -PercentComplete (100/26 * 14)

    <# Export machine certificates #>
    certutil.exe -silent -store my > $Global:strUniqueLogFolder"\CertMachine.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export machine certificates" -strLogValue "CertMachine.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: User certificates..." -PercentComplete (100/26 * 15)

    <# Export user certificates #>
    certutil.exe -silent -user -store my > $Global:strUniqueLogFolder"\CertUser.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export user certificates" -strLogValue "CertUser.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Credentials information..." -PercentComplete (100/26 * 16)

    <# Export Credential Manager #>
    cmdkey.exe /list > $Global:strUniqueLogFolder"\CredMan.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Credential Manager" -strLogValue "CredMan.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: IP configuration..." -PercentComplete (100/26 * 17)

    <# Export ipconfig all #>
    ipconfig.exe /all > $Global:strUniqueLogFolder"\IPConfigAll.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export ipconfig" -strLogValue "IPConfigAll.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: DNS..." -PercentComplete (100/26 * 18)

    <# Display DNS #>
    ipconfig.exe /displaydns > $Global:strUniqueLogFolder"\WinIPConfig.txt" | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export DNS" -strLogValue "WinIPConfig.txt"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Environment information..." -PercentComplete (100/26 * 19)

    <# Export environment variables #>
    Get-ChildItem Env: | Out-File $Global:strUniqueLogFolder"\EnvVar.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export environment variables" -strLogValue "EnvVar.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Group policy report..." -PercentComplete (100/26 * 20)
    
    <# Export Gpresult #>
    gpresult /f /h $Global:strUniqueLogFolder"\Gpresult.htm" | Out-Null
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export group policy report" -strLogValue "Gpresult.htm"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Time zone information..." -PercentComplete (100/26 * 21)

    <# Export timezone difference (UTC) #>
    (Get-Timezone).BaseUTCOffset.Hours | Out-File $Global:strUniqueLogFolder"\BaseUTCOffset.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export timezone offset" -strLogValue "BaseUTCOffset.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Tasklist..." -PercentComplete (100/26 * 22)

    <# Export Tasklist #>
    Tasklist.exe /svc > $Global:strUniqueLogFolder"\Tasklist.log"
    
    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Tasklist" -strLogValue "Tasklist.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Programs and Features..." -PercentComplete (100/26 * 23)

    <# Export Programs and Features (32) #>
    If ($(Test-Path -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") -Eq $true) {

        <# Programs32 #>
        Get-ItemProperty "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Export-CSV $Global:strUniqueLogFolder"\Programs32.log" -ErrorAction SilentlyContinue

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Programs (x86)" -strLogValue "Programs32.log" 

    }
    
    <# Export Programs and Features (64) #>
    Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Export-CSV $Global:strUniqueLogFolder"\Programs64.log" -ErrorAction SilentlyContinue

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Programs (x64)" -strLogValue "Programs64.log"

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: AIP registry keys..." -PercentComplete (100/26 * 24)
    
    <# Export AIP plugin Adobe Acrobat RMS logs #>
    If ($(Test-Path -Path $env:LOCALAPPDATA\Microsoft\RMSLocalStorage\MIP\logs) -Eq $true) {

        <# Progress bar update #>
        Write-Progress -Activity " Collecting logs: Adobe logs..." -PercentComplete (100/26 * 25)

        <# Export MSIP/MSIPC content to logs folder #>
        fncCopyItem $env:LOCALAPPDATA\Microsoft\RMSLocalStorage\MIP\logs $Global:strUniqueLogFolder"\Adobe\LOCALAPPDATA" "Adobe\LOCALAPPDATA\*"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Adobe logs" -strLogValue "\Adobe"

    }

    If ($(Test-Path -Path $env:USERPROFILE\appdata\locallow\Microsoft\RMSLocalStorage\mip\logs) -Eq $true) {

        <# Export MSIP/MSIPC content to logs folder #>
        fncCopyItem $env:USERPROFILE\appdata\locallow\Microsoft\RMSLocalStorage\mip\logs $Global:strUniqueLogFolder"\Adobe\USERPROFILE" "Adobe\USERPROFILE\*"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export Adobe logs" -strLogValue "\Adobe"

    }

    <# Progress bar update #>
    Write-Progress -Activity " Collecting logs: Filter drivers..." -PercentComplete (100/26 * 26)

    <# Export filter drivers #>
    fltmc.exe filters > $Global:strUniqueLogFolder"\Filters.log"

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export filter drivers" -strLogValue "Filters.log"

    <# Export several AIP registry keys: Defining an array and feeding it with related AIP registry keys #>
    $Private:arrRegistryKeys = "HKLM:\Software\Classes\MSIP.ExcelAddin", 
                               "HKLM:\Software\Classes\MSIP.WordAddin",
                               "HKLM:\SOFTWARE\Classes\MSIP.PowerPointAddin",
                               "HKLM:\SOFTWARE\Classes\MSIP.OutlookAddin",
                               "HKLM:\SOFTWARE\Classes\AllFileSystemObjects\shell\Microsoft.Azip.RightClick",
                               "HKLM:\SOFTWARE\Microsoft\MSIPC",
                               "HKLM:\SOFTWARE\Microsoft\Office\16.0\Common\DRM",
                               "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\SOFTWARE\Microsoft\Office\16.0\Common\DRM",
                               "HKLM:\SOFTWARE\Microsoft\Office\Word\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\Excel\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\PowerPoint\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\Outlook\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\SOFTWARE\Microsoft\Office\Word\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\SOFTWARE\Microsoft\Office\Excel\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\SOFTWARE\Microsoft\Office\PowerPoint\Addins",
                               "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\REGISTRY\MACHINE\SOFTWARE\Microsoft\Office\Outlook\Addins",
                               "HKLM:\SOFTWARE\WOW6432Node\Microsoft\MSIPC",
                               "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\Word\Addins",
                               "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\Excel\Addins",
                               "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\PowerPoint\Addins",
                               "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Office\Outlook\Addins",
                               "HKCU:\SOFTWARE\Microsoft\MSIP",
                               "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\DRM",
                               "HKCU:\SOFTWARE\Microsoft\Office\16.0\Common\Security",
                               "HKCU:\Software\Microsoft\Office\16.0\Common\Identity",
                               "HKCU:\SOFTWARE\Microsoft\Office\Word\Addins",
                               "HKCU:\SOFTWARE\Microsoft\Office\Excel\Addins",
                               "HKCU:\SOFTWARE\Microsoft\Office\PowerPoint\Addins",
                               "HKCU:\SOFTWARE\Microsoft\Office\Outlook\Addins",
                               "HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Resiliency",
                               "HKCU:\SOFTWARE\Microsoft\Office\16.0\Excel\Resiliency",
                               "HKCU:\SOFTWARE\Microsoft\Office\16.0\PowerPoint\Resiliency",
                               "HKCU:\SOFTWARE\Microsoft\Office\15.0\Outlook\Resiliency",
                               "HKCU:\SOFTWARE\Microsoft\Office\16.0\Outlook\Resiliency",
                               "HKCU:\SOFTWARE\Classes\Local Settings\SOFTWARE\Microsoft\MSIPC",
                               "HKCR:\MSIP.ExcelAddin",
                               "HKCR:\MSIP.WordAddin",
                               "HKCR:\MSIP.PowerPointAddin",
                               "HKCR:\MSIP.OutlookAddin",
                               "HKCR:\Local Settings\SOFTWARE\Microsoft\MSIPC"

    <# Loop though array and cache to a temp file #>
    ForEach ($_ in $Private:arrRegistryKeys) {

        If ($(Test-Path -Path $_) -Eq $true) {

            $Private:strTempFile = $Private:strTempFile + 1
            & REG EXPORT $_.Replace(":", $null) "$Global:strTempFolder\$Private:strTempFile.reg" /Y | Out-Null <# Remove ":" for export (replace) #>

        }

    }

    <# Inserting first information; create log file #>
    "Windows Registry Editor Version 5.00" | Set-Content "$Global:strUniqueLogFolder\Registry.log"

    <# Reading data from cached temp file, and add it to the logfile #>
    (Get-Content "$Global:strTempFolder\*.reg" | ? {$_ -ne "Windows Registry Editor Version 5.00"} | Add-Content "$Global:strUniqueLogFolder\Registry.log")

    <# Cleaning temp folder of cached files #>
    Remove-Item "\\?\$Global:strTempFolder\*.reg" -Force -ErrorAction SilentlyContinue | Out-Null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Export AIP registry keys" -strLogValue "Registry.log"

    <# Progress bar update #>
    Write-Progress -Activity " Logs collected" -Completed

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLogging" -strLogDescription "Collecting logs" -strLogValue "Proceeded" 

}

<# Function to check and update needed modules for PowerShellGallery.com #>
Function fncUpdateRequiredModules {

    <# Checking for AADRM module and uninstalling it (AADRM retired, and replaced by AIPservice: https://docs.microsoft.com/en-us/powershell/azure/aip/overview?view=azureipps) #>
    If (Get-Module -ListAvailable -Name AADRM) {

        <# Unstalling AADRM PowerShell module #>
        Uninstall-Module -Verbose:$false -Name AADRM | Out-Null 

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "AADRM module" -strLogValue "Removed"

    }

    <# Define powershellgallery.com as trusted location, to be able to install AIPService module #>
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

    <# Remember default progress bar status: "Continue" #>
    $Private:strOriginalPreference = $Global:ProgressPreference 
    $Global:ProgressPreference = "SilentlyContinue" <# Hiding progress bar #>

    <# Validating connection to PowerShell Gallery by Find-Module #>
    If (Find-PackageProvider -Name NuGet -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) { <# Actions, if PowerShell Gallery can be reached #>

        <# Install/update nuGet provider to be able to install the latest modules #>
        Install-PackageProvider -Name NuGet -MinimumVersion "2.8.5.208" -ForceBootstrap -Scope CurrentUser -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Verbose:$false | Out-Null

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "NuGet version" -strLogValue (Find-PackageProvider -Verbose:$false -Name NuGet).Version

    }
    Else { <# Actions, if PowerShell Gallery can not be reached (no internet connection) #>

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "NuGet update" -strLogValue "Failed"

    }

    <# Set back progress bar to previous default #>
    $Global:ProgressPreference = $Private:strOriginalPreference

    <# Validating connection to PowerShell Gallery #>
    If (Get-Module -ListAvailable -Name "AIPService") {

        <# Updating AIPService, if we can connect to PowerShell Gallery #>
        If (Find-Module -Name AIPService -Repository PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {

            <# Filling variables with version information #>
            [Version]$Private:strAIPOnlineVersion = (Find-Module -Name AIPService -Repository PSGallery).Version
            [Version]$Private:strAIPLocalVersion = (Get-Module -ListAvailable -Name "AIPService").Version | Select-Object -First 1

            <# Comparing local version vs. online version #>
            If ([Version]::new($Private:strAIPOnlineVersion.Major, $Private:strAIPOnlineVersion.Minor, $Private:strAIPOnlineVersion.Build, $Private:strAIPOnlineVersion.Revision) -gt [Version]::new($Private:strAIPLocalVersion.Major, $Private:strAIPLocalVersion.Minor, $Private:strAIPLocalVersion.Build, $Private:strAIPLocalVersion.Revision) -eq $true) {

                <# Console output #>
                Write-Output "Updating AIPService module..."

                <# Updating AIPService PowerShell module #>
                Update-Module -Verbose:$false -Name AIPService -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "AIPService module" -strLogValue "Updated"

            }

            <# Releasing private variables #>
            [Version]$Private:strAIPOnlineVersion = $null
            [Version]$Private:strAIPLocalVersion = $null

        }
        Else { <# Actions, if we can't connect to PowerShell Gallery (no internet connection) #>

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "AIPService module update" -strLogValue "Failed"

        }

    }

    <# Actions, if AIPService module isn't installed #>
    If (-Not (Get-Module -ListAvailable -Name "AIPService")) {

        <# Installing AIPService, if we can connect to PowerShell Gallery #>
        If (Find-Module -Name AIPService -Repository PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {

            <# Console output #>
            Write-Output "Intalling AIPService module..."

            <# Installing AIPService PowerShell module #>
            Install-Module -Verbose:$false -Name AIPService -Scope CurrentUser -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "AIPService module" -strLogValue "Installed"

        }
        Else { <# Actions, if we can't connect to PowerShell Gallery (no internet connection) #>

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "AIPService module installation" -strLogValue "Failed"

        }

    }

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncUpdateRequiredModules" -strLogDescription "AIPService version" -strLogValue (Get-Module -Verbose:$false -ListAvailable -Name AIPService).Version

}

<# Function to collect AIP service configuration #>
Function fncCollectAipConfig {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "Collect AIP service configuration" -strLogValue "Initiated"

    <# Console output #>
    Write-Output "COLLECT AIP SERVICE CONFIGURATION:"

    <# Console output #>
    Write-Output (Write-Host "ATTENTION: Please request assistance from your administrator to proceed this option." -ForegroundColor Red)
    $Private:ReadHost = Read-Host "Only if the above is true, please press [Y]es to continue, or [N]o to cancel"

    <# Checking if running as administrator #>
    fncCheckForAdminPermissions("COLLECT AIP SERVICE CONFIGURATION:")

    <# Actions, if yes was selected #>
    If ($Private:ReadHost -Eq "Y") {

        <# Console output #>
        Write-Output "Initializing, please wait..."

        <# Check and update needed modules for PowerShellGallery.com #>
        fncUpdateRequiredModules

        <# Console output #>
        Write-Output "Connecting to AIPService..."

        <# Connecting/Logon to AIPService #>
        If (Connect-AIPService -Verbose:$false) { <# Action if AIPService connection was opened #>

            <# Console output #> 
            Write-Output "AIPService connected."

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "AIPService connected" -strLogValue $true

        }
        Else{ <# Action if AIPService connection failed #>
    
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "AIPService connected" -strLogValue $false 
            fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "Collect AIP service configuration" -strLogValue "Login failed"
    
            <# Console output #>
            Write-Output (Write-Host "COLLECT AIP SERVICE CONFIGURATION: Failed! Please try again.`n" -ForegroundColor Red)
    
            <# Signal sound #>
            [console]::beep(500,200)

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Checking if 'Collect'-folder exist and create it if not #>
        If ($(Test-Path -Path $Global:strUserLogPath"\Collect") -Eq $false) {

            New-Item -ItemType Directory -Force -Path $Global:strUserLogPath"\Collect" | Out-Null <# Defining Collect path #>

        }

        <# Check for existing AIPService log file and create it, if it not exist #>
        If ($(Test-Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log") -Eq $false) {

            <# Create AIPService logging file #>
            Out-File -FilePath $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Encoding UTF8 -Append -Force

        }

        <# Console output #> 
        Write-Output "Collecting AIP service configuration...`n"

        <# Check for existing AIPService logging file and extend it, if it exist #>
        If ($(Test-Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log") -Eq $true) {

            <# Exporting AIP service configuration and output result: #>
            
            <# Timestamp #>
            $Private:Timestamp = (Get-Date -Verbose:$false -UFormat "%y%m%d-%H%M%S") <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("Date/Timestamp : " + $Private:Timestamp) <# Extend log file #>
            Write-Output (Write-Host ("Date/Timestamp : $Private:Timestamp") -ForegroundColor Yellow) <# Console output #> 
            $Private:Timestamp = $null <# Releasing variable #>
            
            <# AIPService Module version #>
            $Private:AIPServiceModule = (Get-Module -Verbose:$false -ListAvailable -Name AIPService).Version <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("Module version : $Private:AIPServiceModule") <# Extend log file #>
            Write-Output (Write-Host ("Module version : $Private:AIPServiceModule") -ForegroundColor Yellow) <# Console output #> 
            $Private:AIPServiceModule = $null <# Releasing variable #>

            <# BPOSId #>
            $Private:BPOSId = (Get-AipServiceConfiguration).BPOSId <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("BPOSId : $Private:BPOSId") <# Extend log file #>
            Write-Output (Write-Host ("BPOSId : $Private:BPOSId") -ForegroundColor Yellow) <# Console output #> 
            $Private:BPOSId = $null <# Releasing variable #>

            <# RightsManagementServiceId #>
            $Private:RightsManagementServiceId = (Get-AipServiceConfiguration).RightsManagementServiceId <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("RightsManagementServiceId : $Private:RightsManagementServiceId") <# Extend log file #>
            Write-Output (Write-Host ("RightsManagementServiceId : $Private:RightsManagementServiceId") -ForegroundColor Yellow) <# Console output #> 
            $Private:RightsManagementServiceId = $null <# Releasing variable #>

            <# LicensingIntranetDistributionPointUrl #>
            $Private:LicensingIntranetDistributionPointUrl = (Get-AipServiceConfiguration).LicensingIntranetDistributionPointUrl <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("LicensingIntranetDistributionPointUrl : $Private:LicensingIntranetDistributionPointUrl") <# Extend log file #>
            Write-Output (Write-Host ("LicensingIntranetDistributionPointUrl : $Private:LicensingIntranetDistributionPointUrl") -ForegroundColor Yellow) <# Console output #> 
            $Private:LicensingIntranetDistributionPointUrl = $null <# Releasing variable #>

            <# LicensingExtranetDistributionPointUrl #>
            $Private:LicensingExtranetDistributionPointUrl = (Get-AipServiceConfiguration).LicensingExtranetDistributionPointUrl <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("LicensingExtranetDistributionPointUrl : $Private:LicensingExtranetDistributionPointUrl") <# Extend log file #>
            Write-Output (Write-Host ("LicensingExtranetDistributionPointUrl : $Private:LicensingExtranetDistributionPointUrl") -ForegroundColor Yellow) <# Console output #> 
            $Private:LicensingExtranetDistributionPointUrl = $null <# Releasing variable #>

            <# CertificationIntranetDistributionPointUrl #>
            $Private:CertificationIntranetDistributionPointUrl = (Get-AipServiceConfiguration).CertificationIntranetDistributionPointUrl <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("CertificationIntranetDistributionPointUrl : $Private:CertificationIntranetDistributionPointUrl") <# Extend log file #>
            Write-Output (Write-Host ("CertificationIntranetDistributionPointUrl : $Private:CertificationIntranetDistributionPointUrl") -ForegroundColor Yellow) <# Console output #> 
            $Private:CertificationIntranetDistributionPointUrl = $null <# Releasing variable #>

            <# CertificationExtranetDistributionPointUrl #>
            $Private:CertificationExtranetDistributionPointUrl = (Get-AipServiceConfiguration).CertificationExtranetDistributionPointUrl <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("CertificationExtranetDistributionPointUrl : $Private:CertificationExtranetDistributionPointUrl") <# Extend log file #>
            Write-Output (Write-Host ("CertificationExtranetDistributionPointUrl : $Private:CertificationExtranetDistributionPointUrl") -ForegroundColor Yellow) <# Console output #> 
            $Private:CertificationExtranetDistributionPointUrl = $null <# Releasing variable #>

            <# AdminConnectionUrl #>
            $Private:AdminConnectionUrl = (Get-AipServiceConfiguration).AdminConnectionUrl <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AdminConnectionUrl : $Private:AdminConnectionUrl") <# Extend log file #>
            Write-Output (Write-Host ("AdminConnectionUrl : $Private:AdminConnectionUrl") -ForegroundColor Yellow) <# Console output #> 
            $Private:AdminConnectionUrl = $null <# Releasing variable #>

            <# AdminV2ConnectionUrl #>
            $Private:AdminV2ConnectionUrl = (Get-AipServiceConfiguration).AdminV2ConnectionUrl <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AdminV2ConnectionUrl : $Private:AdminV2ConnectionUrl") <# Extend log file #>
            Write-Output (Write-Host ("AdminV2ConnectionUrl : $Private:AdminV2ConnectionUrl") -ForegroundColor Yellow) <# Console output #> 
            $Private:AdminV2ConnectionUrl = $null <# Releasing variable #>

            <# OnPremiseDomainName #>
            $Private:OnPremiseDomainName = (Get-AipServiceConfiguration).OnPremiseDomainName <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("OnPremiseDomainName : $Private:OnPremiseDomainName") <# Extend log file #>
            Write-Output (Write-Host ("OnPremiseDomainName : $Private:OnPremiseDomainName") -ForegroundColor Yellow) <# Console output #> 
            $Private:OnPremiseDomainName = $null <# Releasing variable #>

            <# Keys #>
            $Private:Keys = (Get-AipServiceConfiguration).Keys <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("Keys : $Private:Keys") <# Extend log file #>
            Write-Output (Write-Host ("Keys : $Private:Keys") -ForegroundColor Yellow) <# Console output #> 
            $Private:Keys = $null <# Releasing variable #>

            <# CurrentLicensorCertificateGuid #>
            $Private:CurrentLicensorCertificateGuid = (Get-AipServiceConfiguration).CurrentLicensorCertificateGuid <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("CurrentLicensorCertificateGuid : $Private:CurrentLicensorCertificateGuid") <# Extend log file #>
            Write-Output (Write-Host ("CurrentLicensorCertificateGuid : $Private:CurrentLicensorCertificateGuid") -ForegroundColor Yellow) <# Console output #> 
            $Private:CurrentLicensorCertificateGuid = $null <# Releasing variable #>

            <# Templates #>
            $Private:Templates = (Get-AipServiceConfiguration).Templates <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("Template IDs : $Private:Templates") <# Extend log file #>
            Write-Output (Write-Host ("Template IDs : $Private:Templates") -ForegroundColor Yellow) <# Console output #> 
            $Private:Templates = $null <# Releasing variable #>

            <# FunctionalState #>
            $Private:FunctionalState = (Get-AipServiceConfiguration).FunctionalState <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("FunctionalState : $Private:FunctionalState") <# Extend log file #>
            Write-Output (Write-Host ("FunctionalState : $Private:FunctionalState") -ForegroundColor Yellow) <# Console output #> 
            $Private:FunctionalState = $null <# Releasing variable #>

            <# SuperUsersEnabled #>
            $Private:SuperUsersEnabled = (Get-AipServiceConfiguration).SuperUsersEnabled <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("SuperUsersEnabled : $Private:SuperUsersEnabled") <# Extend log file #>
            Write-Output (Write-Host ("SuperUsersEnabled : $Private:SuperUsersEnabled") -ForegroundColor Yellow) <# Console output #> 
            $Private:SuperUsersEnabled = $null <# Releasing variable #>

            <# SuperUsers #>
            $Private:SuperUsers = (Get-AipServiceConfiguration).SuperUsers <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("SuperUsers : $Private:SuperUsers") <# Extend log file #>
            Write-Output (Write-Host ("SuperUsers : $Private:SuperUsers") -ForegroundColor Yellow) <# Console output #> 
            $Private:SuperUsers = $null <# Releasing variable #>

            <# AdminRoleMembers #>
            $Private:AdminRoleMembers = (Get-AipServiceConfiguration).AdminRoleMembers <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AdminRoleMembers : $Private:AdminRoleMembers") <# Extend log file #>
            Write-Output (Write-Host ("AdminRoleMembers : $Private:AdminRoleMembers") -ForegroundColor Yellow) <# Console output #> 
            $Private:AdminRoleMembers = $null <# Releasing variable #>

            <# KeyRolloverCount #>
            $Private:KeyRolloverCount = (Get-AipServiceConfiguration).KeyRolloverCount <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("KeyRolloverCount : $Private:KeyRolloverCount") <# Extend log file #>
            Write-Output (Write-Host ("KeyRolloverCount : $Private:KeyRolloverCount") -ForegroundColor Yellow) <# Console output #> 
            $Private:KeyRolloverCount = $null <# Releasing variable #>

            <# ProvisioningDate #>
            $Private:ProvisioningDate = (Get-AipServiceConfiguration).ProvisioningDate <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("ProvisioningDate : $Private:ProvisioningDate") <# Extend log file #>
            Write-Output (Write-Host ("ProvisioningDate : $Private:ProvisioningDate") -ForegroundColor Yellow) <# Console output #> 
            $Private:ProvisioningDate = $null <# Releasing variable #>

            <# IPCv3ServiceFunctionalState #>
            $Private:IPCv3ServiceFunctionalState = (Get-AipServiceConfiguration).IPCv3ServiceFunctionalState <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("IPCv3ServiceFunctionalState : $Private:IPCv3ServiceFunctionalState") <# Extend log file #>
            Write-Output (Write-Host ("IPCv3ServiceFunctionalState : $Private:IPCv3ServiceFunctionalState") -ForegroundColor Yellow) <# Console output #> 
            $Private:IPCv3ServiceFunctionalState = $null <# Releasing variable #>

            <# DevicePlatformState #>
            $Private:DevicePlatformState = (Get-AipServiceConfiguration).DevicePlatformState <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("DevicePlatformState : $Private:DevicePlatformState") <# Extend log file #>
            Write-Output (Write-Host ("DevicePlatformState : $Private:DevicePlatformState") -ForegroundColor Yellow) <# Console output #> 
            $Private:DevicePlatformState = $null <# Releasing variable #>

            <# FciEnabledForConnectorAuthorization #>
            $Private:FciEnabledForConnectorAuthorization = (Get-AipServiceConfiguration).FciEnabledForConnectorAuthorization <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("FciEnabledForConnectorAuthorization : $Private:FciEnabledForConnectorAuthorization") <# Extend log file #>
            Write-Output (Write-Host ("FciEnabledForConnectorAuthorization : $Private:FciEnabledForConnectorAuthorization") -ForegroundColor Yellow) <# Console output #> 
            $Private:FciEnabledForConnectorAuthorization = $null <# Releasing variable #>

            <# AIP service templates details log file #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AIP service templates : AipServiceTemplates.log")
            
            <# AipServiceDocumentTrackingFeature #>
            $Private:AipServiceDocumentTrackingFeature = Get-AipServiceDocumentTrackingFeature <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AipServiceDocumentTrackingFeature : $Private:AipServiceDocumentTrackingFeature") <# Extend log file #>
            Write-Output (Write-Host ("AipServiceDocumentTrackingFeature : $Private:AipServiceDocumentTrackingFeature") -ForegroundColor Yellow) <# Console output #> 
            $Private:AipServiceDocumentTrackingFeature = $null <# Releasing variable #>

            <# AipServiceOnboardingControlPolicy #>
            $Private:AipServiceOnboardingControlPolicy = ("{[UseRmsUserLicense, " + $(Get-AipServiceOnboardingControlPolicy).UseRmsUserLicense +"], [SecurityGroupObjectId, " + $(Get-AipServiceOnboardingControlPolicy).SecurityGroupObjectId + "], [Scope, " + $(Get-AipServiceOnboardingControlPolicy).Scope + "]}") <# Filling private variable #>
            Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AipServiceOnboardingControlPolicy : $Private:AipServiceOnboardingControlPolicy") <# Extend log file #>
            Write-Output (Write-Host ("AipServiceOnboardingControlPolicy : $Private:AipServiceOnboardingControlPolicy") -ForegroundColor Yellow) <# Console output #> 
            $Private:AipServiceOnboardingControlPolicy = $null <# Releasing variable #>

            <# AipServiceDoNotTrackUserGroup #>
            $Private:AipServiceDoNotTrackUserGroup = Get-AipServiceDoNotTrackUserGroup <# Filling private variable #>

            <# Actions, if AipServiceDoNotTrackUserGroup variable value is not empty #>
            If ($Private:AipServiceDoNotTrackUserGroup) {

                Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AipServiceDoNotTrackUserGroup : $Private:AipServiceDoNotTrackUserGroup") <# Extend log file #>
                Write-Output (Write-Host ("AipServiceDoNotTrackUserGroup : $Private:AipServiceDoNotTrackUserGroup") -ForegroundColor Yellow) <# Console output #> 

            }
            Else { <# Actions, if variable value is empty #>
            
                Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AipServiceDoNotTrackUserGroup :") <# Extend log file #>
                Write-Output (Write-Host ("AipServiceDoNotTrackUserGroup :") -ForegroundColor Yellow) <# Console output #> 

            }
            
            <# Releasing AipServiceDoNotTrackUserGroup variable #>
            $Private:AipServiceDoNotTrackUserGroup = $null 

            <# AipServiceRoleBasedAdministrator #>
            $Private:AipServiceRoleBasedAdministrator = Get-AipServiceRoleBasedAdministrator <# Filling private variable #>

            <# Actions, if AipServiceRoleBasedAdministrator variable value is not empty #>
            If ($Private:AipServiceRoleBasedAdministrator) {

                Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AipServiceRoleBasedAdministrator : $Private:AipServiceRoleBasedAdministrator") <# Extend log file #>
                Write-Output (Write-Host ("AipServiceRoleBasedAdministrator : $Private:AipServiceRoleBasedAdministrator") -ForegroundColor Yellow) <# Console output #> 

            }
            Else { <# Actions, if variable value is empty #>
            
                Add-Content -Path $Global:strUserLogPath"\Collect\AipServiceConfiguration.log" -Value ("AipServiceRoleBasedAdministrator :") <# Extend log file #>
                Write-Output (Write-Host ("AipServiceRoleBasedAdministrator :") -ForegroundColor Yellow) <# Console output #> 

            }
            
            <# Releasing AipServiceRoleBasedAdministrator variable #>
            $Private:AipServiceRoleBasedAdministrator = $null 

        }

        <# Collect AIP service templates #>
        $Private:Timestamp = (Get-Date -Verbose:$false -UFormat "%y%m%d-%H%M%S") <# Filling private variable with date/time #>
        ("Date/Timestamp : " + $Private:Timestamp) | Out-File $Global:strUserLogPath"\Collect\AipServiceTemplates.log" -Append <# Extend log file with date/time #>
            
        <# Releasing date/time variable #>
        $Private:Timestamp = $null 

        <# Add template details #>
        Get-AipServiceConfiguration | Select-Object -ExpandProperty Templates | Out-File $Global:strUserLogPath"\Collect\AipServiceTemplates.log" -Append <# Extending log file with template summary #>
        Get-AIPServicetemplate | fl * | Out-File $Global:strUserLogPath"\Collect\AipServiceTemplates.log" -Append <# Extending log file with template details #>

        <# Disconnect from AIPService #>
        Disconnect-AIPService | Out-Null

        <# Console output #>
        Write-Output "`nAIPService disconnected.`n"

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "AIPService disconnected" -strLogValue $true
        fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "Export AIP service configuration" -strLogValue "AipServiceConfiguration.log"
        fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "Export AIP Templates" -strLogValue "AipServiceTemplates.log"
        fncLogging -strLogFunction "fncCollectAipConfig" -strLogDescription "Collect AIP service configuration" -strLogValue "Proceeded"

        <# Console output #> 
        Write-Output "Log files: $Global:strUserLogPath\Collect\AipServiceConfiguration.log`n $Global:strUserLogPath\Collect\AipServiceTemplates.log"
        Write-Output (Write-Host "COLLECT AIP SERVICE CONFIGURATION: Proceeded.`n" -ForegroundColor Green)

        <# Signal sound #>
        [console]::beep(1000,200)

    }
    <# Actions, if no (cancel) was selected #>
    ElseIf ($Private:ReadHost -eq "N") {

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {


            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {

            <# Clearing console #>
            Clear-Host

            <# Calling show menu function #>
            fncShowMenu    

        }

    }
    Else { <# Actions, if any other key was pressed #>

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {
 
            <# Clearing console #>
            Clear-Host
 
            <# Calling show menu function #>
            fncShowMenu    
 
        }

    }

    <# Releasing private variables #>
    $Private:ReadHost = $null

}

<# Function to collect Labels and Policies from Office 365 Security & Compliance Center #>
Function fncCollectLabelsAndPolicies {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Collect labels and policies" -strLogValue "Initiated"

    <# Console output #>
    Write-Output "COLLECT LABELS AND POLICIES:"

    <# Console output #>
    Write-Output (Write-Host "ATTENTION: Please request assistance from your administrator to proceed this option." -ForegroundColor Red)
    $Private:ReadHost = Read-Host "Only if the above is true, please press [Y]es to continue, or [N]o to cancel"

    <# Checking if running as administrator #>
    fncCheckForAdminPermissions("COLLECT LABELS AND POLICIES:")

    <# Actions, if yes was selected #>
    If ($Private:ReadHost -Eq "Y") {

        <# Console output #>
        Write-Output "Initializing, please wait..."

        <# Check and update needed modules for PowerShellGallery.com #>
        fncUpdateRequiredModules

        <# Actions, if ExchangeOnlineManagement module is installed #>
        If (Get-Module -ListAvailable -Name "ExchangeOnlineManagement") {

            <# Updating ExchangeOnlineManagement, if we can connect to PowerShell Gallery #>
            If (Find-Module -Name ExchangeOnlineManagement -Repository PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {

                <# Filling variables with version information #>
                [Version]$Private:strEOPOnlineVersion = (Find-Module -Name ExchangeOnlineManagement -Repository PSGallery).Version
                [Version]$Private:strAIPLocalVersion = (Get-Module -ListAvailable -Name "AIPService").Version | Select-Object -First 1

                <# Comparing local version vs. online version #>
                If ([Version]::new($Private:strEOPPOnlineVersion.Major, $Private:strEOPPOnlineVersion.Minor, $Private:strEOPPOnlineVersion.Build) -gt [Version]::new($Private:strEOPLocalVersion.Major, $Private:strEOPLocalVersion.Minor, $Private:strEOPLocalVersion.Build) -eq $true) {

                    <# Console output #>
                    Write-Output "Updating Exchange Online PowerShell V2 module..."

                    <# Updating AIPService PowerShell module #>
                    Update-Module -Verbose:$false -Name ExchangeOnlineManagement -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null

                    <# Verbose/Logging #>
                    fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Exchange Online PowerShell V2 module" -strLogValue "Updated"

                }

                <# Releasing private variables #>
                [Version]$Private:strEOPOnlineVersion = $null
                [Version]$Private:strEOPLocalVersion = $null

            }
            Else { <# Actions, if we can't connect to PowerShell Gallery (no internet connection) #>

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Exchange Online PowerShell V2 module update" -strLogValue "Failed"

            }

        }

        <# Actions, if ExchangeOnlineManagement module isn't installed #>
        If (-Not (Get-Module -ListAvailable -Name "ExchangeOnlineManagement")) {

            <# Installing ExchangeOnlineManagement, if we can connect to PowerShell Gallery #>
            If (Find-Module -Name ExchangeOnlineManagement -Repository PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {

                <# Console output #>
                Write-Output "Installing Exchange Online PowerShell V2 module..."

                <# Installing ExchangeOnlineManagement PowerShell module #>
                Install-Module -Verbose:$false -Name ExchangeOnlineManagement -Scope CurrentUser -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Exchange Online PowerShell V2 module" -strLogValue "Installed"

            }
            Else { <# Actions, if we can't connect to PowerShell Gallery (no internet connection) #>

                <# Console output #>
                Write-Output (Write-Host "ATTENTION:`n`nCollecting labels and policies could not be performed.`nEither PowerShell Gallery cannot be reached or there is no internet connection.`n`nYou must have Exchange Online PowerShell V2 module installed to proceed.`n`nPlease check the following website and install the latest version of the ExchangeOnlineManagement modul:`nhttps://www.powershellgallery.com/packages/ExchangeOnlineManagement`n" -ForegroundColor Red)

                <# Signal sound #>
                [console]::beep(500,200)

                <# Console output #>
                Write-Output (Write-Host "COLLECT LABELS AND POLICIES: Failed!`n" -ForegroundColor Red)

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Exchange Online PowerShell V2 module installation" -strLogValue "Failed"

                <# Action, if function was called from the menu #>
                If ($Global:bolCommingFromMenu -eq $true) {

                    <# Calling pause function #>
                    fncPause
    
                    <# Clearing console #>
                    Clear-Host

                    <# Calling show menu function #>
                    fncShowMenu

                }

                <# Action, if function was called from command-line #>
                If ($Global:bolCommingFromMenu -eq $false) {

                    <# Calling pause function #>
                    fncPause
    
                    <# Set back window title to default #>
                    $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

                    <# Interrupting, because of missing internet connection #>
                    Break

                }

            }

        }

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Exchange Online PowerShell V2 module version" -strLogValue (Get-Module -Verbose:$false -ListAvailable -Name ExchangeOnlineManagement).Version

        <# Console output #>
        Write-Output "Connecting to Office 365 Security & Compliance Center (SCC)..."

        <# Remember default progress bar status: "Continue" #>
        $Private:strOriginalPreference = $Global:ProgressPreference 
        $Global:ProgressPreference = "SilentlyContinue" <# Hiding progress bar #>

        <# Try to connect/logon to Security & Compliance Center (SCC) #>
        Try {

            <# Connect/logon to SCC #>
            Connect-IPPSSession -Verbose:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null

            <# Defining variable to show full Format-List within this session #>
            $FormatEnumerationLimit = -1

        }
        Catch { <# Catch action for any error that occur on connect/logon #>

            Write-Output "Office 365 Security & Compliance Center (SCC) login failed!"

            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Office 365 Security & Compliance Center (SCC) connected" -strLogValue $false 
            fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Office 365 Security & Compliance Center (SCC)" -strLogValue "Login failed"
    
            <# Console output #>
            Write-Output (Write-Host "COLLECT LABELS AND POLICIES: Failed! Please try again.`n" -ForegroundColor Red)

            <# Signal sound #>
            [console]::beep(500,200)

            <# Action, if function was called from the menu #>
            If ($Global:bolCommingFromMenu -eq $true) {

                <# Calling pause function #>
                fncPause
    
                <# Clearing console #>
                Clear-Host

                <# Calling show menu function #>
                fncShowMenu

            }

            <# Action, if function was called from command-line #>
            If ($Global:bolCommingFromMenu -eq $false) {

                <# Calling pause function #>
                fncPause
    
                <# Set back window title to default #>
                $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

                <# Interrupting, because of missing internet connection #>
                Break

            }

        }

        <# Console output #> 
        Write-Output "Office 365 Security & Compliance Center (SCC) connected."

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Office 365 Security & Compliance Center (SCC) connected" -strLogValue $true
    
        <# Console output #> 
        Write-Output "Collecting labels and policies..."

        <# Checking if 'Collect'-folder exist and create it if not #>
        If ($(Test-Path -Path $Global:strUserLogPath"\Collect") -Eq $false) {

            New-Item -ItemType Directory -Force -Path $Global:strUserLogPath"\Collect" | Out-Null <# Defining Collect path #>

        }

        <# Check for existing CollectLabels.log file and create it, if it not exist #>
        If ($(Test-Path $Global:strUserLogPath"\Collect\LabelsAndPolicies.log") -Eq $false) {

            <# Create CollectLabels.log logging file #>
            Out-File -FilePath $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Encoding UTF8 -Append -Force

        }

        <# Check for existing CollectLabels.log file and extend it, if it exist #>
        If ($(Test-Path $Global:strUserLogPath"\Collect\LabelsAndPolicies.log") -Eq $true) {

            <# Collecting data #>
            Add-Content -Path $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Value "CURRENT POLICY LABELS:`n"
            (Get-LabelPolicy).Name | Out-File $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Encoding UTF8 -Append -Force
            Add-Content -Path $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Value "`nALL LABELS:"
            Get-Label | Out-File $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Encoding UTF8 -Append -Force
            Add-Content -Path $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Value "ALL LABELS WITH DETAILS:"
            Get-Label | fl * | Out-File $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Encoding UTF8 -Append -Force
            Add-Content -Path $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Value "LABEL POLICIES:"
            Get-LabelPolicy | Out-File $Global:strUserLogPath"\Collect\LabelsAndPolicies.log" -Encoding UTF8 -Append -Force

        }

        <# Disconnect from Exchange Online Protection (EOP) #>
        Remove-PSSession -ComputerName (Get-PSSession).ComputerName

        <# Set back progress bar to previous default #>
        $Global:ProgressPreference = $Private:strOriginalPreference

        <# Console output #>
        Write-Output "Office 365 Security & Compliance Center (SCC) disconnected."

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Office 365 Security & Compliance Center (SCC) disconnected" -strLogValue $true
        fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Export labels and policy definitions" -strLogValue "LabelsAndPolicies.log"
        fncLogging -strLogFunction "fncCollectLabelsAndPolicies" -strLogDescription "Collect labels and policies" -strLogValue "Proceeded"

        <# Console output #> 
        Write-Output "`nLog file: $Global:strUserLogPath\Collect\LabelsAndPolicies.log"
        Write-Output (Write-Host "COLLECT LABELS AND POLICIES: Proceeded.`n" -ForegroundColor Green)

        <# Signal sound #>
        [console]::beep(1000,200)

    }
    <# Actions, if no (cancel) was selected #>
    ElseIf ($Private:ReadHost -eq "N") {

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {

            <# Clearing console #>
            Clear-Host

            <# Calling show menu function #>
            fncShowMenu    

        }

    }
    Else { <# Actions, if any other key was pressed #>

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {
 
            <# Clearing console #>
            Clear-Host
 
            <# Calling show menu function #>
            fncShowMenu    
 
        }

    }

    <# Releasing private variables #>
    $Private:ReadHost = $null

}
        
<# Function to verify Endpoint URL http status code / used in function fncVerifyIssuer #>
Function fncVerifyEndpoint ($strURL, $strEndpointName) {

    <# Checking for endpoints to extend #>
    If ($strEndpointName -Eq "LicensingIntranetDistributionPointUrl" -or $strEndpointName -eq "LicensingExtranetDistributionPointUrl" -or $strEndpointName -eq "CertificationDistributionPointUrl") {

        <# Extending URL with .asmx #>
        $strURL = $strURL + "/ServiceLocator.asmx"

    }

    Try { <# Action with http return code 200 #>

        <# Initialize web connection to check for URL #>
        $Private:CheckConnection = (Invoke-WebRequest -Uri $strURL -UseBasicParsing -DisableKeepAlive).StatusCode

        <# Check for successfully web connection and output result #>
        If ($Private:CheckConnection -eq 200) {

            <# Function return value (http status) #>
            Return, $Private:CheckConnection
            
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncVerifyEndpoint" -strLogDescription $strEndpointName -strLogValue $Private:CheckConnection

        }

    }
    Catch [Net.WebException] { <# Action with http errors #>

        <# Catching http error into variable #>
        $Private:HttpStatusCode = [int]$_.Exception.Response.StatusCode

        <# Function return value (http status) #>
        Return, $Private:HttpStatusCode

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncVerifyEndpoint" -strLogDescription $strEndpointName -strLogValue $Private:HttpStatusCode

    }

}

<# Function to analyze AIP endpoint URLs #>
Function fncAnalyzeEndpointURLs {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "Analyze endpoint URLs" -strLogValue "Initiated"

    <# Console output #>
    Write-Output "ANALYZE ENDPOINT URLs:"

    <# Defining and filling variables with static URLs #>
    $Private:MyUnifiedLabelingDistributionPointUrl = "https://dataservice.protection.outlook.com"
    $Private:MyTelemetryDistributionPointUrl = "https://self.events.data.microsoft.com"
    $Private:MyAIPv1PolicyDistributionPointUrl = "https://api.informationprotection.azure.com"

    <# Defining and filling variable with date/time for unique log folder #>
    $Private:MyTimestamp = (Get-Date -Verbose:$false -UFormat "%y%m%d-%H%M%S")
    $Private:strCertLogPath = "$Global:strUserLogPath\Analyze\$Private:MyTimestamp"

    <# Checking if 'Analyze'-folder exist and create it if not #>
    If ($(Test-Path -Path $Private:strCertLogPath) -Eq $false) {

        New-Item -ItemType Directory -Force -Path $Private:strCertLogPath | Out-Null <# Defining Analyze path #>

    }

    <# Check for existing EndpointURLs.log file and create it, if it not exist #>
    If ($(Test-Path $Global:strUserLogPath"\Analyze\EndpointURLs.log") -Eq $false) {

        Out-File -FilePath $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Encoding UTF8 -Append -Force

    }

    <# Checking for analyze AIP endpoints URLs [MSIPC] if bootstrap was done / running in 'non-admin mode' / reading URLs from registry #>
    If ($(Test-Path -Path "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC") -Eq $true) {

        <# Console output #>
        Write-Output "Initializing, please wait..."
        Write-Output "Verifying endpoint URLs...`n"

        <# Reading URLs from registry #>
        Get-ChildItem -Path "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC" | ForEach-Object {

            <# Reading Tenant Id #>
            $Private:strMainKey = $_.Name.Substring(75).ToString()
         
            <# Actions, if it's about '.aadrm.com', but not about 'discover.aadrm.com' #>
            If ($Private:strMainKey -like "*.aadrm.com" -and $Private:strMainKey -notmatch "discover.aadrm.com") {

                <# Private variabel definition for Tenant Id string #>
                $Private:strTenantId = $Private:strMainKey.Remove(36)

                <# Console output #> 
                Write-Output (Write-Host "-------------------------------------------------`nTenant Id: $Private:strTenantId`n-------------------------------------------------`n" -ForegroundColor Magenta)

                <# Create Tenant Id as first log entry #>
                Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "-----------------------------------------------`nTenant Id: $Private:strTenantId`n-----------------------------------------------"

                <# Defining and filling variables with URLs #>
                $Private:MyLicensingIntranetDistributionPointUrl = (Get-ItemProperty "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC\$Private:strMainKey\Identities" -ErrorAction SilentlyContinue).InternalUrl
                $Private:MyLicensingExtranetDistributionPointUrl = (Get-ItemProperty "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC\$Private:strMainKey\Identities" -ErrorAction SilentlyContinue).ExternalUrl

                <# Defining and filling variables: Extending colledted registry key with https and subkey #>
                $Private:strMainKey = "https://$Private:strMainKey".ToString()
                $Private:MyCertificationDistributionPointUrl = "$Private:strMainKey/_wmcs/certification"

                <# Create Timestamp #>
                Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value ("Date/Timestamp: " + (Get-Date -Verbose:$false -UFormat "$Private:MyTimestamp"))
                
                <# Add read mode #>
                Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value ("Read from registry [MSIPC]:`n")

                <# Calling function to verify endpoint and certificate issuer #>
                fncVerifyIssuer -strCertURL $Private:MyLicensingIntranetDistributionPointUrl -strEndpointName "LicensingIntranetDistributionPointUrl" -strLogPath $Private:strCertLogPath
                fncVerifyIssuer -strCertURL $Private:MyLicensingExtranetDistributionPointUrl -strEndpointName "LicensingExtranetDistributionPointUrl" -strLogPath $Private:strCertLogPath
                fncVerifyIssuer -strCertURL $Private:MyCertificationDistributionPointUrl -strEndpointName "CertificationDistributionPointUrl" -strLogPath $Private:strCertLogPath
                fncVerifyIssuer -strCertURL $Private:MyUnifiedLabelingDistributionPointUrl -strEndpointName "UnifiedLabelingDistributionPointUrl" -strLogPath $Private:strCertLogPath
                fncVerifyIssuer -strCertURL $Private:MyTelemetryDistributionPointUrl -strEndpointName "TelemetryDistributionPointUrl" -strLogPath $Private:strCertLogPath
                fncVerifyIssuer -strCertURL $Private:MyAIPv1PolicyDistributionPointUrl -strEndpointName "AIPv1PolicyDistributionPointUrl" -strLogPath $Private:strCertLogPath

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "Export endpoint URLs" -strLogValue "EndpointURLs.log"
                fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "Analyze endpoint URLs" -strLogValue "Proceeded"

            }
            
        }

        <# Checking for analyze AIP endpoints URLs [MSIP] if bootstrap was done / running in 'non-admin mode' / reading URLs from registry #>
        If ($(Test-Path -Path "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC\MSIP") -Eq $true) {

            <# Reading URLs from registry #>
            Get-ChildItem -Path "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC\MSIP" | ForEach-Object {

                <# Reading Tenant Id #>
                $Private:strMainKey = $_.Name.Substring(80).ToString()
         
                <# Actions, if it's about '.aadrm.com', but not about 'discover.aadrm.com' #>
                If ($Private:strMainKey -like "*.aadrm.com" -and $Private:strMainKey -notmatch "discover.aadrm.com") {

                    <# Private variabel definition for Tenant Id string #>
                    $Private:strTenantId = $Private:strMainKey.Remove(36)

                    <# Console output #> 
                    Write-Output (Write-Host "------------------------------------------------`nTenant Id: $Private:strTenantId`n------------------------------------------------`n" -ForegroundColor Magenta)

                    <# Create Tenant Id as first log entry #>
                    Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "------------------------------------------------`nTenant Id: $Private:strTenantId`n------------------------------------------------"

                    <# Defining and filling variables with URLs #>
                    $Private:MyLicensingIntranetDistributionPointUrl = (Get-ItemProperty "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC\MSIP\$Private:strMainKey\Identities" -ErrorAction SilentlyContinue).InternalUrl
                    $Private:MyLicensingExtranetDistributionPointUrl = (Get-ItemProperty "HKCU:\Software\Classes\Local Settings\Software\Microsoft\MSIPC\MSIP\$Private:strMainKey\Identities" -ErrorAction SilentlyContinue).ExternalUrl

                    <# Defining and filling variables: Extending colledted registry key with https and subkey #>
                    $Private:strMainKey = "https://$Private:strMainKey".ToString()
                    $Private:MyCertificationDistributionPointUrl = "$Private:strMainKey/_wmcs/certification"

                    <# Create Timestamp #>
                    Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value ("Date/Timestamp: " + (Get-Date -Verbose:$false -UFormat "$Private:MyTimestamp"))
                
                    <# Add read mode #>
                    Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value ("Read from registry [MSIP]:`n")

                    <# Calling function to verify endpoint and certificate issuer #>
                    fncVerifyIssuer -strCertURL $Private:MyLicensingIntranetDistributionPointUrl -strEndpointName "LicensingIntranetDistributionPointUrl" -strLogPath $Private:strCertLogPath
                    fncVerifyIssuer -strCertURL $Private:MyLicensingExtranetDistributionPointUrl -strEndpointName "LicensingExtranetDistributionPointUrl" -strLogPath $Private:strCertLogPath
                    fncVerifyIssuer -strCertURL $Private:MyCertificationDistributionPointUrl -strEndpointName "CertificationDistributionPointUrl" -strLogPath $Private:strCertLogPath
                    fncVerifyIssuer -strCertURL $Private:MyUnifiedLabelingDistributionPointUrl -strEndpointName "UnifiedLabelingDistributionPointUrl" -strLogPath $Private:strCertLogPath
                    fncVerifyIssuer -strCertURL $Private:MyTelemetryDistributionPointUrl -strEndpointName "TelemetryDistributionPointUrl" -strLogPath $Private:strCertLogPath
                    fncVerifyIssuer -strCertURL $Private:MyTelemetryDistributionPointUrl -strEndpointName "AIPv1PolicyDistributionPointUrl" -strLogPath $Private:strCertLogPath
                    
                }
            
            }
 
        }

    }
    Else { <# Actions for analyze AIP endpoints URLs [PORTAL] if bootstrap might have failed / reading URLs from portal / running in 'admin mode' #>

        <# Console output #>
        Write-Output (Write-Host "ATTENTION: Please request assistance from your administrator to proceed this option." -ForegroundColor Red)

        <# Console output; press yes or enter question #>
        $Private:ReadHost = Read-Host "Only if the above is true, please press [Y]es to continue, or [N]o to cancel"

        <# Actions, if yes was selected #>
        If ($Private:ReadHost -Eq "Y") {

            <# Console output #>
            Write-Output "Initializing, please wait..."

            <# Checking if running as administrator #>
            fncCheckForAdminPermissions("ANALYZE ENDPOINT URLs:")

            <# Check and update needed modules for PowerShellGallery.com #>
            fncUpdateRequiredModules

            <# Console output #>
            Write-Output "Connecting to AIPService..."

            <# Connect to AIPService #>
            If (Connect-AIPService -Verbose:$false) { <# Action when an AIPService connection is opened #>

                <# Private variabel definition for Tenant Id string #>
                $Private:strTenantId = (Get-AipServiceConfiguration).RightsManagementServiceId

                <# Console output #> 
                Write-Output "AIPService connected`n"
                Write-Output (Write-Host "------------------------------------------------`nTenant Id: $Private:strTenantId`n------------------------------------------------`n" -ForegroundColor Magenta)

                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "AIPService connected" -strLogValue $true

            }
            Else{ <# Action if AIPService connection failed #>
    
                <# Verbose/Logging #>
                fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "AIPService connected" -strLogValue $false 
                fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "Admin login" -strLogValue "Login failed"
    
                <# Console output #>
                Write-Output (Write-Host "Sign-In: Failed! Please try again.`n" -ForegroundColor Red)

                <# Signal sound #>
                [console]::beep(500,200)

                <# Set back window title to default #>
                $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

                <# Releasing private variables #>
                $Private:strTenantId = $null
                $Private:ReadHost = $null

                <# Exit function #>
                Break

            }

            <# Defining and filling variables with URLs #>
            $Private:MyLicensingIntranetDistributionPointUrl = (Get-AipServiceConfiguration).LicensingIntranetDistributionPointUrl.ToString()
            $Private:MyLicensingExtranetDistributionPointUrl = (Get-AipServiceConfiguration).LicensingExtranetDistributionPointUrl.ToString()
            $Private:MyCertificationDistributionPointUrl = (Get-AipServiceConfiguration).CertificationExtranetDistributionPointUrl.ToString()

            <# Create Tenant Id as first log entry #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "------------------------------------------------`nTenant Id: $Private:strTenantId`n------------------------------------------------"

            <# Create Timestamp #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value ("Date/Timestamp: " + (Get-Date -Verbose:$false -UFormat "$Private:MyTimestamp"))

            <# Add read mode #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value ("Read from portal:`n")

            <# Calling function to verify endpoint and certificate issuer #>
            fncVerifyIssuer -strCertURL $Private:MyLicensingIntranetDistributionPointUrl -strEndpointName "LicensingIntranetDistributionPointUrl" -strLogPath $Private:strCertLogPath
            fncVerifyIssuer -strCertURL $Private:MyLicensingExtranetDistributionPointUrl -strEndpointName "LicensingExtranetDistributionPointUrl" -strLogPath $Private:strCertLogPath
            fncVerifyIssuer -strCertURL $Private:MyCertificationDistributionPointUrl -strEndpointName "CertificationDistributionPointUrl" -strLogPath $Private:strCertLogPath
            fncVerifyIssuer -strCertURL $Private:MyUnifiedLabelingDistributionPointUrl -strEndpointName "UnifiedLabelingDistributionPointUrl" -strLogPath $Private:strCertLogPath
            fncVerifyIssuer -strCertURL $Private:MyTelemetryDistributionPointUrl -strEndpointName "TelemetryDistributionPointUrl" -strLogPath $Private:strCertLogPath
            fncVerifyIssuer -strCertURL $Private:MyAIPv1PolicyDistributionPointUrl -strEndpointName "AIPv1PolicyDistributionPointUrl" -strLogPath $Private:strCertLogPath

            <# Disconnect from AIPService #>
            Disconnect-AIPService | Out-Null

            <# Console output #>
            Write-Output "AIPService disconnected`n"
    
            <# Verbose/Logging #>
            fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "AIPService disconnected" -strLogValue $true
            fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "Export endpoint URLs" -strLogValue "EndpointURLs.log"
            fncLogging -strLogFunction "fncAnalyzeEndpointURLs" -strLogDescription "Analyze endpoint URLs" -strLogValue "Proceeded"

            <# Releasing private variables #>
            $Private:strTenantId = $null

            <# Signal sound #>
            #[console]::beep(1000,200)

        }
        <# Actions, if no (cancel) was selected #>
        ElseIf ($Private:ReadHost -eq "N") {

            <# Action, if function was called from command-line #>
            If ($Global:bolCommingFromMenu -eq $false) {

                <# Set back window title to default #>
                $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

                <# Exit function #>
                Break

            }

            <# Action, if function was called from the menu #>
            If ($Global:bolCommingFromMenu -eq $true) {

                <# Clearing console #>
                Clear-Host

                <# Calling show menu function #>
                fncShowMenu    

            }

        }
        Else { <# Actions, if any other key was pressed #>

            <# Action, if function was called from command-line #>
            If ($Global:bolCommingFromMenu -eq $false) {

                <# Set back window title to default #>
                $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

                <# Exit function #>
                Break

            }

            <# Action, if function was called from the menu #>
            If ($Global:bolCommingFromMenu -eq $true) {
 
                <# Clearing console #>
                Clear-Host
 
                <# Calling show menu function #>
                fncShowMenu    
 
            }

        }

    }

    <# Signal sound #>
    [console]::beep(1000,200)

    <# Console output #>
    Write-Output "Log file: $Global:strUserLogPath\Analyze\EndpointURLs.log"
    Write-Output (Write-Host "ANALYZE ENDPOINT URLs: Proceeded.`n" -ForegroundColor Green)
    
    <# Releasing private variables #>
    $Private:MyLicensingIntranetDistributionPointUrl = $null
    $Private:MyLicensingExtranetDistributionPointUrl = $null
    $Private:MyCertificationDistributionPointUrl = $null
    $Private:ReadHost = $null
    $Private:MyTimestamp = $null
    $Private:strTenantId = $null
    $Private:strMainKey = $null
    $Private:strCertLogPath = $null
        
}

<# Function to verify certificates issuer #>
Function fncVerifyIssuer ($strCertURL, $strEndpointName, $strLogPath) {

    <# Defining web request with URL #>
    $Private:strWebRequest = [System.Net.HttpWebRequest]::Create($strCertURL)

    <# Get web response for URL #>
    Try {

        <# Getting web response for analyzing certificates issuer #>
        $Private:strWebRequest.GetResponse() | Out-Null

    }
    Catch  { <# Action if analyze/web request failed #>

        <# Ignoring 'Catch' (happen when Web Request fail/end) #>

    }

    <# Defining certificate file conditions #>
    $Private:MyWebCert = $Private:strWebRequest.ServicePoint.Certificate
    
    <# Exporting web certificate #>
    $Private:MyCertBinaries = $Private:MyWebCert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)

    <# Creating temporarily certificate file #>
    Set-Content -Value $Private:MyCertBinaries -Encoding Byte -Path "$strLogPath\$strEndpointName.ce_"
    $Private:MyCertFile = New-Object System.Security.Cryptography.X509Certificates.X509Certificate
    
    <# Import certificate file for analyzing #>
    $Private:MyCertFile.Import("$strLogPath\$strEndpointName.ce_")

    <# Feed variable/certificate data with issuer #>
    $Private:MyCertFile = $Private:MyCertFile.GetIssuerName()

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncVerifyIssuer" -strLogDescription "Export certificate" -strLogValue "$strEndpointName.ce_"

    <# Calling function to verify endpoint https status code #>
    $Private:strHttpCode = fncVerifyEndpoint $strCertURL -strEndpointName $strEndpointName

    <# Analyzing certificate file issuer #>
    If ($Private:MyCertFile -cmatch "O=DigiCert" -or $Private:MyCertFile -cmatch "O=Microsoft") {

        <# Console output #> 
        Write-Output (Write-Host "Endpoint: $strEndpointName" -ForegroundColor Yellow)
        Write-Output (Write-Host "URL: $strCertURL" -ForegroundColor Yellow)
        Write-Output (Write-Host "Issuer: $Private:MyCertFile" -ForegroundColor Yellow)
        Write-Output (Write-Host "Status: Ok ($Private:strHttpCode)`n" -ForegroundColor Green)

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncVerifyIssuer" -strLogDescription $strEndpointName -strLogValue "Ok ($Private:strHttpCode)"

        <# Check for existing EndpointURLs.log file and extend it, if it exist #>
        If ($(Test-Path $Global:strUserLogPath"\Analyze\EndpointURLs.log") -Eq $true) {

            <# Exporting analyze result #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "Endpoint: $strEndpointName"
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "URL: $strCertURL"
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "Issuer: $Private:MyCertFile"
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "Status: Ok ($Private:strHttpCode)`n"

        }

    }
    Else { <# Actions, if verification fail #>

        <# Console output #>
        Write-Output (Write-Host "Endpoint: $strEndpointName" -ForegroundColor Yellow)
        Write-Output (Write-Host "URL: $strCertURL" -ForegroundColor Yellow)
        Write-Output (Write-Host "Issuer: $Private:MyCertFile" -ForegroundColor Yellow)
        Write-Output (Write-Host "Status: Error ($Private:strHttpCode)`n" -ForegroundColor Red)

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncVerifyIssuer" -strLogDescription $strEndpointName -strLogValue "Error ($Private:strHttpCode)"

        <# Check for existing EndpointURLs.log file and extend it, if it exist #>
        If ($(Test-Path $Global:strUserLogPath"\Analyze\EndpointURLs.log") -Eq $true) {

            <# Exporting analyze result #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "Endpoint: $strEndpointName"
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "URL: $strCertURL"
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "Issuer: $Private:MyCertFile"
            Add-Content -Path $Global:strUserLogPath"\Analyze\EndpointURLs.log" -Value "Status: Error ($Private:strHttpCode)`n"

        }

    }

    <# Reset certificate file settings for reuse #> 
    $Private:MyWebCert = $null
    $Private:MyCertFile = $null
    $Private:strHttpCode = $null
    $Private:strWebRequest = $null

}

<# Function to request license to check protection/encryption #>
Function fncAnalyzeProtection {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Analyze protection" -strLogValue "Initiated"

    <# Console output #>
    Write-Output "ANALYZE PROTECTION:"

    <# Console output #>
    Write-Output "Initializing, please wait..."

    <# Checking if 'Analyze'-folder exist and create it if not #>
    If ($(Test-Path -Path $Global:strUserLogPath"\Analyze") -Eq $false) {

        New-Item -ItemType Directory -Force -Path $Global:strUserLogPath"\Analyze" | Out-Null <# Defining Analyze path #>

    }

    <# Check for existing Protection.log file and create it, if it not exist #>
    If ($(Test-Path $Global:strUserLogPath"\Analyze\Protection.log") -Eq $false) {

        <# Create Protection.log file #>
        Out-File -FilePath $Global:strUserLogPath"\Analyze\Protection.log" -Encoding UTF8 -Append -Force

    }

    <# Create Timestamp as first log entry #>
    Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value ("Date/Timestamp : " + (Get-Date -Verbose:$false -UFormat "%y%m%d-%H%M%S"))

    <# Check for existing/previous (protected) Protection.ptxt file #>
    If ($(Test-Path $Global:strUserLogPath"\Analyze\Protection.ptxt") -Eq $true) {

        <# Delete existing/previous Protection.ptxt file to be able to create new without error #>
        fncDeleteItem "\\?\$Global:strUserLogPath\Analyze\Protection.ptxt"

    }

    <# Console output #>
    Write-Output (Write-Host "Verifying protection...`n")

    <# Checking for AIP client 1/2 and trying to protect a sample file #>
    If (Get-Module -ListAvailable -Name AzureInformationProtection) {

        <# Feeding variable with AIP client version information #>
        $strAIPClientVersion = $((Get-Module -ListAvailable -Name AzureInformationProtection).Version).ToString()

        <# Check for existing Protection.txt sample file and create it, if it not exist #>
        If ($(Test-Path $Global:strUserLogPath"\Analyze\Protection.txt") -Eq $false) {

            <# Creating sample text file #>
            Out-File -FilePath $Global:strUserLogPath"\Analyze\Protection.txt" -Encoding UTF8 -Append -Force

            <# Add content to file #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.txt" -Value "This file has been created by the RMS_Support_Tool."

        }

        <# Console output #>
        Write-Output (Write-Host "License : {[OwnerMail, RMSSupToolEncrTest@microsoft.com], [UserMail, RMSSupToolEncrTest@microsoft.com], [Permissions, EDIT]}" -ForegroundColor Yellow)

        <# Logging #>
        fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "License created" -strLogValue $true

        <# Trying protection with AIPv1 client #>
        If ($strAIPClientVersion.StartsWith("1") -eq $true) {
            
            <# Feeding variable with temporary license #>
            $Private:TempLicense = New-RMSProtectionLicense -OwnerEmail "RMSSupToolEncrTest@microsoft.com" -UserEmail "RMSSupToolEncrTest@microsoft.com" -Permission EDIT
            
            <# Add content to log file #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "License : {[OwnerMail, RMSSupToolEncrTest@microsoft.com], [UserMail, RMSSupToolEncrTest@microsoft.com], [Permission, EDIT]}"

            <# Protect test filw with temporary license #>
            $Private:TempTestFile = (Protect-RMSFile -License $Private:TempLicense -InPlace -File $Global:strUserLogPath"\Analyze\Protection.txt" -ErrorAction SilentlyContinue).EncryptedFile

            <# Check, if protection was successfull #>
            If ($Private:TempTestFile.EndsWith(".ptxt") -eq $true) {

                <# Checking for protection status #>
                If ((Get-RMSFileStatus -file $Private:TempTestFile -ErrorAction SilentlyContinue).Status -match "Protected") {

                    <# Console output #>
                    Write-Output (Write-Host "File : $Global:strUserLogPath\Analyze\Protection.ptxt" -ForegroundColor Yellow)
                    Write-Output (Write-Host "Verification : Successfull`n" -ForegroundColor Green)

                    <# Logging #>
                    fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Verification" -strLogValue "Successfull"

                    <# Add content to log file #>
                    Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "File : $Global:strUserLogPath\Analyze\Protection.ptxt"
                    Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "Verification : Successfull`n"

                }
                Else {

                    <# Console output #>
                    Write-Output (Write-Host "Verification : Failed (ERROR)`n" -ForegroundColor Red)

                    <# Logging #>
                    fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Verification" -strLogValue "Failed (ERROR)"

                    <# Add content to log file #>
                    Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "Verification : Failed (ERROR)`n"

                }

            }

        }
        <# Trying protection with AIPv2 client #>
        ElseIf ($strAIPClientVersion.StartsWith("2") -eq $true) {

            <# Feeding variable with temporary license #>
            $Private:TempLicense = New-AIPCustomPermissions -Users "RMSSupToolEncrTest@microsoft.com" -Permissions Viewer

            <# Add content to log file #>
            Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "License : {[Users, RMSSupToolEncrTest@microsoft.com], [Permissons, VIEWER]}"

            <# Remember default progress bar status: "Continue" #>
            $Private:strOriginalPreference = $Global:ProgressPreference 
            $Global:ProgressPreference = "SilentlyContinue" <# Hiding progress bar #>

            <# Protect and check, if it was successfull #>
            If ((Set-AIPFileLabel $Global:strUserLogPath"\Analyze\Protection.txt" -CustomPermissions $Private:TempLicense -ErrorAction SilentlyContinue).Status -eq "Success") {

                <# Console output #>
                Write-Output (Write-Host "File : $Global:strUserLogPath\Analyze\Protection.ptxt" -ForegroundColor Yellow)
                Write-Output (Write-Host "Verification : Successfull`n" -ForegroundColor Green)

                <# Logging #>
                fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Verification" -strLogValue "Successfull"

                <# Add content to log file #>
                Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "File : $Global:strUserLogPath\Analyze\Protection.ptxt"
                Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "Verification : Successfull`n"

            }
            Else {

                <# Console output #>
                Write-Output (Write-Host "Verification : Failed (ERROR)`n" -ForegroundColor Red)

                <# Logging #>
                fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Verification" -strLogValue "Failed (ERROR)"

                <# Add content to log file #>
                Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "Verification : Failed (ERROR)`n"

            }

            <# Set back progress bar to previous default #>
            $Global:ProgressPreference = $Private:strOriginalPreference

        }

    }
    Else {

        <# Console output #>
        Write-Output (Write-Host "ATTENTION: Microsoft® Azure Information Protection cmdlets are required to proceed this option!`nPlease review point 1 in the requirements section of the help file for additional information.`n" -ForegroundColor Red)
        
        <# Add content to log file #>
        Add-Content -Path $Global:strUserLogPath"\Analyze\Protection.log" -Value "Verification : Failed (No AIP client)`n"

        <# Console output #> 
        Write-Output "Log file: $Global:strUserLogPath\Analyze\Protection.log"
        Write-Output (Write-Host "ANALYZE PROTECTION: Failed.`n" -ForegroundColor Red)

        <# Signal sound #>
        [console]::beep(500,200)

        <# Logging: If AIP client is not installed #>
        fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "AIP client installed" -strLogValue $false
        fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Verification" -strLogValue "Failed (No AIP client)"
        fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Export analyze protection" -strLogValue "Protection.log"
        fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Analyze protection" -strLogValue "Failed"

        <# Action, if function was called from command-line #>
        If ($Global:bolCommingFromMenu -eq $false) {

            <# Set back window title to default #>
            $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle

            <# Exit function #>
            Break

        }

        <# Action, if function was called from the menu #>
        If ($Global:bolCommingFromMenu -eq $true) {
 

            <# Calling pause function #>
            fncPause
    
            <# Clearing console #>
            Clear-Host

            <# Calling show menu function #>
            fncShowMenu
 
        }

    }

    <# Deleting sample text file #>
    fncDeleteItem "\\?\$Global:strUserLogPath\Analyze\Protection.txt"

    <# Clearing variables for re-use #>
    $Private:TempLicense = $null
    $Private:TempTestFile = $null
    $strAIPClientVersion = $null

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Export analyze protection" -strLogValue "Protection.log"
    fncLogging -strLogFunction "fncAnalyzeProtection" -strLogDescription "Analyze protection" -strLogValue "Proceeded"

    <# Console output #> 
    Write-Output "Log file: $Global:strUserLogPath\Analyze\Protection.log"
    Write-Output (Write-Host "ANALYZE PROTECTION: Proceeded.`n" -ForegroundColor Green)

    <# Signal sound #>
    [console]::beep(1000,200)

}

<# Function to compress all log files into a .zip file #>
Function fncCompressLogs {

    <# Console output #> 
    Write-Output "COMPRESS LOGS:`nCompressing logs, please wait...`n"
        
    <# Defining default zip folder path #>
    $Global:strZipLogPath = $Global:strTempFolder + "\RMS_Support_Tool"

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncCompressLogs" -strLogDescription "Compress logs" -strLogValue "Initiated"
    fncLogging -strLogFunction "fncCompressLogs" -strLogDescription "Zip folder path" -strLogValue $Global:strZipLogPath

    <# Check, if MSOIDSVC service (Microsoft® Online Services Sign-in Assistant) exist #>
    If (Get-Service "MSOIDSVC" -ErrorAction SilentlyContinue) {

        <# Checking if servcie is running and acting accordingly #>
        If ((Get-Service "MSOIDSVC").Status -Eq "Running") { <# Needs to be stopped to prevent file locks while compressing zip file #>

            <# Stop service #>
            Stop-Service -Name "MSOIDSVC"

        }

    }

    <# Compress all files into a .zip file #>
    If ($(Test-Path -Path $Global:strZipLogPath) -Eq $true) { <# Actions, if path exist #>

        <# Defining .zip file name #>
        $Private:strZipFile = "RMS_Support_Tool (" + $env:USERNAME + (Get-Date -UFormat "-%H%M%S") + ").zip".ToString()

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncCompressLogs" -strLogDescription "Zip file name" -strLogValue $Private:strZipFile
        fncLogging -strLogFunction "fncCompressLogs" -strLogDescription "Compress logs" -strLogValue "Proceeded"

        <# Compress all files and logs into zip file (overwrites) #>
        Compress-Archive -Path $Global:strZipLogPath"\Logs\*" -DestinationPath $Global:strZipLogPath\$Private:strZipFile -Force -ErrorAction SilentlyContinue

    }

    <# Console output #> 
    Write-Output "Zip file: $Global:strZipLogPath\$Private:strZipFile"
    Write-Output (Write-Host "COMPRESS LOGS: Proceeded.`n" -ForegroundColor Green)

    <# Cleaning Logs folders to start from scratch next time #>
    Remove-Item "\\?\$Global:strZipLogPath\Logs" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null

    <# Signal sound #>
    [console]::beep(1000,200)

    <# Check, if MSOIDSVC service (Microsoft® Online Services Sign-in Assistant) exist #>
    If (Get-Service "MSOIDSVC" -ErrorAction SilentlyContinue) { <# Checking if service exist #>

        <# Checking if servcie is not running and acting accordingly #>
        If (-Not (Get-Service "MSOIDSVC").Status -Eq "Running") { <# Action, if service is not running. #>

            <# Start service #>
            Start-Service -Name "MSOIDSVC"

        }

    }

    <# Releasing private variable #>
    $Private:strZipFile = $null

    <# Releasing global variable #>
    $Global:strWindowsEdition = $null
    $Global:strZipLogPath = $null

}

<# Function to pause menu for message display #>
Function fncPause {

    <# Filling variable with default pause message #>
    $Private:strPauseMessage = "Press any key to continue"

    <# Pausing the script module with a message #>
    If ($Global:psISE) { <# Actions, if running in PowerShell ISE #>

        Add-Type -AssemblyName System.Windows.Forms
        [System.Windows.Forms.MessageBox]::Show("$Private:strPauseMessage")

    }
    Else { <# Actions, if running in PowerShell command window #>

        <# Console output #> 
        Write-Output (Write-Host $Private:strPauseMessage -ForegroundColor Yellow)
        $Private:strValue = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

    }

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncPause" -strLogDescription "Pause" -strLogValue "Called"

}

<# Function to call script module menu #>
Function fncShowMenu {

    <# Clearing console #>
    Clear-Host

    <# Helper variable to control menu handling inside function calls #>
    $Global:bolCommingFromMenu = $true

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncShowMenu" -strLogDescription "Main menu" -strLogValue "Called"

    <# Menu output #>
    Write-Output (Write-Host " [I] INFORMATION" -ForegroundColor Green)
    Write-Output (Write-Host " [D] DISCLAIMER" -ForegroundColor Red)
    Write-Output (Write-Host " [H] HELP" -ForegroundColor Green)
    Write-Output (Write-Host " [R] RESET" -ForegroundColor Yellow)
    Write-Output (Write-Host " [P] RECORD PROBLEM" -ForegroundColor Yellow)
    Write-Output (Write-Host " [C] COLLECT" -ForegroundColor Yellow)
    If (@($Global:MenuCollectExtended) -Match $true) {
        Write-Output (Write-Host " ├──[A] AIP service configuration" -ForegroundColor Yellow)
        Write-Output (Write-Host " └──[L] Labels and policies" -ForegroundColor Yellow)
        Write-Output (Write-Host " [Y] ANALYZE" -ForegroundColor Yellow)
        If (@($Global:MenuAnalyzeExtended) -Match $true) {
            Write-Output (Write-Host " ├──[U] Endpoint URLs" -ForegroundColor Yellow)
            Write-Output (Write-Host " └──[T] Protection" -ForegroundColor Yellow)
            Write-Output (Write-Host " [Z] COMPRESS LOGS" -ForegroundColor Yellow)
            Write-Output (Write-Host " [X] EXIT`n" -ForegroundColor Green)
        }
        Else {
            Write-Output (Write-Host " [Z] COMPRESS LOGS" -ForegroundColor Yellow)
            Write-Output (Write-Host " [X] EXIT`n" -ForegroundColor Green)
        }        
    }
    Else {
        Write-Output (Write-Host " [Y] ANALYZE" -ForegroundColor Yellow)
        If (@($Global:MenuAnalyzeExtended) -Match $true) {
            Write-Output (Write-Host " ├──[U] Endpoint URLs" -ForegroundColor Yellow)
            Write-Output (Write-Host " └──[T] Protection" -ForegroundColor Yellow)
            Write-Output (Write-Host " [Z] COMPRESS LOGS" -ForegroundColor Yellow)
            Write-Output (Write-Host " [X] EXIT`n" -ForegroundColor Green)
        }
        Else {
            Write-Output (Write-Host " [Z] COMPRESS LOGS" -ForegroundColor Yellow)
            Write-Output (Write-Host " [X] EXIT`n" -ForegroundColor Green)
        }         
    }

    <# Defining menu selection variable #>
    $Private:intMenuSelection = Read-Host "Please select an option and press enter"

    <# Actions, for information menu selected #>
    If ($Private:intMenuSelection -Eq "I") {
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[I] INFORMATION" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host
        
        <# Calling information function #>
        fncInformation
        
        <# Calling pause function #>
        fncPause

    }

    <# Actions, for disclaimer menu selected #>
    If ($Private:intMenuSelection -Eq "D") {
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[D] DISCLAIMER" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host

        <# Calling disclaimer function #>
        fncDisclaimer

        <# Calling pause function #>
        fncPause
    }
   
    <# Actions, for help menu selected #>
    If ($Private:intMenuSelection -Eq "H") {
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[H] HELP" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host

        <# Calling help function #>
        fncHelp

    }
    
    <# Actions, for reset menu selected #>
    If ($Private:intMenuSelection -Eq "R") {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[R] RESET" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host

        <# Calling reset function #>
        fncReset

        <# Calling pause function #>
        fncPause

    }

    <# Actions, for record problem menu selected #>
    If ($Private:intMenuSelection -Eq "P") {
        
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[P] RECORD PROBLEM" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host
        
        <# Calling user logging function #>
        fncRecordProblem
        
        <# Calling pause function #>
        fncPause

    }

    <# Actions, for collect menu selected #>
    If ($Private:intMenuSelection -Eq "C") {
    
        <# Show/Hide menu extenstion #>
        If (@($Global:MenuCollectExtended) -Match $true) {$Global:MenuCollectExtended = $false}
        Else {$Global:MenuCollectExtended = $true}

    }

    <# Actions, for AIP service configuration menu selected #>
    If ($Private:intMenuSelection -Eq "A") {
    
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[A] AIP service configuration" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host
        
        <# Calling function to collect AIP service configuration #>
        fncCollectAipConfig
        
        <# Calling pause function #>
        fncPause

    }

    <# Actions, for Labels and Policies menu selected #>
    If ($Private:intMenuSelection -Eq "L") {
    
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[L] Labels and Policies" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host
        
        <# Calling Labels and Policies function #>
        fncCollectLabelsAndPolicies
        
        <# Calling pause function #>
        fncPause

    }

    <# Actions, for analyze menu selected #>
    If ($Private:intMenuSelection -Eq "Y") {

        <# Show/Hide menu extenstion #>
        If (@($Global:MenuAnalyzeExtended) -Match $true) {$Global:MenuAnalyzeExtended = $false}
        Else {$Global:MenuAnalyzeExtended = $true}
        
    }

    <# Actions, for AnalyzeEndpoints menu selected #>
    If ($Private:intMenuSelection -Eq "U") {
    
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[U] Endpoint URLs" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host
        
        <# Calling AnalzeEndpoints function #>
        fncAnalyzeEndpointURLs
        
        <# Calling pause function #>
        fncPause
        
    }

    <# Actions, for AnalyzeProtection menu selected #>
    If ($Private:intMenuSelection -Eq "T") {
    
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[T] Protection" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host

        <# Calling AnalyzeProtection function #>
        fncAnalyzeProtection
        
        <# Calling pause function #>
        fncPause
        
    }

    <# Actions, for compress logs menu selected #>
    If ($Private:intMenuSelection -Eq "Z") {
    
        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[Z] COMPRESS LOGS" -strLogValue "Selected"
        
        <# Clearing console #>
        Clear-Host
        
        <# Calling compress logs function #>
        fncCompressLogs
        
        <# Calling pause function #>
        fncPause
        
    }

    <# Actions, for exit menu selected #>
    If ($Private:intMenuSelection -Eq "X") {

        <# Verbose/Logging #>
        fncLogging -strLogFunction "fncShowMenu" -strLogDescription "[X] EXIT" -strLogValue "Selected"

        <# Clear global variables #>
        $Global:bolCommingFromMenu = $false

        <# Set back window title to default #>
        $Global:host.UI.RawUI.WindowTitle = $Global:strDefaultWindowTitle
        
        <# Exit function #>
        Break
        
    }
    Else {

        <# Clearing console #>
        Clear-Host

        <# Calling show menu function #>
        fncShowMenu

    }

}

<# Function to show version #>
Function fncShowVersion {

    <# Verbose/Logging #>
    fncLogging -strLogFunction "fncShowVersion" -strLogDescription "Version" -strLogValue "Called"

    <# Console output version information #>
    Write-Output "You are using version: $Global:strVersion`n"

}

<# Creating default log entries #>
fncCreateDefaultLogEntries

<# Checking Windows version #>
fncCheckWindowsVersion

<# Export functions for script module manifest #>
Export-ModuleMember -Function RMS_Support_Tool