-
Documenting a Citrix XenApp 6 Farm with Microsoft PowerShell
September 30, 2011
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 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 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 Extract the file to C:\XA6SDK. Click Start, Run, type in C:\XA6SDK\XASDK6.0.exe, and press Enter (Figure 4).
Figure 4 Click Run (Figure 5).
Figure 5 Select I accept the terms of this license agreement and click Next (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 Click Install (Figure 8).
Figure 8 After a few seconds, the installation completes. Click Finish (Figure 9).
Figure 9 Back in your Internet browser; go to http://tinyurl.com/XenApp6PSPolicies (Figure 10).
Figure 10 Scroll down and click on Citrix.GroupPolicy.Commands.psm1 (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 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 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 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 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 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 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 Typing Get-CtxCommand into the PowerShell session returns a long list of Citrix PowerShell commands. A sample is shown in 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 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 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.
- The farm name
- Each server’s name, product edition, and product version
- 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 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 The Citrix XenApp Commands Reference help opens. Double-click XenApp Commands (Figure 27).
Figure 27 Click on Get-XAServer (Figure 28).
Figure 28 In the right pane, scroll down until you see the Return Type section (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 Click on XAServer (Figure 31).
Figure 31 In the right pane, you will see the information, or properties, returned by running Get-XAServer (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:
- Farm settings in XenApp 5 are now policy settings
- Server-specific settings in XenApp 5 are now policy settings
- XenApp 6 uses Worker Groups
- 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 $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(“;”,”
n
tt
t”)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 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:
- Applications can be served by either Worker Groups or Servers
- Applications can be hosted on the XenApp server or Streamed
- File type associations
- 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 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/
14 Responses to “Documenting a Citrix XenApp 6 Farm with Microsoft PowerShell”
Leave a Reply
October 11, 2016 at 9:19 am
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
October 14, 2016 at 8:33 am
Sorry, I don’t.
Webster
June 12, 2014 at 8:33 am
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
June 12, 2014 at 8:37 am
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
November 5, 2013 at 2:15 pm
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?
November 7, 2013 at 5:08 am
Ahhh, thanks for finding this bug. I believe I have it fixed and have sent you a script to test and verify.
Thanks
Webster
August 25, 2013 at 6:25 pm
Hey Carl. This is seriously handy – im loving your work and i am learning so much from your scripting.
thanks a bunch
March 29, 2013 at 4:51 am
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.
May 11, 2012 at 5:41 am
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
May 11, 2012 at 7:40 am
Go here:
https://carlwebster.com/where-to-get-copies-of-the-xenapp-farm-documentation-scripts/
and print what you need.
Webster
April 11, 2012 at 2:44 am
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
April 12, 2012 at 7:15 pm
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
November 10, 2011 at 3:21 pm
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.
November 10, 2011 at 3:23 pm
Thank you for the very kind words.
Webster