• Documenting a Citrix XenApp 6 Farm with Microsoft PowerShell

    September 30, 2011

    PowerShell, XenApp, XenApp 6.0

    A customer site I was at recently needed their new XenApp 6 farm documented. I remembered reading about Citrix having some PowerShell “stuff” for XenApp 6 so I started searching. I came across a short article by Michael Bogobowicz Getting a Farm Inventory With XenApp 6 PowerShell Scripting. That short article really piqued my interest. I took Michael’s little script as the starting point to learn Microsoft’s PowerShell. With some help from PowerShell MVP and fellow CTP Brandon Shell and a lot of help from Exchange MVP Michael B. Smith, I turned the original script into over 1600 lines of PowerShell to thoroughly document a XenApp 6 farm.

    NOTE: This script is continually updated.  You can always find the most current version by going to https://carlwebster.com/where-to-get-copies-of-the-documentation-scripts/

    This article will focus only on XenApp 6. There will be additional articles for XenApp 5 and XenApp 6.5.

    The prerequisites to follow along with this article are:

    • A server, physical or virtual, running Microsoft Windows Server 2008 R2 with or without SP1
    • Citrix XenApp 6 installed

    In this article, we will be installing:

    • Citrix XenApp 6 Software Developers Kit (SDK)
    • Citrix Group Policy PowerShell Commands

    My initial goal was to see if I could walk down the nodes in the Delivery Services Console (Figure 1), or AppCenter (the current Citrix terminology), and see if I could document every nook and cranny.

    Figure 1
    Figure 1

    Before we can start using PowerShell to document anything in the XenApp 6 farm we first need to install the SDK and Citrix Group Policy commands. From your XenApp 6 server, go to http://tinyurl.com/XenApp6PSSDK (Figure 2).

    Figure 2
    Figure 2

    Scroll down and click on Download XenApp 6 Powershell SDK — Version 6.1.2 (Figure 3). Do not exit your Internet browser at this time.

    Figure 3
    Figure 3

    Extract the file to C:\XA6SDK. Click Start, Run, type in C:\XA6SDK\XASDK6.0.exe, and press Enter (Figure 4).

    Figure 4
    Figure 4

    Click Run (Figure 5).

    Figure 5
    Figure 5

    Select I accept the terms of this license agreement and click Next (Figure 6).

    Figure 6
    Figure 6

    Select Update the execution policy (to AllSigned) and Click Next (Figure 7).

    Note: If you do not update the execution policy to AllSigned, the Citrix supplied XenApp PowerShell scripts will not load.

    Figure 7
    Figure 7

    Click Install (Figure 8).

    Figure 8
    Figure 8

    After a few seconds, the installation completes. Click Finish (Figure 9).

    Figure 9
    Figure 9

    Back in your Internet browser; go to http://tinyurl.com/XenApp6PSPolicies (Figure 10).

    Figure 10
    Figure 10

    Scroll down and click on Citrix.GroupPolicy.Commands.psm1 (Figure 11).

    Figure 11
    Figure 11

    Save the file in two different places:

    C:\Windows\System32\WindowsPowerShell\v1.0\Modules, in a new folder named Citrix.GroupPolicy.Commands (Figure 12)

    C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules, in a new folder named Citrix.GroupPolicy.Commands (Figure 13)

    Figure 12
    Figure 12
    Figure 13
    Figure 13

    You can now close your Internet browser.

    You now have two new Start Menu items under All Programs, Citrix:

      • Windows PowerShell with Citrix XenApp Server SDK (x86) (Figure 14)
      • Windows PowerShell with Citrix XenApp Server SDK (Figure 15)
    Figure 14
    Figure 14
    Figure 15
    Figure 15

    The one shown in Figure 15 is 64-bit and will be the one we use for this article. Click Start, All Programs, Citrix, XenApp Server SDK, Windows PowerShell with Citrix XenApp Server SDK. You should see the message shown in Figure 16.

    Figure 16
    Figure 16

    This message is asking if you want to trust the PowerShell scripts from Citrix. Type the letter A and press Enter. You will see the Citrix PowerShell scripts and the modules load (Figure 17).

    Figure 17
    Figure 17

    To prepare for processing the Citrix farm policies, type in import-module Citrix.GroupPolicy.Commands, press Enter, type the letter A and press Enter (Figure 18).

    Figure 18
    Figure 18

    Everything is now set up for us to get started. Returning back to Michael Bogobowicz’s script, I didn’t need any of the e-mail stuff so I removed all that, which left the following:

    Note: If it appears the text is truncated on the right, there will be a horizontal scroll bar below the PowerShell code.

    $farm = Get-XAFarm  #Gets the farm information
    $applications = Get-XAApplication  #Gets the published applications
    $servers = Get-XAServer  #Gets the XA servers in the farm
    #Prepares the output
    $output = "Farm: "+$farm.FarmName + "`n"
    $output += "`nServers `n"
    foreach($server in $servers){
    $output+=$server.ServerName + " ("+$server.CitrixEdition+" "+$server.CitrixVersion+")`n"
    }
    $output += "`nApplications `n"
    foreach($application in $applications){
    $output+=$application.DisplayName + " ("+$application.ApplicationType+")`n"
    }
    echo $output
    

    Pasting that into the PowerShell session, gave me what is shown in Figure 19.

    Figure 19
    Figure 19

    Next, I wanted to know all the information I could get. When the Citrix PowerShell module s load, you are shown how to get a list of all the Citrix commands (Figure 20).

    Figure 20
    Figure 20

    Typing Get-CtxCommand into the PowerShell session returns a long list of Citrix PowerShell commands. A sample is shown in Figure 21.

    Figure 21
    Figure 21

    PowerShell commands are done in a Verb-Noun format. Get-Something, New-Something, Copy-Something, etc. I don’t want to change anything in my script, I just want to get, or retrieve, all the farm information possible. So how can I get a list of just the “Get” Citrix PowerShell commands, showing just the name, in alphabetical order? Being a good PowerShell citizen, Citrix puts “XA” or “Ctx” at the beginning of their Get commands.

    To get a list of the Get commands, showing just the Name, where the noun starts with “Ctx”, type the following in the PowerShell session (results are shown in Figure 22):

    Get-Command –Noun Ctx* -Verb Get | Select-Object Name

    Figure 22
    Figure 22

    To get a list of the Get commands, showing just the Name, where the noun starts with “XA”, type the following in the PowerShell session (results are shown in Figure 23):

    Get-Command –Noun XA* -Verb Get | Select-Object Name

    Figure 23
    Figure 23

    Note: I figured out the commands I needed based on an e-mail from Brandon Shell and then typing help get-command –full. Looking at the examples in the help showed me the –Noun and –Verb parameters. My friend Michael B. Smith showed me how to retrieve just the Name column by using Select-Object Name. I did not have to sort the results as help told me that Get-Command returns the results in alphabetical order.

    Looking at Michael’s Bogobowicz’s script, I can see the pieces of information being returned.

    1. The farm name
    2. Each server’s name, product edition, and product version
    3. Each application’s name and application type.

    Typing the commands into the PowerShell session gave me the results shown in Figure 24 and Figure 25.

    Figure 24
    Figure 24
    Figure 25
    Figure 25

    My next question was how do I find out what information each command returns for me to use? That information is contained in the SDK Help file. Click Start, All Programs, Citrix, XenApp Server SDK, Citrix XenApp Server SDK Help (Figure 26).

    Figure 26
    Figure 26

    The Citrix XenApp Commands Reference help opens. Double-click XenApp Commands (Figure 27).

    Figure 27
    Figure 27

    Click on Get-XAServer (Figure 28).

    Figure 28
    Figure 28

    In the right pane, scroll down until you see the Return Type section (Figure 29).

    Figure 29
    Figure 29

    You see where the Return Type is a collection of XAServer objects. In the left pane, double-click XenApp Data Classes (Figure 30).

    Figure 30
    Figure 30

    Click on XAServer (Figure 31).

    Figure 31
    Figure 31

    In the right pane, you will see the information, or properties, returned by running Get-XAServer (Figure 32).

    Figure 32
    Figure 32

    These Properties are the same as what you see back in Figure 24.

    I used the same processes for finding and retrieving the information for all the nodes in the Delivery Services Console (DSC).

    My goal is to use the same wording as what is seen in the DSC for headings, captions, and text. In order to do that, I needed a way to format the output text. At this point in my PowerShell learning, I did not know how to output objects. Michael B. Smith (MBS) developed a function for me to use called Line.

    Function line
    #function created by Michael B. Smith, Exchange MVP
    #@essentialexchange on Twitter
    #http://TheEssentialExchange.com
    {
    Param( [int]$tabs = 0, [string]$name = ’’, [string]$value = ’’, [string]$newline = “`n”, [switch]$nonewline )
    While( $tabs --gt 0 ) { $global:output += “`t”; $tabs--; }
    If( $nonewline )
    {
    $global:output += $name + $value
    }
    Else
    {
    $global:output += $name + $value + $newline
    }
    }
    

    Another lesson MBS taught me is to check to see if each cmdlet used returned an error and how to tell the cmdlet how I wanted to proceed if there was an error. This is done by using –ErrorAction, or –EA. ErrorAction has four values (Table 1):

    Table 1

    Enumeration Value Description
    SilentlyContinue 0 The Windows PowerShell runtime will continue processing without notifying the user that an action has occurred.
    Stop 1 The Windows PowerShell runtime will stop processing when an action occurs.
    Continue 2 The Windows PowerShell runtime will continue processing and notify the user that an action has occurred.
    Inquire 3 The Windows PowerShell runtime will stop processing and ask the user how it should proceed.

    For this documentation script, I always use 0. If an error occurs, I want the rest of the script to continue.

    Next, I needed to know how to test to see if an action, like Get-XAFarm, succeeded, or had an error. MBS said to use $? to test if the most recent action succeeded (True) or had an error (False). For example:

    $farm = Get-XAFarm -EA 0
    If( $? )
    {
    #success
    }
    Else
    {
    #error
    }
    

    There are numerous differences between XenApp 6 and XenApp 5. For example:

    1. Farm settings in XenApp 5 are now policy settings
    2. Server-specific settings in XenApp 5 are now policy settings
    3. XenApp 6 uses Worker Groups
    4. XenApp 6 uses Load Balancing Policies

    Because of these differences, to use PowerShell to document a XenApp farm requires a different script for each XenApp version. This also means each script needs to test to verify it is being run on the correct XenApp version.

    Let’s get started. We will build the script node by node.

    The beginning of the script:

    #Original Script created 8/17/2010 by Michael Bogobowicz, Citrix Systems.
    #To contact, please message @mcbogo on Twitter
    #This script is designed to be run on a XenApp 6 server
    #Modifications by Carl Webster, CTP and independent consultant
    #webster@carlwebster.com
    #@carlwebster on Twitter
    #http://www.CarlWebster.com
    Function line
    #function created by Michael B. Smith, Exchange MVP
    #@essentialexchange on Twitter
    #http://Essential.Exchange/blog
    {
    Param( [int]$tabs = 0, [string]$name = ’’, [string]$value = ’’, [string]$newline = “`n”, [switch]$nonewline )
    While( $tabs --gt 0 ) { $global:output += “`t”; $tabs--; }
    If( $nonewline )
    {
    $global:output += $name + $value
    }
    Else
    {
    $global:output += $name + $value + $newline
    }
    }
    #Script begins
    $global:output = ""
    

    The first node in the DSC is the Farm itself and the first thing we need to check is to verify the script is being run under XenApp 6.

    # Get farm information
    $farm = Get-XAFarm -EA 0
    If( $? )
    {
    #first check to make sure this is a XenApp 6 farm
    If($Farm.ServerVersion.ToString().SubString(0,1) -eq "6")
    {
    #this is a XenApp 6 farm, script can proceed
    }
    Else
    {
    #this is not a XenApp 6 farm, script cannot proceed
    write-warning "This script is designed for XenApp 6 and should not be run on XenApp 5"
    Return 1
    }
    line 0 "Farm: "$farm.FarmName
    }
    Else
    {
    line 0 "Farm information could not be retrieved"
    }
    Write-Output $global:output
    $farm = $null
    $global:output = $null
    

    The next sub-node in Farm Properties is Configuration Logging (Figure 33).

    Figure 33
    Figure 33
    $global:ConfigLog = $False
    $ConfigurationLogging = Get-XAConfigurationLog -EA 0
    If( $? )
    {
    If ($ConfigurationLogging.LoggingEnabled )
    {
    $global:ConfigLog = $True
    line 0 ""
    line 0 "Configuration Logging is enabled."
    line 1 "Allow changes to the farm when logging database is disconnected: " $ConfigurationLogging.ChangesWhileDisconnectedAllowed
    line 1 "Require administrator to enter credentials before clearing the log: " $ConfigurationLogging.CredentialsOnClearLogRequired
    line 1 "Database type: "$ConfigurationLogging.DatabaseType
    line 1 "Authentication mode: "$ConfigurationLogging.AuthenticationMode
    line 1 "Connection string: "$ConfigurationLogging.ConnectionString
    line 1 "User name: "$ConfigurationLogging.UserName
    }
    Else
    {
    line 0 ""
    line 0 "Configuration Logging is disabled."
    }
    }
    Else
    {
    line 0 "Configuration Logging could not be retrieved"
    }
    Write-Output $global:output
    $ConfigurationLogging = $null
    $global:output = $null
    

    Script output:

    Configuration Logging is enabled.
    Changes while disconnected allowed: True
    Credentials on clear log required: True
    Database type: SqlServer
    Authentication mode: Integrated
    Connection string: Server=SQL;Database=XA6ConfigLog;Connection Timeout=20;Packet Size=8192;Encrypt=false;Pooling
    =true;
    Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0;Enlist=true;Connection Reset=true;
    User name: administrator
    

    The Connection string line is ugly and needs to be cleaned up. One thing we can do is to replace each “;” with a New Line character and several Tab characters to line each item up. PowerShell has a built-in replace method we can use.

    $ConfigurationLogging.ConnectionString.replace(“;”,”nttt”)

    New Configuration Logging portion of the script:

    $global:ConfigLog = $False
    $ConfigurationLogging = Get-XAConfigurationLog -EA 0
    
    If( $? )
    {
    	If ($ConfigurationLogging.LoggingEnabled )
    	{
    		$global:ConfigLog = $True
    		line 0 ""
    		line 0 "Configuration Logging is enabled."
    		line 1 "Allow changes to the farm when logging database is disconnected: " $ConfigurationLogging.ChangesWhileDisconnectedAllowed
    		line 1 "Require administrator to enter credentials before clearing the log: " $ConfigurationLogging.CredentialsOnClearLogRequired
    		line 1 "Database type: " $ConfigurationLogging.DatabaseType
    		line 1 "Authentication mode: " $ConfigurationLogging.AuthenticationMode
    		line 1 "Connection string: "
    		$Tmp = "`t`t" + $ConfigurationLogging.ConnectionString.replace(";","`n`t`t`t")
    		line 1 $Tmp -NoNewline
    		line 0 ""
    		line 1 "User name: " $ConfigurationLogging.UserName
    		$Tmp = $null
    	}
    	Else
    	{
    		line 0 ""
    		line 0 "Configuration Logging is disabled."
    	}
    }
    Else
    {
    	line 0 "Configuration Logging could not be retrieved"
    }
    Write-Output $global:output
    $ConfigurationLogging = $null
    $global:output = $null
    

    New script output:

    Configuration Logging is enabled.
    Changes while disconnected allowed: True
    Credentials on clear log required: True
    Database type: SqlServer
    Authentication mode: Integrated
    Connection string:
    Server=SQL
    Database=XA6ConfigLog
    Connection Timeout=20
    Packet Size=8192
    Encrypt=false
    Pooling=true
    Min Pool Size=0
    Max Pool Size=100
    Connection Lifetime=0
    Enlist=true
    Connection Reset=true
    User name: administrator
    

    The next node in the DSC is Administrators. Administrators can have Privileges and Permissions (Figure 34 and Figure 35).

    Figure 34
    Figure 34
    Figure 35
    Figure 35

    The Get-XAAdministrator cmdlet does not return all the information contained in the DSC. I created a custom administrator and set permissions in each of the folders. Only the Servers, Worker Groups, and Application folders were returned. We can only work with the data Citrix returns to us via PowerShell.

    The folder permissions are returned in the same format as the Configuration Logging Connection String and are quite ugly. I am using the PowerShell replace method to clean up the output. I am also sorting the output by the administrator’s name.

    $Administrators = Get-XAAdministrator -EA 0 | sort-object AdministratorName
    
    If( $? )
    {
    	line 0 ""
    	line 0 "Administrators:"
    	ForEach($Administrator in $Administrators)
    	{
    		line 0 ""
    		line 1 "Administrator name: "$Administrator.AdministratorName
    		line 1 "Administrator type: "$Administrator.AdministratorType -nonewline
    		line 0 " Administrator"
    		line 1 "Administrator account is " -NoNewLine
    		If($Administrator.Enabled)
    		{
    			line 0 "Enabled"
    		}
    		Else
    		{
    			line 0 "Disabled"
    		}
    		If ($Administrator.AdministratorType -eq "Custom")
    		{
    			line 1 "Farm Privileges:"
    			ForEach($farmprivilege in $Administrator.FarmPrivileges)
    			{
    				line 2 $farmprivilege
    			}
    
    			line 1 "Folder Privileges:"
    			ForEach($folderprivilege in $Administrator.FolderPrivileges)
    			{
    				$test = $folderprivilege.ToString()
    				$folderlabel = $test.substring(0, $test.IndexOf(":") + 1)
    				line 2 $folderlabel
    				$test1 = $test.substring($test.IndexOf(":") + 1)
    				$folderpermissions = $test1.replace(",","`n`t`t`t")
    				line 3 $folderpermissions
    			}
    		}
    
    	Write-Output $global:output
    	$global:output = $null
    	}
    }
    Else
    {
    	line 0 "Administrator information could not be retrieved"
    	Write-Output $global:output
    }
    
    $Administrators = $null
    $global:outout = $null
    

    Script output:

    Administrators:
    Administrator name: XA6\Administrator
    Administrator type: Full Administrator
    Administrator account is Enabled
    
    Administrator name: XA6\cwebster
    Administrator type: Custom Administrator
    Administrator account is Enabled
    Farm Privileges:
    EditFarmOther
    EditConfigurationLog
    ViewFarm
    LogOnConsole
    ViewAdmins
    AssignLoadEvaluators
    ViewLoadEvaluators
    ViewLoadBalancingPolicies
    ViewPrinterDrivers
    Folder Privileges:
    Servers:
    AssignApplicationsToServers
    ViewSessions
    SendMessages
    LogOffSessions
    DisconnectSessions
    ResetSessions
    ViewServers
    EditOtherServerSettings
    RemoveServer
    WorkerGroups:
    ViewWorkerGroups
    Applications:
    ViewApplications
    EditApplications
    ViewSessions
    SendMessages
    LogOffSessions
    DisconnectSessions
    ResetSessions
    Applications/Graphic Apps:
    ViewApplications
    EditApplications
    ViewSessions
    SendMessages
    LogOffSessions
    DisconnectSessions
    ResetSessions
    
    Administrator name: XA6\Lou
    Administrator type: ViewOnly Administrator
    Administrator account is Enabled
    

    The next node is the applications. Several items that made this node more of a challenge:

    1. Applications can be served by either Worker Groups or Servers
    2. Applications can be hosted on the XenApp server or Streamed
    3. File type associations
    4. Anonymous connections can be allowed

    Because applications can be in folders, I am sorting the output by folder name and then by the application’s display name.

    $Applications = Get-XAApplication -EA 0 | sort-object FolderPath, DisplayName
    
    If( $? -and $Applications)
    {
    	line 0 ""
    	line 0 "Applications:"
    	ForEach($Application in $Applications)
    	{
    		$AppServerInfoResults = $False
    		$AppServerInfo = Get-XAApplicationReport -BrowserName $Application.BrowserName -EA 0
    		If( $? )
    		{
    			$AppServerInfoResults = $True
    		}
    		$streamedapp = $False
    		If($Application.ApplicationType -Contains "streamedtoclient" -or $Application.ApplicationType -Contains "streamedtoserver")
    		{
    			$streamedapp = $True
    		}
    		#name properties
    		line 0 ""
    		line 1 "Display name: " $Application.DisplayName
    		line 2 "Application name (Browser name): " $Application.BrowserName
    		line 2 "Disable application: " -NoNewLine
    		If ($Application.Enabled)
    		{
    		 line 0 "False"
    		}
    		Else
    		{
    		 line 0 "True"
    		}
    		line 2 "Hide disabled application: " $Application.HideWhenDisabled
    		line 2 "Application description: " $Application.Description
    
    		#type properties
    		line 2 "Application Type: " $Application.ApplicationType
    		line 2 "Folder path: " $Application.FolderPath
    		line 2 "Content Address: " $Application.ContentAddress
    
    		#if a streamed app
    		If($streamedapp)
    		{
    			line 2 "Citrix streaming application profile address: " $Application.ProfileLocation
    			line 2 "Application to launch from the Citrix streaming application profile: " $Application.ProfileProgramName
    			line 2 "Extra command line parameters: " $Application.ProfileProgramArguments
    			#if streamed, Offline access properties
    			If($Application.OfflineAccessAllowed)
    			{
    				line 2 "Enable offline access: " $Application.OfflineAccessAllowed
    			}
    			If($Application.CachingOption)
    			{
    				line 2 "Cache preference: " $Application.CachingOption
    			}
    		}
    
    		#location properties
    		If(!$streamedapp)
    		{
    			line 2 "Command line: " $Application.CommandLineExecutable
    			line 2 "Working directory: " $Application.WorkingDirectory
    
    			#servers properties
    			If($AppServerInfoResults)
    			{
    				line 2 "Servers:"
    				ForEach($servername in $AppServerInfo.ServerNames)
    				{
    					line 3 $servername
    				}
    				line 2 "Workergroups:"
    				ForEach($workergroup in $AppServerInfo.WorkerGroupNames)
    				{
    					line 3 $workergroup
    				}
    			}
    			Else
    			{
    				line 3 "Unable to retrieve a list of Servers for this application"
    				line 3 "Unable to retrieve a list of Worker Groups for this application"
    			}
    		}
    
    		#users properties
    		If($Application.AnonymousConnectionsAllowed)
    		{
    			line 2 "Allow anonymous users: " $Application.AnonymousConnectionsAllowed
    		}
    		Else
    		{
    			If($AppServerInfoResults)
    			{
    				line 2 "Users:"
    				ForEach($user in $AppServerInfo.Accounts)
    				{
    					line 3 $user
    				}
    			}
    			Else
    			{
    				line 3 "Unable to retrieve a list of Users for this application"
    			}
    		}
    
    		#shortcut presentation properties
    		#application icon is ignored
    		line 2 "Client application folder: " $Application.ClientFolder
    		If($Application.AddToClientStartMenu)
    		{
    			line 2 "Add to client's start menu: " $Application.AddToClientStartMenu
    		}
    		If($Application.StartMenuFolder)
    		{
    			line 2 "Start menu folder: " $Application.StartMenuFolder
    		}
    		If($Application.AddToClientDesktop)
    		{
    			line 2 "Add shortcut to the client's desktop: " $Application.AddToClientDesktop
    		}
    
    		#access control properties
    		If($Application.ConnectionsThroughAccessGatewayAllowed)
    		{
    			line 2 "Allow connections made through AGAE: " $Application.ConnectionsThroughAccessGatewayAllowed
    		}
    		If($Application.OtherConnectionsAllowed)
    		{
    			line 2 "Any connection: " $Application.OtherConnectionsAllowed
    		}
    		If($Application.AccessSessionConditionsEnabled)
    		{
    			line 2 "Any connection that meets any of the following filters: " $Application.AccessSessionConditionsEnabled
    			line 2 "Access Gateway Filters:"
    			ForEach($filter in $Application.AccessSessionConditions)
    			{
    				line 3 $filter
    			}
    		}
    
    		#content redirection properties
    		If($AppServerInfoResults)
    		{
    			If($AppServerInfo.FileTypes)
    			{
    				line 2 "File type associations:"
    				ForEach($filetype in $AppServerInfo.FileTypes)
    				{
    					line 3 $filetype
    				}
    			}
    			Else
    			{
    				line 2 "No File Type Associations exist for this application"
    			}
    		}
    		Else
    		{
    			line 2 "Unable to retrieve the list of File Type Associations for this application"
    		}
    
    		#if streamed app, Alternate profiles
    		If($streamedapp)
    		{
    			If($Application.AlternateProfiles)
    			{
    				line 2 "Primary application profile location: " $Application.AlternateProfiles
    			}
    
    			#if streamed app, User privileges properties
    			If($Application.RunAsLeastPrivilegedUser)
    			{
    				line 2 "Run application as a least-privileged user account: " $Application.RunAsLeastPrivilegedUser
    			}
    		}
    
    		#limits properties
    		line 2 "Limit instances allowed to run in server farm: " -NoNewLine
    
    		If($Application.InstanceLimit -eq -1)
    		{
    			line 0 "No limit set"
    		}
    		Else
    		{
    			line 0 $Application.InstanceLimit
    		}
    
    		line 2 "Allow only one instance of application for each user: " -NoNewLine
    
    		If ($Application.MultipleInstancesPerUserAllowed)
    		{
    			line 0 "False"
    		}
    		Else
    		{
    			line 0 "True"
    		}
    
    		If($Application.CpuPriorityLevel)
    		{
    			line 2 "Application importance: " $Application.CpuPriorityLevel
    		}
    
    		#client options properties
    		If($Application.AudioRequired)
    		{
    			line 2 "Enable legacy audio: " $Application.AudioRequired
    		}
    		If($Application.AudioType)
    		{
    			line 2 "Minimum requirement: " $Application.AudioType
    		}
    		If($Application.SslConnectionEnable)
    		{
    			line 2 "Enable SSL and TLS protocols: " $Application.SslConnectionEnabled
    		}
    		If($Application.EncryptionLevel)
    		{
    			line 2 "Encryption: " $Application.EncryptionLevel
    		}
    		If($Application.EncryptionRequire)
    		{
    			line 2 "Minimum requirement: " $Application.EncryptionRequired
    		}
    
    		line 2 "Start this application without waiting for printers to be created: " -NoNewLine
    		If ($Application.WaitOnPrinterCreation)
    		{
    			line 0 "False"
    		}
    		Else
    		{
    			line 0 "True"
    		}
    
    		#appearance properties
    		If($Application.WindowType)
    		{
    			line 2 "Session window size: " $Application.WindowType
    		}
    		If($Application.ColorDepth)
    		{
    			line 2 "Maximum color quality: " $Application.ColorDepth
    		}
    		If($Application.TitleBarHidden)
    		{
    			line 2 "Hide application title bar: " $Application.TitleBarHidden
    		}
    		If($Application.MaximizedOnStartup)
    		{
    			line 2 "Maximize application at startup: " $Application.MaximizedOnStartup
    		}
    
    	Write-Output $global:output
    	$global:output = $null
    	$AppServerInfo = $null
    	}
    }
    Else
    {
    	line 0 "Application information could not be retrieved"
    }
    
    $Applications = $null
    $global:output = $null
    

    Script output:

    Applications:
    
    Display name: Notepad
    Application name (Browser name): Notepad
    Disable application: False
    Hide disabled application: False
    Application description: Notepad
    Application Type: ServerInstalled
    Folder path: Applications
    Content Address:
    Command line: c:\windows\system32\notepad.exe
    Working directory:
    Servers:
    Workergroups:
    All XA6 Servers
    Users:
    XA6\Users
    Client application folder:
    Allow connections made through AGAE: True
    Any connection: True
    No File Type Associations exist for this application
    Limit instances allowed to run in server farm: No limit set
    Allow only one instance of application for each user: False
    Application importance: Normal
    Minimum requirement: None
    Encryption: Basic
    Start this application without waiting for printers to be created: True
    Session window size: 1024x768
    Maximum color quality: Colors32Bit
    
    Display name: Paint
    Application name (Browser name): Paint
    Disable application: False
    Hide disabled application: False
    Application description: Paint
    Application Type: ServerInstalled
    Folder path: Applications/Graphic Apps
    Content Address:
    Command line: c:\windows\system32\mspaint.exe "%*"
    Working directory:
    Servers:
    XA6
    Workergroups:
    Users:
    XA6\Users
    Client application folder:
    Allow connections made through AGAE: True
    Any connection: True
    File type associations:
    PAINT.PICTURE
    EMFFILE
    RLEFILE
    WMFFILE
    Limit instances allowed to run in server farm: No limit set
    Allow only one instance of application for each user: False
    Application importance: Normal
    Minimum requirement: None
    Encryption: Basic
    Start this application without waiting for printers to be created: True
    Session window size: 1024x768
    Maximum color quality: Colors32Bit
    

    I didn’t have any streamed applications in my lab but a couple of friends who helped test this script did and the streaming information was displayed.

    Next up is the History node which is actually the Configuration Logging report. This was the second hardest node to figure out because it is so poorly documented by Citrix.

    Note: Begin October 2, 2011 update

    Originally I had this set so that the $ConnectionString parameters would need to be manually set. It wasn’t until I was writing the follow-up article for XenApp 5 that I realized the flaw in my thinking. Since I also provide a signed copy of the script, manually changing the script is impossible. If the signed copy of the script is altered, the script is no longer valid and will not run. The way around this dilemma is to use a UDL file. For an explanation, see http://tinyurl.com/CreateUDLFile.

    The UDL file will need to be placed in the same folder as this script. The UDL file will need to be named XA6ConfigLog.udl. You will need to edit the UDL file and add ;Password=ConfigLogDatabasePassword to the end of the last line in the file. For example, here is mine (the line is one line):

    Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;User ID=administrator;Initial Catalog=XA6ConfigLog;Data Source=SQL;Password=abcd1234

    There are a couple of modifications that need to be made to the script to accommodate this change.

    In the Configuration Logging section, you will need to add one line:

    $global:ConfigLog = $False # ADD THIS LINE
    $ConfigurationLogging = Get-XAConfigurationLog -EA 0
    If( $? )
    {
    If ($ConfigurationLogging.LoggingEnabled)
    {
    $global:ConfigLog = $True #ADD THIS LINE
    line 0 ""
    line 0 "Configuration Logging is enabled."
    <snip>
    
    <strong>Note: End October 2, 2011 update</strong>
    
    
    If( $Global:ConfigLog )
    {
    	#history AKA Configuration Logging report
    	#only process if $Global:ConfigLog = $True and .\XA6ConfigLog.udl file exists
    	#build connection string for Microsoft SQL Server
    	#User ID is account that has access permission for the configuration logging database
    	#Initial Catalog is the name of the Configuration Logging SQL Database
    	If ( Test-Path .\XA6ConfigLog.udl )
    	{
    		$ConnectionString = Get-Content .\xa6configlog.udl | select-object -last 1
    		$ConfigLogReport = get-CtxConfigurationLogReport -connectionstring $ConnectionString -EA 0
    
    		If( $? -and $ConfigLogReport)
    		{
    			line 0 ""
    			line 0 "History:"
    			ForEach($ConfigLogItem in $ConfigLogReport)
    			{
    				line 0 ""
    				Line 1 "Date: " $ConfigLogItem.Date
    				Line 1 "Account: " $ConfigLogItem.Account
    				Line 1 "Change description: " $ConfigLogItem.Description
    				Line 1 "Type of change: " $ConfigLogItem.TaskType
    				Line 1 "Type of item: " $ConfigLogItem.ItemType
    				Line 1 "Name of item: " $ConfigLogItem.ItemName
    			}
    			Write-Output $global:output
    			$global:output = $null
    		}
    		Else
    		{
    			line 0 "History information could not be retrieved"
    		}
    		Write-Output $global:output
    		$ConfigLogReport = $null
    		$global:output = $null
    	}
    	Else
    	{
    		line 0 "XA6ConfigLog.udl file was not found"
    	}
    }

    Script output:

    History:
    
    Date: 08/07/2011 15:38:55
    Account: XA6\Administrator
    Change description: Settings for Configuration Logging were initialized.
    Type of change: Modified
    Type of item: Farm
    Name of item: XA6Farm
    
    Date: 09/28/2011 20:03:00
    Account: XA6\Administrator
    Change description: Published application Notepad was modified.
    Type of change: Modified
    Type of item: Application
    Name of item: Notepad
    
    Date: 09/28/2011 20:03:14
    Account: XA6\Administrator
    Change description: Published application Paint was modified.
    Type of change: Modified
    Type of item: Application
    Name of item: Paint
    
    Date: 09/28/2011 23:41:39
    Account: XA6\Administrator
    Change description: Administrator XA6\cwebster was added.
    Type of change: Created
    Type of item: User
    Name of item: XA6\cwebster
    
    Date: 09/28/2011 23:42:49
    Account: XA6\Administrator
    Change description: Administrator XA6\Lou was added.
    Type of change: Created
    Type of item: User
    Name of item: XA6\Lou
    

    Next up is Load Balancing Policies. This node was a challenge due to all the multiple conditions that can be set.

    #load balancing policies
    $LoadBalancingPolicies = Get-XALoadBalancingPolicy -EA 0 | sort-object PolicyName
    
    If( $? -and $LoadBalancingPolicies)
    {
    	line 0 ""
    	line 0 "Load Balancing Policies:"
    	ForEach($LoadBalancingPolicy in $LoadBalancingPolicies)
    	{
    		$LoadBalancingPolicyConfiguration = Get-XALoadBalancingPolicyConfiguration -PolicyName $LoadBalancingPolicy.PolicyName
    		$LoadBalancingPolicyFilter = Get-XALoadBalancingPolicyFilter -PolicyName $LoadBalancingPolicy.PolicyName
    
    		line 1 "Load balancing policy name: " $LoadBalancingPolicy.PolicyName
    		line 2 "Load balancing policy description: " $LoadBalancingPolicy.Description
    		line 2 "Load balancing policy enabled: " $LoadBalancingPolicy.Enabled
    		line 2 "Load balancing policy priority: " $LoadBalancingPolicy.Priority
    
    		line 2 "Filter based on Access Control: " $LoadBalancingPolicyFilter.AccessControlEnabled
    		If($LoadBalancingPolicyFilter.AccessControlEnabled)
    		{
    			line 2 "Apply to connections made through Access Gateway: " $LoadBalancingPolicyFilter.AllowConnectionsThroughAccessGateway
    			If($LoadBalancingPolicyFilter.AllowConnectionsThroughAccessGateway)
    			{
    				If($LoadBalancingPolicyFilter.AllowOtherConnections)
    				{
    					line 3 "Any connection"
    				}
    				Else
    				{
    					line 3 "Any connection that meets any of the following filters"
    					If($LoadBalancingPolicyFilter.AccessSessionConditions)
    					{
    						ForEach($AccessSessionCondition in $LoadBalancingPolicyFilter.AccessSessionConditions)
    						{
    							line 4 $AccessSessionCondition
    						}
    					}
    				}
    			}
    		}
    
    		If($LoadBalancingPolicyFilter.ClientIPAddressEnabled)
    		{
    			line 2 "Filter based on client IP address"
    			If($LoadBalancingPolicyFilter.ApplyToAllClientIPAddresses)
    			{
    				line 3 "Apply to all client IP addresses: " $LoadBalancingPolicyFilter.ApplyToAllClientIPAddresses
    			}
    			Else
    			{
    				If($LoadBalancingPolicyFilter.AllowedIPAddresses)
    				{
    					ForEach($AllowedIPAddress in $LoadBalancingPolicyFilter.AllowedIPAddresses)
    					{
    						line 3 "Client IP Address Matched: " $AllowedIPAddress
    					}
    				}
    				If($LoadBalancingPolicyFilter.DeniedIPAddresses)
    				{
    					ForEach($DeniedIPAddress in $LoadBalancingPolicyFilter.DeniedIPAddresses)
    					{
    						line 3 "Client IP Address Ignored: " $DeniedIPAddress
    					}
    				}
    			}
    		}
    		If($LoadBalancingPolicyFilter.ClientNameEnabled)
    		{
    			line 2 "Filter based on client name"
    			If($LoadBalancingPolicyFilter.ApplyToAllClientNames)
    			{
    				line 3 "Apply to all client names: " $LoadBalancingPolicyFilter.ApplyToAllClientNames
    			}
    			Else
    			{
    				If($LoadBalancingPolicyFilter.AllowedClientNames)
    				{
    					ForEach($AllowedClientName in $LoadBalancingPolicyFilter.AllowedClientNames)
    					{
    						line 3 "Client Name Matched: " $AllowedClientName
    					}
    				}
    				If($LoadBalancingPolicyFilter.DeniedClientNames)
    				{
    					ForEach($DeniedClientName in $LoadBalancingPolicyFilter.DeniedClientNames)
    					{
    						line 3 "Client Name Ignored: " $DeniedClientName
    					}
    				}
    			}
    		}
    		If($LoadBalancingPolicyFilter.AccountEnabled)
    		{
    			line 2 "Filter based on user"
    			line 3 "Apply to anonymous users: " $LoadBalancingPolicyFilter.ApplyToAnonymousAccounts
    			If($LoadBalancingPolicyFilter.ApplyToAllExplicitAccounts)
    			{
    				line 3 "Apply to all explicit (non-anonymous) users: " $LoadBalancingPolicyFilter.ApplyToAllExplicitAccounts
    			}
    			Else
    			{
    				If($LoadBalancingPolicyFilter.AllowedAccounts)
    				{
    					ForEach($AllowedAccount in $LoadBalancingPolicyFilter.AllowedAccounts)
    					{
    						line 3 "User Matched: " $AllowedAccount
    					}
    				}
    				If($LoadBalancingPolicyFilter.DeniedAccounts)
    				{
    					ForEach($DeniedAccount in $LoadBalancingPolicyFilter.DeniedAccounts)
    					{
    						line 3 "User Ignored: " $DeniedAccount
    					}
    				}
    			}
    		}
    		If($LoadBalancingPolicyConfiguration.WorkerGroupPreferenceAndFailoverState)
    		{
    			line 2 "Configure application connection preference based on worker group"
    			If($LoadBalancingPolicyConfiguration.WorkerGroupPreferences)
    			{
    				ForEach($WorkerGroupPreference in $LoadBalancingPolicyConfiguration.WorkerGroupPreferences)
    				{
    					line 3 "Worker Group: " $WorkerGroupPreference
    				}
    			}
    		}
    		If($LoadBalancingPolicyConfiguration.StreamingDeliveryProtocolState)
    		{
    			line 2 "Set the delivery protocols for applications streamed to client"
    			line 3 $LoadBalancingPolicyConfiguration.StreamingDeliveryOption
    		}
    
    		Write-Output $global:output
    		$global:output = $null
    		$LoadBalancingPolicyConfiguration = $null
    		$LoadBalancingPolicyFilter = $null
    	}
    }
    Else
    {
    	line 0 "Load balancing policy information could not be retrieved"
    }
    $LoadBalancingPolicies = $null
    $global:output = $null
    
    

    Script output:

    Load Balancing Policies:
    Load balancing policy name: Load Balancing Policy for PS Script
    Load balancing policy description: Load Balancing Policy Description for PS Script
    Load balancing policy enabled: True
    Load balancing policy priority: 1
    Filter based on Access Control: False
    Filter based on client IP address
    Client IP Address Matched: 192.168.1.51-192.168.1.51
    Client IP Address Ignored: 192.168.1.8-192.168.1.8
    Filter based on client name
    Client Name Matched: WIN7LAPTOP
    Client Name Ignored: WRITING
    Filter based on user
    Apply to anonymous users: False
    User Matched: XA6\Lou
    User Ignored: XA6\cwebster
    Configure application connection preference based on worker group
    Worker Group: 1=All XA6 Servers
    Set the delivery protocols for applications streamed to client
    ForceServerAccess
    

    Next up, Load Evaluators.

    #load evaluators
    $LoadEvaluators = Get-XALoadEvaluator -EA 0 | sort-object LoadEvaluatorName
    
    If( $? )
    {
    	line 0 ""
    	line 0 "Load Evaluators:"
    	ForEach($LoadEvaluator in $LoadEvaluators)
    	{
    		line 1 "Name: " $LoadEvaluator.LoadEvaluatorName
    		line 2 "Description: " $LoadEvaluator.Description
    
    		If($LoadEvaluator.IsBuiltIn)
    		{
    			line 2 "Built-in Load Evaluator"
    		}
    		Else
    		{
    			line 2 "User created load evaluator"
    		}
    
    		If($LoadEvaluator.ApplicationUserLoadEnabled)
    		{
    			line 2 "Application User Load Settings"
    			line 3 "Report full load when the number of users for this application equals: " $LoadEvaluator.ApplicationUserLoad
    			line 3 "Application: " $LoadEvaluator.ApplicationBrowserName
    		}
    
    		If($LoadEvaluator.ContextSwitchesEnabled)
    		{
    			line 2 "Context Switches Settings"
    			line 3 "Report full load when the number of context switches per second is greater than this value: " $LoadEvaluator.ContextSwitches[1]
    			line 3 "Report no load when the number of context switches per second is less than or equal to this value: " $LoadEvaluator.ContextSwitches[0]
    		}
    
    		If($LoadEvaluator.CpuUtilizationEnabled)
    		{
    			line 2 "CPU Utilization Settings"
    			line 3 "Report full load when the processor utilization percentage is greater than this value: " $LoadEvaluator.CpuUtilization[1]
    			line 3 "Report no load when the processor utilization percentage is less than or equal to this value: " $LoadEvaluator.CpuUtilization[0]
    		}
    
    		If($LoadEvaluator.DiskDataIOEnabled)
    		{
    			line 2 "Disk Data I/O Settings"
    			line 3 "Report full load when the total disk I/O in kilobytes per second is greater than this value: " $LoadEvaluator.DiskDataIO[1]
    			line 3 "Report no load when the total disk I/O in kilobytes per second is less than or equal to this value: " $LoadEvaluator.DiskDataIO[0]
    		}
    
    		If($LoadEvaluator.DiskOperationsEnabled)
    		{
    			line 2 "Disk Operations Settings"
    			line 3 "Report full load when the total number of read and write operations per second is greater than this value: " $LoadEvaluator.DiskOperations[1]
    			line 3 "Report no load when the total number of read and write operations per second is less than or equal to this value: " $LoadEvaluator.DiskOperations[0]
    		}
    
    		If($LoadEvaluator.IPRangesEnabled)
    		{
    			line 2 "IP Range Settings"
    			If($LoadEvaluator.IPRangesAllowed)
    			{
    				line 3 "Allow " -NoNewLine
    			}
    			Else
    			{
    				line 3 "Deny " -NoNewLine
    			}
    			line 0 "client connections from the listed IP Ranges"
    			ForEach($IPRange in $LoadEvaluator.IPRanges)
    			{
    				line 4 "IP Address Ranges: " $IPRange
    			}
    		}
    
    		If($LoadEvaluator.LoadThrottlingENabled)
    		{
    			line 2 "Load Throttling Settings"
    			line 3 "Impact of logons on load: " $LoadEvaluator.LoadThrottling
    
    		}
    
    		If($LoadEvaluator.MemoryUsageEnabled)
    		{
    			line 2 "Memory Usage Settings"
    			line 3 "Report full load when the memory usage is greater than this value: " $LoadEvaluator.MemoryUsage[1]
    			line 3 "Report no load when the memory usage is less than or equal to this value: " $LoadEvaluator.MemoryUsage[0]
    		}
    
    		If($LoadEvaluator.PageFaultsEnabled)
    		{
    			line 2 "Page Faults Settings"
    			line 3 "Report full load when the number of page faults per second is greater than this value: " $LoadEvaluator.PageFaults[1]
    			line 3 "Report no load when the number of page faults per second is less than or equal to this value: " $LoadEvaluator.PageFaults[0]
    		}
    
    		If($LoadEvaluator.PageSwapsEnabled)
    		{
    			line 2 "Page Swaps Settings"
    			line 3 "Report full load when the number of page swaps per second is greater than this value: " $LoadEvaluator.PageSwaps[1]
    			line 3 "Report no load when the number of page swaps per second is less than or equal to this value: " $LoadEvaluator.PageSwaps[0]
    		}
    
    		If($LoadEvaluator.ScheduleEnabled)
    		{
    			line 2 "Scheduling Settings"
    			line 3 "Sunday Schedule  : " $LoadEvaluator.SundaySchedule
    			line 3 "Monday Schedule  : " $LoadEvaluator.MondaySchedule
    			line 3 "Tuesday Schedule : " $LoadEvaluator.TuesdaySchedule
    			line 3 "Wednesday Schedule: " $LoadEvaluator.WednesdaySchedule
    			line 3 "Thursday Schedule : " $LoadEvaluator.ThursdaySchedule
    			line 3 "Friday Schedule  : " $LoadEvaluator.FridaySchedule
    			line 3 "Saturday Schedule : " $LoadEvaluator.SaturdaySchedule
    		}
    
    		If($LoadEvaluator.ServerUserLoadEnabled)
    		{
    			line 2 "Server User Load Settings"
    			line 3 "Report full load when the number of server users equals: " $LoadEvaluator.ServerUserLoad
    		}
    
    		line 0 ""
    		Write-Output $global:output
    		$global:output = $null
    	}
    }
    Else
    {
    	line 0 "Load Evaluator information could not be retrieved"
    }
    $LoadEvaluators = $null
    $global:output = $null
    

    Script output:

    Load Evaluators:
    
    Name: Advanced
    Description: Use the Advanced Load Evaluator to limit memory usage, CPU utilization, and page swaps on a server for load management.
    Built-in Load Evaluator
    CPU Utilization Settings
    Report full load when the processor utilization percentage is greater than this value: 90
    Report no load when the processor utilization percentage is less than or equal to this value: 10
    Load Throttling Settings
    Impact of logons on load: High
    Memory Usage Settings
    Report full load when the memory usage is greater than this value: 90
    Report no load when the memory usage is less than or equal to this value: 10
    Page Swaps Settings
    Report full load when the number of page swaps per second is greater than this value: 100
    Report no load when the number of page swaps per second is less than or equal to this value: 0
    
    Name: Default
    Description: The Default Load Evaluator uses the user session count for its criteria.
    Built-in Load Evaluator
    Load Throttling Settings
    Impact of logons on load: High
    Server User Load Settings
    Report full load when the number of server users equals: 100
    
    Name: Webster
    Description: Load Evaluator with every option set
    User created load evaluator
    Application User Load Settings
    Report full load when the number of users for this application equals: 100
    Application: Notepad
    Context Switches Settings
    Report full load when the number of context switches per second is greater than this value: 16000
    Report no load when the number of context switches per second is less than or equal to this value: 900
    CPU Utilization Settings
    Report full load when the processor utilization percentage is greater than this value: 90
    Report no load when the processor utilization percentage is less than or equal to this value: 10
    Disk Data I/O Settings
    Report full load when the total disk I/O in kilobytes per second is greater than this value: 32767
    Report no load when the total disk I/O in kilobytes per second is less than or equal to this value: 0
    Disk Operations Settings
    Report full load when the total number of read and write operations per second is greater than this value: 100
    Report no load when the total number of read and write operations per second is less than or equal to this value: 0
    IP Range Settings
    Allow client connections from the listed IP Ranges
    IP Address Ranges: 192.168.1.1-192.168.1.254
    Load Throttling Settings
    Impact of logons on load: High
    Memory Usage Settings
    Report full load when the memory usage is greater than this value: 90
    Report no load when the memory usage is less than or equal to this value: 10
    Page Faults Settings
    Report full load when the number of page faults per second is greater than this value: 2000
    Report no load when the number of page faults per second is less than or equal to this value: 0
    Page Swaps Settings
    Report full load when the number of page swaps per second is greater than this value: 100
    Report no load when the number of page swaps per second is less than or equal to this value: 0
    Scheduling Settings
    Sunday Schedule  :
    Monday Schedule  : 08:00-18:00
    Tuesday Schedule : 08:00-18:00
    Wednesday Schedule: 08:00-18:00
    Thursday Schedule : 08:00-18:00
    Friday Schedule  : 08:00-18:00
    Saturday Schedule :
    Server User Load Settings
    Report full load when the number of server users equals: 100
    

    Even though Policies are next in the DSC, I will save that for last because of the sheer number of policy settings. So the next node we will do is Servers.

    #servers
    $servers = Get-XAServer -EA 0 | sort-object FolderPath, ServerName
    
    If( $? )
    {
    	line 0 ""
    	line 0 "Servers:"
    	ForEach($server in $servers)
    	{
    		line 1 "Name: " $server.ServerName
    		line 2 "Product: " $server.CitrixProductName -NoNewLine
    		line 0 ", " $server.CitrixEdition -NoNewLine
    		line 0 " Edition"
    		line 2 "Version: " $server.CitrixVersion
    		line 2 "Service Pack: " $server.CitrixServicePack
    		line 2 "Operating System Type: " -NoNewLine
    		If($server.Is64Bit)
    		{
    			line 0 "64 bit"
    		}
    		Else
    		{
    			line 0 "32 bit"
    		}
    		line 2 "TCP Address: " $server.IPAddresses
    		line 2 "Logon: " -NoNewLine
    		If($server.LogOnsEnabled)
    		{
    			line 0 "Enabled"
    		}
    		Else
    		{
    			line 0 "Disabled"
    		}
    		line 2 "Product Installation Date: " $server.CitrixInstallDate
    		line 2 "Operating System Version: " $server.OSVersion -NoNewLine
    		line 0 " " $server.OSServicePack
    		line 2 "Zone: " $server.ZoneName
    		line 2 "Election Preference: " $server.ElectionPreference
    		line 2 "Folder: " $server.FolderPath
    		line 2 "Product Installation Path: " $server.CitrixInstallPath
    		If($server.LicenseServerName)
    		{
    			line 2 "License Server Name: " $server.LicenseServerName
    			line 2 "License Server Port: " $server.LicenseServerPortNumber
    		}
    		If($server.ICAPortNumber -gt 0)
    		{
    			line 2 "ICA Port Number: " $server.ICAPortNumber
    		}
    		If($server.RDPPortNumber -gt 0)
    		{
    			line 2 "RDP Port Number: " $server.RDPPortNumber
    		}
    		#applications published to server
    		$Applications = Get-XAApplication -ServerName $server.ServerName -EA 0 | sort-object FolderPath, DisplayName
    		If( $? -and $Applications )
    		{
    			line 2 "Published applications:"
    			ForEach($app in $Applications)
    			{
    				line 0 ""
    				line 3 "Display name: " $app.DisplayName
    				line 3 "Folder path: " $app.FolderPath
    			}
    		}
    		#Citrix hotfixes installed
    		$hotfixes = Get-XAServerHotfix -ServerName $server.ServerName -EA 0 | sort-object HotfixName
    		If( $? -and $hotfixes )
    		{
    			line 0 ""
    			line 2 "Citrix Hotfixes:"
    			ForEach($hotfix in $hotfixes)
    			{
    				line 0 ""
    				line 3 "Hotfix: " $hotfix.HotfixName
    				line 3 "Installed by: " $hotfix.InstalledBy
    				line 3 "Installed date: " $hotfix.InstalledOn
    				line 3 "Hotfix type: " $hotfix.HotfixType
    				line 3 "Valid: " $hotfix.Valid
    				line 3 "Hotfixes replaced: "
    				ForEach($Replaced in $hotfix.HotfixesReplaced)
    				{
    					line 4 $Replaced
    				}
    			}
    		}
    		line 0 ""
    		Write-Output $global:output
    		$global:output = $null
    	}
    }
    Else
    {
    	line 0 "Server information could not be retrieved"
    }
    $servers = $null
    $global:output = $null
    

    Script output:

    Servers:
    
    Name: XA6
    Product: Citrix Presentation Server, Platinum Edition
    Version: 6.0.6410
    Service Pack: 0
    Operating System Type: 64 bit
    TCP Address: 192.168.1.151
    Logon: Enabled
    Product Installation Date: 08/07/2011 17:38:43
    Operating System Version: 6.1.7601 Service Pack 1
    Zone: Default Zone
    Election Preference: MostPreferred
    Folder: Servers
    Product Installation Path: C:\Program Files (x86)\Citrix\
    License Server Name: XA6
    License Server Port: 27000
    ICA Port Number: 1494
    Published applications:
    Display name: Paint
    Folder path: Applications/Graphic Apps
    Citrix Hotfixes:
    Hotfix: XA600W2K8R2X64012
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:31:03
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    
    Hotfix: XA600W2K8R2X64017
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:20:08
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    
    Hotfix: XA600W2K8R2X64018
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:31:59
    Hotfix type: Hotfix
    Valid: False
    Hotfixes replaced:
    XA600W2K8R2X64003
    
    Hotfix: XA600W2K8R2X64021
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:32:34
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    
    Hotfix: XA600W2K8R2X64026
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:33:09
    Hotfix type: Hotfix
    Valid: False
    Hotfixes replaced:
    XA600W2K8R2X64001
    XA600W2K8R2X64011
    XA600W2K8R2X64016
    XA600W2K8R2X64025
    
    Hotfix: XA600W2K8R2X64029
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:21:45
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    
    Hotfix: XA600W2K8R2X64046
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:33:42
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    XA600W2K8R2X64003
    XA600W2K8R2X64018
    
    Hotfix: XA600W2K8R2X64058
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:23:27
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    XA600W2K8R2X64036
    
    Hotfix: XA600W2K8R2X64060
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:34:19
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    XA600W2K8R2X64002
    
    Hotfix: XA600W2K8R2X64062
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:28:33
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    
    Hotfix: XA600W2K8R2X64063
    Installed by: XA6\Administrator
    Installed date: 08/13/2011 18:34:57
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    
    Hotfix: XA600W2K8R2X64068
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:30:15
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    XA600W2K8R2X64019
    XA600W2K8R2X64028
    XA600W2K8R2X64043
    XA600W2K8R2X64045
    XA600W2K8R2X64047
    XA600W2K8R2X64056
    XA600W2K8R2X64061
    
    Hotfix: XA600W2K8R2X64077
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:33:20
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    XA600W2K8R2X64001
    XA600W2K8R2X64011
    XA600W2K8R2X64013
    XA600W2K8R2X64016
    XA600W2K8R2X64025
    XA600W2K8R2X64026
    XA600W2K8R2X64030
    XA600W2K8R2X64040
    XA600W2K8R2X64048
    
    Hotfix: XA600W2K8R2X64079
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:34:14
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    XA600W2K8R2X64010
    XA600W2K8R2X64034
    XA600W2K8R2X64057
    
    Hotfix: XA600W2K8R2X64089
    Installed by: XA6\Administrator
    Installed date: 09/28/2011 19:35:17
    Hotfix type: Hotfix
    Valid: True
    Hotfixes replaced:
    

    Next up is Worker Groups.

    #worker groups
    $WorkerGroups = Get-XAWorkerGroup -EA 0 | sort-object WorkerGroupName
    
    If( $? -and $WorkerGroups)
    {
    	line 0 ""
    	line 0 "Worker Groups:"
    	ForEach($WorkerGroup in $WorkerGroups)
    	{
    		line 0 ""
    		line 1 "Name: " $WorkerGroup.WorkerGroupName
    		line 2 "Description: " $WorkerGroup.Description
    		line 2 "Folder Path: " $WorkerGroup.FolderPath
    		If($WorkerGroup.ServerNames)
    		{
    			line 2 "Farm Servers:"
    			$TempArray = $WorkerGroup.ServerNames | Sort-Object
    			ForEach($ServerName in $TempArray)
    			{
    				line 3 $ServerName
    			}
    			$TempArray = $null
    		}
    		If($WorkerGroup.ServerGroups)
    		{
    			line 2 "Server Group Accounts:"
    			$TempArray = $WorkerGroup.ServerGroups | Sort-Object
    			ForEach($ServerGroup in $TempArray)
    			{
    				line 3 $ServerGroup
    			}
    			$TempArray = $null
    		}
    		If($WorkerGroup.OUs)
    		{
    			line 2 "Organization Units:"
    			$TempArray = $WorkerGroup.OUs | Sort-Object
    			ForEach($OU in $TempArray)
    			{
    				line 3 $OU
    			}
    			$TempArray = $null
    		}
    		#applications published to worker group
    		$Applications = Get-XAApplication -WorkerGroup $WorkerGroup.WorkerGroupName -EA 0 | sort-object FolderPath, DisplayName
    		If( $? -and $Applications )
    		{
    			line 2 "Published applications:"
    			ForEach($app in $Applications)
    			{
    				line 0 ""
    				line 3 "Display name: " $app.DisplayName
    				line 3 "Folder path: " $app.FolderPath
    			}
    		}
    
    		Write-Output $global:output
    		$global:output = $null
    	}
    }
    Else
    {
    	line 0 "Worker Group information could not be retrieved"
    }
    $WorkerGroups = $null
    $global:output = $null
    

    Script output:

    Worker Groups:
    Name: All XA6 Servers
    Description: All XenApp 6 Servers
    Folder Path: WorkerGroups
    Farm Servers:
    XA6
    Published applications:
    Display name: Notepad
    Folder path: Applications
    

    Next up, Zones.

    #zones
    $Zones = Get-XAZone -EA 0 | sort-object ZoneName
    If( $? )
    {
    	line 0 ""
    	line 0 "Zones:"
    	ForEach($Zone in $Zones)
    	{
    		line 1 "Zone Name: " $Zone.ZoneName
    		line 2 "Current Data Collector: " $Zone.DataCollector
    		$Servers = Get-XAServer -ZoneName $Zone.ZoneName -EA 0 | sort-object ElectionPreference, ServerName
    		If( $? )
    		{
    			line 2 "Servers in Zone"
    
    			ForEach($Server in $Servers)
    			{
    				line 3 "Server Name and Preference: " $server.ServerName -NoNewLine
    				line 0 " " $server.ElectionPreference
    			}
    		}
    		Else
    		{
    			line 2 "Unable to enumerate servers in the zone"
    		}
    		Write-Output $global:output
    		$global:output = $null
    		$Servers = $Null
    	}
    }
    Else
    {
    	line 0 "Zone information could not be retrieved"
    }
    $Servers = $null
    $Zones = $null
    $global:output = $null
    

    Script output:

    Zones:
    Zone Name: DEFAULT ZONE
    Current Data Collector: XA6
    Servers in Zone
    Server Name and Preference: XA6 MostPreferred
    

    WHEW! Now for the bad boy! Policies. This was very hard to do. Not only was there an incredible amount of typing involved but not all policy settings are available and just trying to figure some of this stuff out was pretty darn hard. All I can figure out how to retrieve are the IMA based farm policies. Sorry.

    Echo "Please wait while Citrix Policies are retrieved..."
    $Policies = Get-CtxGroupPolicy -EA 0 | sort-object PolicyName
    If( $? )
    {
    	line 0 ""
    	line 0 "Policies:"
    	ForEach($Policy in $Policies)
    	{
    		line 1 "Policy Name: " $Policy.PolicyName
    		line 2 "Type: " $Policy.Type
    		line 2 "Description: " $Policy.Description
    		line 2 "Enabled: " $Policy.Enabled
    		line 2 "Priority: " $Policy.Priority
    
    		$filter = Get-CtxGroupPolicyFilter -PolicyName $Policy.PolicyName -EA 0
    
    		If( $? )
    		{
    			If($Filter -and $filter.FilterName -and ($filter.FilterName.Trim() -ne ""))
    			{
    				Line 2 "Filter name: " $filter.FilterName
    				Line 2 "Filter type: " $filter.FilterType
    				Line 2 "Filter enabled: " $filter.Enabled
    				Line 2 "Filter mode: " $filter.Mode
    				Line 2 "Filter value: " $filter.FilterValue
    
    			}
    			Else
    			{
    				line 2 "No filter information"
    			}
    		}
    		Else
    		{
    			Line 2 "Unable to retrieve Filter settings"
    		}
    
    		$Settings = Get-CtxGroupPolicyConfiguration -PolicyName $Policy.PolicyName -EA 0
    		If( $? )
    		{
    			ForEach($Setting in $Settings)
    			{
    				If($Setting.Type -eq "Computer")
    				{
    					line 2 "Computer settings:"
    					If($Setting.IcaListenerTimeout.State -ne "NotConfigured")
    					{
    						line 3 "ICA\ICA listener connection timeout - Value: " $Setting.IcaListenerTimeout.Value
    					}
    					If($Setting.IcaListenerPortNumber.State -ne "NotConfigured")
    					{
    						line 3 "ICA\ICA listener port number - Value: " $Setting.IcaListenerPortNumber.Value
    					}
    					If($Setting.AutoClientReconnect.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Auto Client Reconnect\Auto client reconnect - Value: " $Setting.AutoClientReconnect.State
    					}
    					If($Setting.AutoClientReconnectAuthenticationRequired.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Auto Client Reconnect\Auto client reconnect authorization - Value: " $Setting.AutoClientReconnectAuthenticationRequired.Value
    					}
    					If($Setting.AutoClientReconnectLogging.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Auto Client Reconnect\Auto client reconnect logging - Value: " $Setting.AutoClientReconnectLogging.Value
    					}
    					If($Setting.IcaRoundTripCalculation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\End User Monitoring\ICA round trip calculation - Value: " $Setting.IcaRoundTripCalculation.State
    					}
    					If($Setting.IcaRoundTripCalculationInterval.State -ne "NotConfigured")
    					{
    						line 3 "ICA\End User Monitoring\ICA round trip calculation interval (Seconds) - Value: " $Setting.IcaRoundTripCalculationInterval.Value
    					}
    					If($Setting.IcaRoundTripCalculationWhenIdle.State -ne "NotConfigured")
    					{
    						line 3 "ICA\End User Monitoring\ICA round trip calculations for idle connections - Value: " $Setting.IcaRoundTripCalculationWhenIdle.State
    					}
    					If($Setting.DisplayMemoryLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Display memory limit: " $Setting.DisplayMemoryLimit.Value
    					}
    					If($Setting.DisplayDegradePreference.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Display mode degrade preference: " $Setting.DisplayDegradePreference.Value
    					}
    					If($Setting.ImageCaching.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Image caching - Value: " $Setting.ImageCaching.State
    					}
    					If($Setting.MaximumColorDepth.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Maximum allowed color depth: " $Setting.MaximumColorDepth.Value
    					}
    					If($Setting.DisplayDegradeUserNotification.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Notify user when display mode is degraded - Value: " $Setting.DisplayDegradeUserNotification.State
    					}
    					If($Setting.QueueingAndTossing.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Queueing and tossing - Value: " $Setting.QueueingAndTossing.State
    					}
    					If($Setting.IcaKeepAliveTimeout.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Keep ALive\ICA keep alive timeout - Value: " $Setting.IcaKeepAliveTimeout.Value
    					}
    					If($Setting.IcaKeepAlives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Keep ALive\ICA keep alives - Value: " $Setting.IcaKeepAlives.Value
    					}
    					If($Setting.MultimediaAcceleration.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream Multimedia Acceleration - Value: " $Setting.MultimediaAcceleration.State
    					}
    					If($Setting.MultimediaAccelerationDefaultBufferSize.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream Multimedia Acceleration default buffer size - Value: " $Setting.MultimediaAccelerationDefaultBufferSize.Value
    					}
    					If($Setting.MultimediaAccelerationUseDefaultBufferSize.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream Multimedia Acceleration default buffer size use - Value: " $Setting.MultimediaAccelerationUseDefaultBufferSize.State
    					}
    					If($Setting.MultimediaConferencing.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\Multimedia conferencing - Value: " $Setting.MultimediaConferencing.State
    					}
    					If($Setting.PromptForPassword.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Security\Prompt for password - Value: " $Setting.PromptForPassword.State
    					}
    					If($Setting.IdleTimerInterval.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Server Limits\Server idle timer interval - Value: " $Setting.IdleTimerInterval.Value
    					}
    					If($Setting.SessionReliabilityConnections.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Reliability\Session reliability connections - Value: " $Setting.SessionReliabilityConnections.State
    					}
    					If($Setting.SessionReliabilityPort.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Reliability\Session reliability port number - Value: " $Setting.SessionReliabilityPort.Value
    					}
    					If($Setting.SessionReliabilityTimeout.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Reliability\Session reliability timeout - Value: " $Setting.SessionReliabilityTimeout.Value
    					}
    					If($Setting.Shadowing.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Shadowing\Shadowing - Value: " $Setting.Shadowing.State
    					}
    					If($Setting.LicenseServerHostName.State -ne "NotConfigured")
    					{
    						line 3 "Licensing\License server host name: " $Setting.LicenseServerHostName.Value
    					}
    					If($Setting.LicenseServerPort.State -ne "NotConfigured")
    					{
    						line 3 "Licensing\License server port: " $Setting.LicenseServerPort.Value
    					}
    					If($Setting.ConnectionAccessControl.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Connection access control - Value: " $Setting.ConnectionAccessControl.Value
    					}
    					If($Setting.DnsAddressResolution.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\DNS address resolution - Value: " $Setting.DnsAddressResolution.State
    					}
    					If($Setting.FullIconCaching.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Full icon caching - Value: " $Setting.FullIconCaching.State
    					}
    					If($Setting.ProductEdition.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\XenApp product edition - Value: " $Setting.ProductEdition.Value
    					}
    					If($Setting.UserSessionLimit.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Connection Limits\Limit user sessions - Value: " $Setting.UserSessionLimit.Value
    					}
    					If($Setting.UserSessionLimitAffectsAdministrators.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Connection Limits\Limits on administrator sessions - Value: " $Setting.UserSessionLimitAffectsAdministrators.State
    					}
    					If($Setting.UserSessionLimitLogging.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Connection Limits\Logging of logon limit events - Value: " $Setting.UserSessionLimitLogging.State
    					}
    					If($Setting.HealthMonitoring.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Health Monitoring and Recovery\Health monitoring - Value: " $Setting.HealthMonitoring.State
    					}
    					If($Setting.HealthMonitoringTests.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Health Monitoring and Recovery\Health monitoring tests - Value: " $Setting.HealthMonitoringTests.Value
    					}
    					If($Setting.MaximumServersOfflinePercent.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Health Monitoring and Recovery\Maximum percent of offline servers - Value: " $Setting.MaximumServersOfflinePercent.Value
    					}
    					If($Setting.CpuManagementServerLevel.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\CPU management server level - Value: " $Setting.CpuManagementServerLevel.Value
    					}
    					If($Setting.MemoryOptimization.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\Memory optimization - Value: " $Setting.MemoryOptimization.State
    					}
    					If($Setting.MemoryOptimizationExcludedPrograms.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\Memory optimization exclusion list - Value: " $Setting.MemoryOptimizationExcludedPrograms.Value
    					}
    					If($Setting.MemoryOptimizationIntervalType.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\Memory optimization interval - Value: " $Setting.MemoryOptimizationIntervalType.Value
    					}
    					If($Setting.MemoryOptimizationDayOfMonth.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\Memory optimization schedule: day of month - Value: " $Setting.MemoryOptimizationDayOfMonth.Value
    					}
    					If($Setting.MemoryOptimizationDayOfWeek.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\Memory optimization schedule: day of week - Value: " $Setting.MemoryOptimizationDayOfWeek.Value
    					}
    					If($Setting.MemoryOptimizationTime.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Memory/CPU\Memory optimization schedule: time - Value: " $Setting.MemoryOptimizationTime.Value
    					}
    					If($Setting.OfflineClientTrust.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Offline Applications\Offline app client trust - Value: " $Setting.OfflineClientTrust.State
    					}
    					If($Setting.OfflineEventLogging.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Offline Applications\Offline app event logging - Value: " $Setting.OfflineEventLogging.State
    					}
    					If($Setting.OfflineLicensePeriod.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Offline Applications\Offline app license period - Value: " $Setting.OfflineLicensePeriod.Value
    					}
    					If($Setting.OfflineUsers.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Offline Applications\Offline app users - Value: " $Setting.OfflineUsers.Value
    					}
    					If($Setting.RebootCustomMessage.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot custom warning - Value: " $Setting.RebootCustomMessage.State
    					}
    					If($Setting.RebootCustomMessageText.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot custom warning text - Value: " $Setting.RebootCustomMessageText.Value
    					}
    					If($Setting.RebootDisableLogOnTime.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot logon disable time - Value: " $Setting.RebootDisableLogOnTime.Value
    					}
    					If($Setting.RebootScheduleFrequency.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot schedule frequency - Value: " $Setting.RebootScheduleFrequency.Value
    					}
    					If($Setting.RebootScheduleStartDate.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot schedule start date - Value: " $Setting.RebootScheduleStartDate.Value
    					}
    					If($Setting.RebootScheduleTime.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot schedule time - Value: " $Setting.RebootScheduleTime.Value
    					}
    					If($Setting.RebootWarningInterval.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot warning interval - Value: " $Setting.RebootWarningInterval.Value
    					}
    					If($Setting.RebootWarningStartTime.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot warning start time - Value: " $Setting.RebootWarningStartTime.Value
    					}
    					If($Setting.RebootWarningMessage.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Reboot warning to users - Value: " $Setting.RebootWarningMessage.State
    					}
    					If($Setting.ScheduledReboots.State -ne "NotConfigured")
    					{
    						line 3 "Server Settings\Reboot Behavior\Scheduled reboots - Value: " $Setting.ScheduledReboots.State
    					}
    					If($Setting.FilterAdapterAddresses.State -ne "NotConfigured")
    					{
    						line 3 "Virtual IP\Virtual IP adapter address filtering - Value: " $Setting.FilterAdapterAddresses.State
    					}
    					If($Setting.EnhancedCompatibilityPrograms.State -ne "NotConfigured")
    					{
    						line 3 "Virtual IP\Virtual IP compatibility programs list - Value: " $Setting.EnhancedCompatibilityPrograms.Value
    					}
    					If($Setting.EnhancedCompatibility.State -ne "NotConfigured")
    					{
    						line 3 "Virtual IP\Virtual IP enhanced compatibility - Value: " $Setting.EnhancedCompatibility.State
    					}
    					If($Setting.FilterAdapterAddressesPrograms.State -ne "NotConfigured")
    					{
    						line 3 "Virtual IP\Virtual IP filter adapter addresses programs list - Value: " $Setting.FilterAdapterAddressesPrograms.Value
    					}
    					If($Setting.VirtualLoopbackSupport.State -ne "NotConfigured")
    					{
    						line 3 "Virtual IP\Virtual IP loopback support - Value: " $Setting.VirtualLoopbackSupport.State
    					}
    					If($Setting.VirtualLoopbackPrograms.State -ne "NotConfigured")
    					{
    						line 3 "Virtual IP\Virtual IP virtual loopback programs list - Value: " $Setting.VirtualLoopbackPrograms.Value
    					}
    					If($Setting.TrustXmlRequests.State -ne "NotConfigured")
    					{
    						line 3 "XML Service\Trust XML requests - Value: " $Setting.TrustXmlRequests.State
    					}
    					If($Setting.XmlServicePort.State -ne "NotConfigured")
    					{
    						line 3 "XML Service\XML service port - Value: " $Setting.XmlServicePort.Value
    					}
    				}
    				Else
    				{
    					line 2 "User settings:"
    					If($Setting.ClipboardRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Client clipboard redirection - Value: " $Setting.ClipboardRedirection.State
    					}
    					If($Setting.DesktopLaunchForNonAdmins.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Desktop launches - Value: " $Setting.DesktopLaunchForNonAdmins.State
    					}
    					If($Setting.NonPublishedProgramLaunching.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Launching of non-published programs during client connection - Value: " $Setting.NonPublishedProgramLaunching.State
    					}
    					If($Setting.OemChannels.State -ne "NotConfigured")
    					{
    						line 3 "ICA\OEM Channels - Value: " $Setting.OemChannels.State
    					}
    					If($Setting.AudioQuality.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Audio\Audio quality - Value: " $Setting.AudioQuality.Value
    					}
    					If($Setting.ClientAudioRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Audio\Client audio redirection - Value: " $Setting.ClientAudioRedirection.State
    					}
    					If($Setting.MicrophoneRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Audio\Client microphone redirection - Value: " $Setting.MicrophoneRedirection.State
    					}
    					If($Setting.AudioBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Audio redirection bandwidth limit - Value: " $Setting.AudioBandwidthLimit.Value
    					}
    					If($Setting.AudioBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Audio redirection bandwidth limit percent - Value: " $Setting.AudioBandwidthPercent.Value
    					}
    					If($Setting.ClipboardBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Clipboard redirection bandwidth limit - Value: " $Setting.ClipboardBandwidthLimit.Value
    					}
    					If($Setting.ClipboardBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Clipboard redirection bandwidth limit percent - Value: " $Setting.ClipboardBandwidthPercent.Value
    					}
    					If($Setting.ComPortBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\COM port redirection bandwidth limit - Value: " $Setting.ComPortBandwidthLimit.Value
    					}
    					If($Setting.ComPortBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\COM port redirection bandwidth limit percent - Value: " $Setting.ComPortBandwidthPercent.Value
    					}
    					If($Setting.FileRedirectionBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\File redirection bandwidth limit - Value: " $Setting.FileRedirectionBandwidthLimit.Value
    					}
    					If($Setting.FileRedirectionBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\File redirection bandwidth limit percent - Value: " $Setting.FileRedirectionBandwidthPercent.Value
    					}
    					If($Setting.LptBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\LPT port redirection bandwidth limit - Value: " $Setting.LptBandwidthLimit.Value
    					}
    					If($Setting.LptBandwidthLimitPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\LPT port redirection bandwidth limit percent - Value: " $Setting.LptBandwidthLimitPercent.Value
    					}
    					If($Setting.OemChannelBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\OEM channels bandwidth limit - Value: " $Setting.OemChannelBandwidthLimit.Value
    					}
    					If($Setting.OemChannelBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\OEM channels bandwidth limit percent - Value: " $Setting.OemChannelBandwidthPercent.Value
    					}
    					If($Setting.OverallBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Overall session bandwidth limit - Value: " $Setting.OverallBandwidthLimit.Value
    					}
    					If($Setting.PrinterBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Printer redirection bandwidth limit - Value: " $Setting.PrinterBandwidthLimit.Value
    					}
    					If($Setting.PrinterBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\Printer redirection bandwidth limit percent - Value: " $Setting.PrinterBandwidthPercent.Value
    					}
    					If($Setting.TwainBandwidthLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\TWAIN device redirection bandwidth limit - Value: " $Setting.TwainBandwidthLimit.Value
    					}
    					If($Setting.TwainBandwidthPercent.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Bandwidth\TWAIN device redirection bandwidth limit percent - Value: " $Setting.TwainBandwidthPercent.Value
    					}
    					If($Setting.DesktopWallpaper.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Desktop UI\Desktop wallpaper - Value: " $Setting.DesktopWallpaper.State
    					}
    					If($Setting.MenuAnimation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Desktop UI\Menu animation - Value: " $Setting.MenuAnimation.State
    					}
    					If($Setting.WindowContentsVisibleWhileDragging.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Desktop UI\View window contents while dragging - Value: " $Setting.WindowContentsVisibleWhileDragging.State
    					}
    					If($Setting.AutoConnectDrives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Auto connect client drives - Value: " $Setting.AutoConnectDrives.State
    					}
    					If($Setting.ClientDriveRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Client drive redirection - Value: " $Setting.ClientDriveRedirection.State
    					}
    					If($Setting.ClientFixedDrives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Client fixed drives - Value: " $Setting.ClientFixedDrives.State
    					}
    					If($Setting.ClientFloppyDrives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Client floppy drives - Value: " $Setting.ClientFloppyDrives.State
    					}
    					If($Setting.ClientNetworkDrives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Client network drives - Value: " $Setting.ClientNetworkDrives.State
    					}
    					If($Setting.ClientOpticalDrives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Client optical drives - Value: " $Setting.ClientOpticalDrives.State
    					}
    					If($Setting.ClientRemoveableDrives.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Client removable drives - Value: " $Setting.ClientRemoveableDrives.State
    					}
    					If($Setting.HostToClientRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Host to client redirection - Value: " $Setting.HostToClientRedirection.State
    					}
    					If($Setting.ClientDriveLetterPreservation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Preserve client drive letters - Value: " $Setting.ClientDriveLetterPreservation.State
    					}
    					If($Setting.SpecialFolderRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Special folder redirection - Value: " $Setting.SpecialFolderRedirection.State
    					}
    					If($Setting.AsynchronousWrites.State -ne "NotConfigured")
    					{
    						line 3 "ICA\File Redirection\Use asynchronous writes - Value: " $Setting.AsynchronousWrites.State
    					}
    					If($Setting.LossyCompressionLevel.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Image compression\Lossy compression level - Value: " $Setting.LossyCompressionLevel.Value
    					}
    					If($Setting.LossyCompressionThreshold.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Image compression\Lossy compression threshold value - Value: " $Setting.LossyCompressionThreshold.Value
    					}
    					If($Setting.ProgressiveCompressionLevel.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Image compression\Progressive compression level - Value: " $Setting.ProgressiveCompressionLevel.Value
    					}
    					If($Setting.ProgressiveCompressionThreshold.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Image compression\Progressive compression threshold value - Value: " $Setting.ProgressiveCompressionThreshold.Value
    					}
    					If($Setting.ProgressiveHeavyweightCompression.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Graphics\Image compression\Progressive heavyweight compression - Value: " $Setting.ProgressiveHeavyweightCompression.State
    					}
    					If($Setting.FlashAcceleration.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream for Flash (client side)\Flash acceleration - Value: " $Setting.FlashAcceleration.State
    					}
    					If($Setting.FlashEventLogging.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream for Flash (client side)\Flash event logging - Value: " $Setting.FlashEventLogging.State
    					}
    					If($Setting.FlashLatencyThreshold.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream for Flash (client side)\Flash latency threshold - Value: " $Setting.FlashLatencyThreshold.Value
    					}
    					If($Setting.FlashServerSideContentFetchingWhitelist.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream for Flash (client side)\Flash server-side content fetching whitelist - Value: " $Setting.FlashServerSideContentFetchingWhitelist.Value
    					}
    					If($Setting.FlashUrlBlacklist.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream for Flash (client side)\Flash URL blacklist - Value: " $Setting.FlashUrlBlacklist.Value
    					}
    					If($Setting.AllowSpeedFlash.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Multimedia\HDX MediaStream for Flash (server side)\Flash quality adjustment - Value: " $Setting.AllowSpeedFlash.Value
    					}
    					If($Setting.ClientComPortsAutoConnection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Ports\Auto connect client COM ports - Value: " $Setting.ClientComPortsAutoConnection.State
    					}
    					If($Setting.ClientLptPortsAutoConnection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Ports\Auto connect client LPT ports - Value: " $Setting.ClientLptPortsAutoConnection.State
    					}
    					If($Setting.ClientComPortRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Ports\Client COM port redirection - Value: " $Setting.ClientComPortRedirection.State
    					}
    					If($Setting.ClientLptPortRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Ports\Client LPT port redirection - Value: " $Setting.ClientLptPortRedirection.State
    					}
    					If($Setting.ClientPrinterRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Client Printers\Client printer redirection - Value: " $Setting.ClientPrinterRedirection.State
    					}
    					If($Setting.DefaultClientPrinter.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Default printer - Value: " $Setting.DefaultClientPrinter.Value
    					}
    					If($Setting.AutoCreationEventLogPreference.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Printer auto-creation event log preference - Value: " $Setting.AutoCreationEventLogPreference.Value
    					}
    					If($Setting.SessionPrinters.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Session printers - Value: " $Setting.SessionPrinters.State
    					}
    					If($Setting.WaitForPrintersToBeCreated.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Wait for printers to be created (desktop) - Value: " $Setting.WaitForPrintersToBeCreated.State
    					}
    					If($Setting.ClientPrinterAutoCreation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Client Printers\Auto-create client printers - Value: " $Setting.ClientPrinterAutoCreation.Value
    					}
    					If($Setting.ClientPrinterNames.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Client Printers\Client printer names - Value: " $Setting.ClientPrinterNames.Value
    					}
    					If($Setting.DirectConnectionsToPrintServers.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Client Printers\Direct connections to print servers - Value: " $Setting.DirectConnectionsToPrintServers.State
    					}
    					If($Setting.PrinterPropertiesRetention.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Client Printers\Printer properties retention - Value: " $Setting.PrinterPropertiesRetention.Value
    					}
    					If($Setting.RetainedAndRestoredClientPrinters.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Client Printers\Retained and restored client printers - Value: " $Setting.RetainedAndRestoredClientPrinters.State
    					}
    					If($Setting.InboxDriverAutoInstallation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Drivers\Automatic installation of in-box printer drivers - Value: " $Setting.InboxDriverAutoInstallation.State
    					}
    					If($Setting.PrinterDriverMappings.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Drivers\Printer driver mapping and compatibility - Value: " $Setting.PrinterDriverMappings.State
    					}
    					If($Setting.GenericUniversalPrinterAutoCreation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Universal Printing\Auto-create generic universal printer - Value: " $Setting.GenericUniversalPrinterAutoCreation.State
    					}
    					If($Setting.UniversalDriverPriority.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Universal Printing\Universal driver priority - Value: " $Setting.UniversalDriverPriority.Value
    					}
    					If($Setting.UniversalPrinting.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Universal Printing\Universal printing - Value: " $Setting.UniversalPrinting.Value
    					}
    					If($Setting.UniversalPrintingPreviewPreference.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Printing\Universal Printing\Universal printing preview preference - Value: " $Setting.UniversalPrintingPreviewPreference.Value
    					}
    					If($Setting.MinimumEncryptionLevel.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Security\SecureICA minimum encryption level - Value: " $Setting.MinimumEncryptionLevel.Value
    					}
    					If($Setting.ConcurrentLogOnLimit.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session limits\Concurrent logon limit - Value: " $Setting.ConcurrentLogOnLimit.Value
    					}
    					If($Setting.SessionDisconnectTimer.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Limits\Disconnected session timer - Value: " $Setting.SessionDisconnectTimer.State
    					}
    					If($Setting.SessionDisconnectTimerInterval.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Limits\Disconnected session timer interval - Value: " $Setting.SessionDisconnectTimerInterval.Value
    					}
    					If($Setting.SessionConnectionTimer.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Limits\Session connection timer - Value: " $Setting.SessionConnectionTimer.State
    					}
    					If($Setting.SessionConnectionTimerInterval.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Limits\Session connection timer interval - Value: " $Setting.SessionConnectionTimerInterval.Value
    					}
    					If($Setting.SessionIdleTimer.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Limits\Session idle timer - Value: " $Setting.SessionIdleTimer.State
    					}
    					If($Setting.SessionIdleTimerInterval.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Session Limits\Session idle timer interval - Value: " $Setting.SessionIdleTimerInterval.Value
    					}
    					If($Setting.ShadowInput.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Shadowing\Input from shadow connections - Value: " $Setting.ShadowInput.State
    					}
    					If($Setting.ShadowLogging.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Shadowing\Log shadow attempts - Value: " $Setting.ShadowLogging.State
    					}
    					If($Setting.ShadowUserNotification.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Shadowing\Notify user of pending shadow connections - Value: " $Setting.ShadowUserNotification.State
    					}
    					If($Setting.ShadowAllowList.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Shadowing\Users who can shadow other users - Value: " $Setting.ShadowAllowList.Value
    					}
    					If($Setting.ShadowDenyList.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Shadowing\Users who cannot shadow other users - Value: " $Setting.ShadowDenyList.Value
    					}
    					If($Setting.LocalTimeEstimation.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Time Zone Control\Local Time Estimation - Value: " $Setting.LocalTimeEstimation.State
    					}
    					If($Setting.SessionTimeZone.State -ne "NotConfigured")
    					{
    						line 3 "ICA\Time Zone Control\Use local time of client - Value: " $Setting.SessionTimeZone.Value
    					}
    					If($Setting.TwainRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\TWAIN devices\Client TWAIN device redirection - Value: " $Setting.TwainRedirection.State
    					}
    					If($Setting.TwainCompressionLevel.State -ne "NotConfigured")
    					{
    						line 3 "ICA\TWAIN devices\TWAIN compression level - Value: " $Setting.TwainCompressionLevel.Value
    					}
    					If($Setting.UsbDeviceRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\USB devices\Client USB device redirection - Value: " $Setting.UsbDeviceRedirection.State
    					}
    					If($Setting.UsbDeviceRedirectionRules.State -ne "NotConfigured")
    					{
    						line 3 "ICA\USB devices\Client USB device redirection rules - Value: " $Setting.UsbDeviceRedirectionRules.Value
    					}
    					If($Setting.UsbPlugAndPlayRedirection.State -ne "NotConfigured")
    					{
    						line 3 "ICA\USB devices\Client USB Plug and Play device redirection - Value: " $Setting.UsbPlugAndPlayRedirection.State
    					}
    					If($Setting.SessionImportance.State -ne "NotConfigured")
    					{
    						line 3 "Server Session Settings\Session importance - Value: " $Setting.SessionImportance.Value
    					}
    					If($Setting.SingleSignOn.State -ne "NotConfigured")
    					{
    						line 3 "Server Session Settings\Single Sign-On - Value: " $Setting.SingleSignOn.State
    					}
    					If($Setting.SingleSignOnCentralStore.State -ne "NotConfigured")
    					{
    						line 3 "Server Session Settings\Single Sign-On central store - Value: " $Setting.SingleSignOnCentralStore.Value
    					}
    				}
    			}
    		}
    		Else
    		{
    			line 2 "Unable to retrieve settings"
    		}
    
    		Write-Output $global:output
    		$global:output = $null
    		$Filter = $null
    		$Settings = $null
    	}
    }
    Else
    {
    	line 0 "Citrix Policy information could not be retrieved. Was the Citrix.GroupPolicy.Command module imported?"
    }
    $Policies = $null
    $global:output = $null
    

    Script output:

    Policies:
    
    Policy Name: Unfiltered
    Type: User
    Description:
    Enabled: True
    Priority: 1
    No filter information
    Computer settings:
    Licensing\License server host name: XA6
    User settings:
    
    Policy Name: Unfiltered
    Type: Computer
    Description: Unfiltered computer policy
    Enabled: True
    Priority: 1
    No filter information
    Computer settings:
    Licensing\License server host name: XA6
    User settings:
    

    How to use this script?

    I saved the script as XA6_Inventory.ps1 in the C:\PSScripts folder. From the PowerShell prompt, change to the C:\PSScripts folder, or the folder where you saved the script. From the PowerShell prompt, type in:

    .\XA6_Inventory.ps1 | out-file .\XA6Farm.txt and press Enter.

    Open XA6Farm.txt in either WordPad or Microsoft Word (Figure 36).

    Figure 36
    Figure 36

    The first update I have planned for this script is to implement generating the output in Word format. This will allow for using Word Headings and formatting. If you have any suggestions for the script, please let me know. Send an e-mail to webster@carlwebster.com.

    NOTE: This script is continually updated.  You can always find the most current version by going to https://carlwebster.com/where-to-get-copies-of-the-documentation-scripts/

    ,





    About Carl Webster

    Webster is a Sr. Solutions Architect for Choice Solutions, LLC and specializes in Citrix, Active Directory and Technical Documentation. Webster has been working with Citrix products for many years starting with Multi-User OS/2 in 1990.

    View all posts by Carl Webster

    14 Responses to “Documenting a Citrix XenApp 6 Farm with Microsoft PowerShell”

    1. Rohit Says:

      Hi Carl,
      Do you have some script for multiple Citrix farm report (Multiple DC and Farms)
      If XenApp5 and XenApp6 can be included would be great.

      Many Thanks
      Rohit

      Reply

    2. Ismael Says:

      Carl, i am having an issue running the application part of the script. here is an example of part of the script (like you need that) and then after is the error im getting… Any assistance would be greatly appreciated….

      $Applications = Get-XAApplication -EA 0 | sort-object FolderPath, DisplayName

      If( $? -and $Applications)
      {
      line 0 “”
      line 0 “Applications:”
      ForEach($Application in $Applications)
      {
      $AppServerInfoResults = $False
      $AppServerInfo = Get-XAApplicationReport -BrowserName $Application.BrowserName -EA 0
      If( $? )
      {
      $AppServerInfoResults = $True
      }
      $streamedapp = $False
      If($Application.ApplicationType -Contains “streamedtoclient” -or $Application.ApplicationType -Contains “streamedtoserver”)
      {

      ERROR:
      The term ‘line’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelli
      ng of the name, or if a path was included, verify that the path is correct and try again.
      At I:\PowerShell\Citrix\Scripts\XenAppApplications.ps1:5 char:9
      + line <<<< 0 ""
      + CategoryInfo : ObjectNotFound: (line:String) [], CommandNotFoundException

      Reply

      • Carl Webster Says:

        WOW, that is an extremely old version of the script. Why are you not using the most current version?

        https://carlwebster.com/where-to-get-copies-of-the-documentation-scripts/

        This function should be at the top of your script file.

        Function line
        #function created by Michael B. Smith, Exchange MVP
        #@essentialexchange on Twitter
        #http://TheEssentialExchange.com
        {
        Param( [int]$tabs = 0, [string]$name = ’’, [string]$value = ’’, [string]$newline = “`n”, [switch]$nonewline )

        While( $tabs –gt 0 ) { $global:output += “`t”; $tabs–; }

        If( $nonewline )
        {
        $global:output += $name + $value
        }
        Else
        {
        $global:output += $name + $value + $newline
        }
        }

        Webster

        Reply

    3. Felton Lewis Says:

      Carl –

      Really great work! Thank you so much for this. I’m new to PowerShell so just the baby steps of going through this has been very helpful. I do have a question. I ran your XA6_Inventory_V4_Signed.ps1 script against one of my farms an it reported that a HFX was missing – (XA600R02W2K8R2X64015 Not Installed). So I installed the HFX and re-ran the script but the Word doc still shows that the HFX was not installed even though my DSC shows that it is. Am I missing something?

      Reply

      • Carl Webster Says:

        Ahhh, thanks for finding this bug. I believe I have it fixed and have sent you a script to test and verify.

        Thanks

        Webster

        Reply

    4. Craig Says:

      Hey Carl. This is seriously handy – im loving your work and i am learning so much from your scripting.

      thanks a bunch

      Reply

    5. Chaitanyakumar G Says:

      Hi Carl, I know you on internet in twitter, this site etc… this documentation is really very useful thanks a lot for posting it..

      Chaitanya.

      Reply

    6. Ismael Says:

      Hi Carl,

      I have been learning so much from your notes.

      How can I print this one? I would like to read it on the train…

      Thanks, Ismael

      Reply

    7. Sreekanth Says:

      WOW!!! Carl!!!

      Your scripts are amazing, keep up the great work!!!

      And by the by is there anyway we can only export the “ACTIVE” settings of XenApp6.5 each Policies to XL sheet or HTML?

      Once again its really great article, keep writing..!!!

      regards,
      Sreekanth

      Reply

      • Carl Webster Says:

        Sreekanth,

        Thanks for the kind words.

        I do think there is a simple change you can make to the Get-CtxGroupPolicy funcrion in the Citrix provided psm1 file.

        Take this section:

        foreach ($pol in $pols)
        {
        $props = CreateDictionary
        $props.PolicyName = $pol.Name
        $props.Type = $poltype
        $props.Description = $pol.Description
        $props.Enabled = $pol.Enabled
        $props.Priority = $pol.Priority
        CreateObject $props $pol.Name
        }

        and change it to this:

        foreach ($pol in $pols)
        {
        If($pol.Enabled)
        {
        $props = CreateDictionary
        $props.PolicyName = $pol.Name
        $props.Type = $poltype
        $props.Description = $pol.Description
        $props.Enabled = $pol.Enabled
        $props.Priority = $pol.Priority
        CreateObject $props $pol.Name
        }
        }

        I believe that will do what you are asking for.

        Thanks

        Webster

        Reply

    8. Tom K. Says:

      Wow. I worked alongside the article for the first pages and was having success in my own environment as I tried to duplicate the sample pieces of posh code. A good way to learn, but then I looked ahead and upon seeing the sheer amount of code-yet-to-come I jumped to the last page and was relieved to see it had been all put together and made available for donwload.

      Not being a coder or developer by nature or proefession I am always looking for examples I can emulate and hopefully learn from,but in this case I was going to be happy if I could download some or all of this and just have it handy. I can’t tell you though how amazed I was when the entire final script with all of those components contained within ran the first time I tried it in my environment on a XA6 server with the SDK installed. It’s never that easy, at least never has been before when I’ve copied other’s scripts. This is a testament to Mr. Webster’s attention to detail and thoroughness. Thanks man.

      Reply

    Leave a Reply