CTXLogging.psm1

#region global variables
$global:ControllerConfigFiles = @('Broker\Service\BrokerService.exe.config','MachineCreation\Service\Citrix.MachineCreation.exe.Config','AdIdentity\Service\Citrix.ADIdentity.exe.Config','Configuration\Service\Citrix.Configuration.exe.Config','Host\Service\Citrix.Host.exe.Config')
$global:ControllerServices = @('CitrixBrokerService','CitrixMachineCreationService','CitrixAdIdentityService','CitrixConfigurationService','CitrixHostService')
$global:VDAConfigFiles = @('Virtual Desktop Agent\BrokerAgent.exe.config')
$global:VDAServices = @('BrokerAgent')

#endregion

#region general functions

Function Set-Registry
{
    <#
            .SYNOPSIS
            This function gives you the ability to create/change Windows registry keys and values. If you want to create a value but the key doesn't exist, it will create the key for you.

            .PARAMETER RegKey
            Path of the registry key to create/change

            .PARAMETER RegValue
            Name of the registry value to create/change

            .PARAMETER RegData
            The data of the registry value

            .PARAMETER RegType
            The type of the registry value. Allowed types: String,DWord,Binary,ExpandString,MultiString,None,QWord,Unknown. If no type is given, the function will use String as the type.

            .EXAMPLE
            Set-Registry -RegKey HKLM:\SomeKey -RegValue SomeValue -RegData 1111 -RegType DWord
            This will create the key SomeKey in HKLM:\. There it will create a value SomeValue of the type DWord with the data 1111.

            .NOTES
            Author: Dominik Britz
            Source: https://github.com/DominikBritz
    #>

    [CmdletBinding()]
    PARAM
    (
        $RegKey,
        $RegValue,
        $RegData,
        [ValidateSet('String','DWord','Binary','ExpandString','MultiString','None','QWord','Unknown')]
        $RegType = 'String'    
    )

    If (-not $RegValue)
    {
        If (-not (Test-Path $RegKey))
        {
            Write-Verbose "The key $RegKey does not exist. Try to create it."
            Try
            {
                New-Item -Path $RegKey -Force
            }
            Catch
            {
                Write-Error -Message $_
            }
            Write-Verbose "Creation of $RegKey was successfull"
        }        
    }

    If ($RegValue)
    {
        If (-not (Test-Path $RegKey))
        {
            Write-Verbose "The key $RegKey does not exist. Try to create it."
            Try
            {
                New-Item -Path $RegKey -Force
                Set-ItemProperty -Path $RegKey -Name $RegValue -Value $RegData -Type $RegType -Force
            }
            Catch
            {
                Write-Error -Message $_
            }
            Write-Verbose "Creation of $RegKey was successfull"
        }
        Else 
        {
            Write-Verbose "The key $RegKey already exists. Try to set value"
            Try
            {
                Set-ItemProperty -Path $RegKey -Name $RegValue -Value $RegData -Type $RegType -Force
            }
            Catch
            {
                Write-Error -Message $_
            }
            Write-Verbose "Creation of $RegValue in $RegKey was successfull"           
        }
    }
}




Function Restart-CitrixService
{
    PARAM
    (
        [switch]$Controller,
        [switch]$VDA    
    )

    If ($Controller)
    {
        $Services = $ControllerServices
    }

    If ($VDA)
    {
        $Services = $VDAServices
    }    

    Foreach ($Service in $Services)
    {
        Try
        {
            Stop-Service $Service
            Start-Service $Service
        }
        Catch
        {
            Throw $_        
        }
    }

}
#endregion

#region Controller and VDA functions
Function Add-XMLNode
{
    PARAM
    (
        $Key,
        $Value,
        $xml
    )

    begin{}

    process
    {
        $xml.CreateElement('add') | ForEach-Object { # Could have used a variable defenition here but wanted to disable console output with out-null
            $newAppSetting = $_
        $xml.Configuration.AppSettings.AppendChild($newAppSetting) | Out-Null}
        $newAppSetting.SetAttribute('key',"$($Key)")
        $newAppSetting.SetAttribute('value', "$($Value)")

        Return $xml
    }
    end{}
}

Function Remove-XMLNode
{
    PARAM
    (
        $node,
        $xml
    )
    begin{}

    process
    {
        $xml.configuration.appSettings.RemoveChild($node) | Out-Null

        Return $xml
    }
    end{}
}

Function Enable-ControllerVDALogging
{
    PARAM
    (
        $ConfigFile,
        $InstallFolder,
        $OverwriteLogfile,
        [switch]$Controller,
        [switch]$VDA
    )
    $ConfigFile = Join-Path $InstallFolder $ConfigFile
            
    Try
    {
        $xml = [xml] (Get-Content -Path $ConfigFile -ErrorAction Stop)
    }
    Catch
    {
        Throw $_        
    }


    $node = $xml.configuration.appSettings.ChildNodes | Where-Object {$_.key -eq 'LogFileName'}
    
    If ($node.key -eq 'LogFileName')
    {
        If (($ConfigFile.split('\')[-2]) -eq 'Service')
        {
            $Service = $ConfigFile.split('\')[-3]
        
        }
        Else
        {
            $Service = $ConfigFile.split('\')[-2]
        }

        Write-Warning "Logging for $Service is already enabled. Nothing to do here."
        Return                   
    }
    
    If (-not(Test-Path $LogPathFolder)) 
    {
        New-Item $LogPathFolder -ItemType Directory -ErrorAction Stop | Out-Null
    }
    $LogName = ($ConfigFile.split('\')[-1]) + '.log' | ForEach-Object {$_ -ireplace('.Config.log','.log')}
    $xml = Add-XMLNode -Key 'LogFileName' -Value $(Join-Path $LogPathFolder $LogName) -xml $xml
    $xml = Add-XMLNode -Key 'OverwriteLogFile' -Value $OverwriteLogFile -xml $xml        

    Try
    {
        $xml.Save($ConfigFile)
        If ($Controller)
        {
            Restart-CitrixService -Controller
        }
        ElseIf ($VDA)
        {
            Restart-CitrixService -VDA
        }
        
        If (($ConfigFile.split('\')[-2]) -eq 'Service')
        {
            $Service = $ConfigFile.split('\')[-3]        
        }
        Else
        {
            $Service = $ConfigFile.split('\')[-2]
        }
                
        Write-Output "Logging for $Service is now enabled. The path is $(Join-Path $LogPathFolder $LogName)."
        #Start-Process explorer.exe -ArgumentList "$LogPathFolder"
    }
    Catch
    {
        Throw $_    
    }
}

Function Disable-ControllerVDALogging
{
    PARAM
    (
        $ConfigFile,
        $InstallFolder,
        [switch]$Controller,
        [switch]$VDA
    )

    $ConfigFile = Join-Path $InstallFolder $ConfigFile

    Try
    {
        $xml = [xml] (Get-Content -Path $ConfigFile -ErrorAction Stop)
    }
    Catch
    {
        Throw $_
    }

    $node = $xml.configuration.appSettings.ChildNodes | Where-Object {$_.key -eq 'LogFileName'}

    If (-not($node.key -eq 'LogFileName'))
    {
        If (($ConfigFile.split('\')[-2]) -eq 'Service')
        {
            $Service = $ConfigFile.split('\')[-3]
        
        }
        Else
        {
            $Service = $ConfigFile.split('\')[-2]
        }
        Write-Warning "Logging for $Service is already disabled. Nothing to do here."
        return
    }
    Else
    {
        $xml = Remove-XMLNode -node $node -xml $xml
        $node = $xml.configuration.appSettings.ChildNodes | Where-Object {$_.key -eq 'OverwriteLogFile'}
        $xml = Remove-XMLNode -node $node -xml $xml            
        Try
        {
            $xml.Save($ConfigFile)
            If ($Controller)
            {
                Restart-CitrixService -Controller
            }
            If ($VDA)
            {
                Restart-CitrixService -VDA
            }

            If (($ConfigFile.split('\')[-2]) -eq 'Service')
            {
                $Service = $ConfigFile.split('\')[-3]
        
            }
            Else
            {
                $Service = $ConfigFile.split('\')[-2]
            }

            Write-Output "Logging for $Service is now disabled"
        }
        Catch
        {
            Throw $_ 
        }
    }    
}

Function Enable-CTXControllerLogging
{
    <#
            .SYNOPSIS
            Enables logging of the Citrix controller services

            .PARAMETER LogPathFolder
            Path to the folder where the losg should be saved. If the folder is not present the script will create it for you. Default is C:\XDLogs.

            .PARAMETER OverwriteLogFile
            Enabling this parameter will overwrite the log files each time the controller services are started. Default is false.

            .PARAMETER InstallFolder
            If you did not install the Citrix controller in the default directory please provide the installation folder. Default is 'C:\Program Files\Citrix.

            .EXAMPLE
            Enable-CTXControllerLogging
            This will enable logging to the path 'C:\XDLogs'. Log file will not be overwritten. VDA is installed in folder 'C:\Program Files\Citrix'.

            .EXAMPLE
            Enable-CTXControllerLogging -LogPathFolder '\\server\share' -OverwriteLogFile
            This will enable logging to the path '\\server\share'. Log file will be overwritten each time a controller service restarts. Controller is installed in folder 'C:\Program Files\Citrix'.

    #>

    
    PARAM
    (
        [string]
        $LogPathFolder = 'C:\XDLogs',
        
        [switch]
        $OverwriteLogFile,

        [string]
        $InstallFolder = 'C:\Program Files\Citrix'    
    )    

    If ($OverwriteLogFile)
    {
        [string]$OverwriteLogFile = 'True'
    }
    Else
    {
        [string]$OverwriteLogFile = 'False'
    }

    $ConfigFiles = $ControllerConfigFiles

    Foreach ($ConfigFile in $ConfigFiles) 
    {
        Enable-ControllerVDALogging -ConfigFile $ConfigFile -InstallFolder $InstallFolder -OverwriteLogfile $OverwriteLogFile -Controller
    }   
}

Function Disable-CTXControllerLogging
{
    <#
            .SYNOPSIS
            Disables the logging of Citrix controller services.

            .PARAMETER InstallFolder
            If you did not install the Citrix controller in the default directory please provide the installation folder. Default is 'C:\Program Files\Citrix'.

            .EXAMPLE
            Disable-CTXControllerLogging
            Disables logging of Citrix controller services.
    #>

    
    PARAM
    (
        [string]
        $InstallFolder = 'C:\Program Files\Citrix'    
    )
            
    $ConfigFiles = $ControllerConfigFiles

    Foreach ($ConfigFile in $ConfigFiles) 
    {
        Disable-ControllerVDALogging -ConfigFile $ConfigFile -InstallFolder $InstallFolder -Controller
    }    
}

Function Enable-CTXVDALogging
{
    <#
            .SYNOPSIS
            Enables Citrix virtual desktop agent logging

            .PARAMETER LogPathFolder
            Path to the folder where the log should be saved. If the folder is not present the script will create it for you. Default is C:\XDLogs.

            .PARAMETER OverwriteLogFile
            Enabling this parameter will overwrite the log file each time the virtual desktop agent service is started. Default is false.

            .PARAMETER InstallFolder
            If you did not install the virtual desktop agent in the default directory please provide the installation folder. Default is 'C:\Program Files\Citrix'.

            .EXAMPLE
            Enable-CTXVDALogging
            This will enable logging to the path 'C:\XDLogs'. Log file will not be overwritten. VDA is installed in folder 'C:\Program Files\Citrix'.

            .EXAMPLE
            Enable-CTXVDALogging -LogPathFolder '\\server\share' -OverwriteLogFile
            This will enable logging to the path '\\server\share'. Log file will be overwritten each time the service restarts. VDA is installed in folder 'C:\Program Files\Citrix'.

    #>

    PARAM
    (
        [string]
        $LogPathFolder = 'C:\XDLogs',
        
        [switch]
        $OverwriteLogFile,

        [string]
        $InstallFolder = 'C:\Program Files\Citrix'    
    )
    
    If ($OverwriteLogFile)
    {
        [string]$OverwriteLogFile = 'True'
    }
    Else
    {
        [string]$OverwriteLogFile = 'False'
    }

    $ConfigFiles = $VDAConfigFiles

    Foreach ($ConfigFile in $ConfigFiles) 
    {
        Enable-ControllerVDALogging -ConfigFile $ConfigFile -InstallFolder $InstallFolder -OverwriteLogfile $OverwriteLogFile -VDA
    }   
}

Function Disable-CTXVDALogging
{
    <#
            .SYNOPSIS
            Disables Citrix virtual desktop agent logging.

            .PARAMETER InstallFolder
            If you did not install the virtual desktop agent in the default directory please provide the installation folder. Default is 'C:\Program Files\Citrix'.

            .EXAMPLE
            Disable-CTXVDALogging
            Disables logging of the Citrix virtual desktop agent service.
    #>

    
    PARAM
    (
        [string]
        $InstallFolder = 'C:\Program Files\Citrix'    
    )
            
    $ConfigFiles = $VDAConfigFiles

    Foreach ($ConfigFile in $ConfigFiles) 
    {
        Disable-ControllerVDALogging -ConfigFile $ConfigFile -InstallFolder $InstallFolder -VDA
    }    
}

#endregion

#region Receiver functions
function Enable-CTXReceiverLogging
{
    <#
            .SYNOPSIS
            Enables logging for Citrix Receiver.
        
            .DESCRIPTION
            Enables logging for Citrix Receiver. You can enable general, Authentication Manager and Self-Service Plugin logging. Have a look at the parameters for details. You have to reboot the system for changes to take effect.

            .PARAMETER General
            Enables general logging for Citrix Receiver.

            .PARAMETER AuthenticationManager
            Use this parameter settings to enable logging for authentication issues (for example StoreFront, and so on.)

            .PARAMETER SelfServicePlugin
            Use this parameter to enable logging related to subscribed applications and the communication with StoreFront.

            .EXAMPLE
            Enable-CTXReceiverLogging -General
            Enables general logging for Citrix Receiver

            .EXAMPLE
            Enable-CTXReceiverLogging -General -AuthenticationManager -SelfServicePlugin
            Enables general, Authentication Manager and SelfService Plugin logging for Citrix Receiver
    #>


    [cmdletbinding()]    
    PARAM
    (
        [switch]$General,
        [switch]$AuthenticationManager,
        [switch]$SelfServicePlugin
    )
    
    begin
    {
        If ((-not $General) -and (-not $AuthenticationManager) -and (-not $SelfServicePlugin))
        {
            Throw 'No parameter was given. You can get parameter info with the command Get-Help Enable-CTXReceiverLogging'
        }
        
        $Is64BitOperatingSystem = [environment]::Is64BitOperatingSystem
    }
    
    process
    {
        Try
        {
            If ($General)
            {
                If ($Is64BitOperatingSystem)
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix -RegValue ReceiverVerboseTracingEnabled -RegData 1 -RegType DWord
                }
                Else
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix -RegValue ReceiverVerboseTracingEnabled -RegData 1 -RegType DWord
                }
                Write-Output "Receiver general logging is enabled. Please reboot your system. Log files will be saved in '%localappdata%\Citrix\Receiver'"
            }
            
            If ($AuthenticationManager)
            {
                If ($Is64BitOperatingSystem)
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\AuthManager -RegValue LoggingMode -RegData verbose -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\AuthManager -RegValue TracingEnabled -RegData true -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\AuthManager -RegValue SDKTracingEnabled -RegData true -RegType String
                }
                Else
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\AuthManager -RegValue LoggingMode -RegData verbose -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\AuthManager -RegValue TracingEnabled -RegData true -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\AuthManager -RegValue SDKTracingEnabled -RegData true -RegType String
                }
                Write-Output "Receiver Authentication Manager logging is enabled. Please reboot your system. Log files will be saved in '%localappdata%\Citrix\AuthManager'"
            }
            
            If ($SelfServicePlugin)
            {
                If ($Is64BitOperatingSystem)
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\Dazzle -RegValue Tracing -RegData true -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\Dazzle -RegValue AuxTracing -RegData true -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\Dazzle -RegValue DefaultTracingConfiguration -RegData 'global all –detail' -RegType String
                }
                Else
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\Dazzle -RegValue Tracing -RegData true -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\Dazzle -RegValue AuxTracing -RegData true -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\Dazzle -RegValue DefaultTracingConfiguration -RegData 'global all –detail' -RegType String
                }
                Write-Output "Receiver Self-Service Plugin logging is enabled. Please reboot your system. Log files will be saved in '%localappdata%\Citrix\Receiver\SelfService'"
            }
        }
        
        Catch
        {
            Throw $_
        }
    
    }
}

function Disable-CTXReceiverLogging
{
    <#
            .SYNOPSIS
            Disables logging for Citrix Receiver

            .DESCRIPTION
            Disables logging for Citrix Receiver. You can disable general, Authentication Manager and Self-Service Plugin logging. Have a look at the parameters for details. You have to reboot the system for changes to take effect.

            .PARAMETER General
            Disables general logging for Citrix Receiver

            .PARAMETER AuthenticationManager
            Use this parameter settings to disable logging for authentication issues (for example StoreFront, and so on.)

            .PARAMETER SelfServicePlugin
            Use this parameter to disable logging related to subscribed applications and the communication with StoreFront.

            .EXAMPLE
            Disable-CTXReceiverLogging -General
            Disables general logging for Citrix Receiver

            .EXAMPLE
            Disable-CTXReceiverLogging -General -AuthenticationManager -SelfServicePlugin
            Disables general, Authentication Manager and SelfService Plugin logging for Citrix Receiver
    #>

    
    [cmdletbinding()]
    PARAM
    (
        [switch]$General,
        [switch]$AuthenticationManager,
        [switch]$SelfServicePlugin
    )
    
    begin
    {
        If ((-not $General) -and (-not $AuthenticationManager) -and (-not $SelfServicePlugin))
        {
            Throw 'No parameter was given. You can get parameter info with the command Get-Help Enable-CTXReceiverLogging'
        }
        
        $Is64BitOperatingSystem = [environment]::Is64BitOperatingSystem
    }
    
    process
    {
        Try
        {
            If ($General)
            {
                If ($Is64BitOperatingSystem)
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix -RegValue ReceiverVerboseTracingEnabled -RegData 0 -RegType DWord
                }
                Else
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix -RegValue ReceiverVerboseTracingEnabled -RegData 0 -RegType DWord
                }
                Write-Output 'Receiver general logging is disabled. Please reboot your system.'
            }
            
            If ($AuthenticationManager)
            {
                If ($Is64BitOperatingSystem)
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\AuthManager -RegValue LoggingMode -RegData verbose -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\AuthManager -RegValue TracingEnabled -RegData false -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\AuthManager -RegValue SDKTracingEnabled -RegData false -RegType String
                }
                Else
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\AuthManager -RegValue LoggingMode -RegData verbose -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\AuthManager -RegValue TracingEnabled -RegData false -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\AuthManager -RegValue SDKTracingEnabled -RegData false -RegType String
                }
                Write-Output 'Receiver Authentication Manager logging is disabled. Please reboot your system.'
            }
            
            If ($SelfServicePlugin)
            {
                If ($Is64BitOperatingSystem)
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\Dazzle -RegValue Tracing -RegData false -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\Dazzle -RegValue AuxTracing -RegData false -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Wow6432Node\Citrix\Dazzle -RegValue DefaultTracingConfiguration -RegData 'global all –detail' -RegType String
                }
                Else
                {
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\Dazzle -RegValue Tracing -RegData false -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\Dazzle -RegValue AuxTracing -RegData false -RegType String
                    Set-Registry -RegKey HKLM:\SOFTWARE\Citrix\Dazzle -RegValue DefaultTracingConfiguration -RegData 'global all –detail' -RegType String
                }
                Write-Output 'Receiver Self-Service Plugin logging is disabled. Please reboot you system.'
            }
        }
        
        Catch
        {
            Throw $_
        }
    
    }   
}
#endregion

#region Storefront functions
Function Enable-CTXStorefrontLogging
{
    <#
            .SYNOPSIS
            Enables logging for Citrix Storefront.
        
            .DESCRIPTION
            Enables logging for Citrix Storefront.

            .EXAMPLE
            Enable-CTXStorefrontLogging
            Enables Citrix Storefront logging
    #>
    

    begin{}

    process
    {
        Try
        {            
            Add-PSSnapin Citrix.DeliveryServices.Framework.Commands -ErrorAction SilentlyContinue            
            Set-DSTraceLevel �All �TraceLevel Verbose
            Write-Output 'Citrix Storefront logging now enabled'
            Write-Output "Log files are located in 'C:\Program Files\Citrix\Receiver Storefront\Admin\Trace' and can be read with the SvcTraceViewer from the Windows Communication Framework. You have to download that on your own as I am not permitted to host it myself."
            Write-Output 'Or you can read the trace stream with the DebugViewer tool from Technet https://live.sysinternals.com/Dbgview.exe. For instructions have a look here: http://support.citrix.com/article/CTX139592'
            
        }
        Catch
        {
            Throw $_
        }
    }

    end{}

}

Function Disable-CTXStorefrontLogging
{
    <#
            .SYNOPSIS
            Disables logging for Citrix Storefront.
        
            .DESCRIPTION
            Disables logging for Citrix Storefront.

            .EXAMPLE
            Disable-CTXStorefrontLogging
            Disables Citrix Storefront logging
    #>
 

    begin{}

    process
    {
        Try
        {
            
            Add-PSSnapin Citrix.DeliveryServices.Framework.Commands -ErrorAction SilentlyContinue
                       
            Set-DSTraceLevel �All �TraceLevel Off            
            Write-Output 'Citrix Storefront logging now disabled'
            Write-Output "Log files in 'C:\Program Files\Citrix\Receiver Storefront\Admin\Trace' will remain there"
        }
        Catch
        {
            Throw $_
        }
    }

    end{}
}
#endregion

#region export module members
Export-ModuleMember -Function Enable-CTXControllerLogging
Export-ModuleMember -Function Disable-CTXControllerLogging
Export-ModuleMember -Function Enable-CTXVDALogging
Export-ModuleMember -Function Disable-CTXVDALogging
Export-ModuleMember -Function Enable-CTXReceiverLogging
Export-ModuleMember -Function Disable-CTXReceiverLogging
Export-ModuleMember -Function Enable-CTXStorefrontLogging
Export-ModuleMember -Function Disable-CTXStorefrontLogging
#endregion