• Documenting a Citrix XenApp 6.5 Farm with Microsoft PowerShell – Version 2

    January 21, 2013

    PowerShell, XenApp, XenApp 6.5

    The original article on Documenting a Citrix XenApp 6.5 Farm with Microsoft PowerShell was released on October 7, 2011.  The original script has been downloaded over 16,000 times. I decided it was time to update the script to have the output match what was shown in AppCenter.   With a lot of help (and patience) from Exchange MVP and PowerShell guru Michael B. Smith, I updated the original script from over 1800 lines to over 2900 lines of PowerShell to thoroughly document a XenApp 6.5 farm.  This article will focus on the changes to the script.
    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/
    I would like to thank the following people for helping to test the script.

    • @BYODre
    • Andrew Morgan
    • Bart Jacobs
    • Brian Hecker
    • Derick
    • Jarian Gibson
    • J. L. Straat
    • Jennifer Auiler
    • Kees Baggerman
    • Knut Gunnar Neggen
    • Magnus Hjorleifsson
    • Mark Fermin
    • Ryan Revord
    • Thomas Poppelgaard
    • And 24 others

    Before we get started, I want you to know that I am NOT a programmer. I am NOT a software developer and I am NOT a real PowerShell coder. I am simply a hack who brute forces his way through all this PowerShell stuff until I either figure it out myself or have to use a lifeline. i.e. Michael B. Smith, Jeff Wouter or worse, I have to read a book!

    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.5 installed with or without HRP01

    Note: A few testers reported that neither this script nor AppCenter displayed the hotfixes installed on the data collectors. Citrix has a public hotfix that should resolve that specific issue. http://support.citrix.com/article/CTX132713

    The nice thing about XenApp 6.5 compared to both XenApp 5 and XenApp 6 is that all the basic Citrix PowerShell stuff is installed when you install XenApp 6.5.  But we still need the XenApp 6.5 PowerShell Help and the Citrix Group Policy PowerShell Commands.  You can read the original article for instructions on how to download and install those components.

    My goal is to use the same wording as what is seen in the AppCenter for headings, captions and text.  This required a lot of extra coding and learning some new things in PowerShell.  In the original script, there were some Citrix policy settings where I thought Citrix stored no data.  Turns out that I didn’t know how to retrieve the data.  My friend MBS had to teach me what I didn’t understand originally.  There were still some objects where the properties contained no data.  For example, for the XAServer object, the property ServerFqdn has never returned any data for any of the servers I tested it on.  For properties like ServerFqdn, I have chosen to remove them from the script so they don’t clutter up the output.

    Andrew Morgan added a Function to the script to make sure the three required PowerShell snap-ins are loaded.

    Function Check-NeededPSSnapins
        Param( [parameter(Mandatory = $true)][alias("Snapin")][string[]]$Snapins)
        #function specifics
        #Creates arrays of strings, rather than objects, we're passing strings so this will be more robust.
        $loadedSnapins += get-pssnapin | % {$_.name}
        $registeredSnapins += get-pssnapin -Registered | % {$_.name}
        foreach ($Snapin in $Snapins){
            #check if the snapin is loaded
            if (!($LoadedSnapins -like $snapin)){
                #Check if the snapin is missing
                if (!($RegisteredSnapins -like $Snapin)){
                    #set the flag if it's not already
                    if (!($FoundMissingSnapin)){
                        $FoundMissingSnapin = $True
                    #add the entry to the list
                    $MissingSnapins += $Snapin
                }#End Registered If
                    #Snapin is registered, but not loaded, loading it now:
                    Write-Host "Loading Windows PowerShell snap-in: $snapin"
                    Add-PSSnapin -Name $snapin
            }#End Loaded If
            #Snapin is registered and loaded
            else{write-debug "Windows PowerShell snap-in: $snapin - Already Loaded"}
        }#End For
        if ($FoundMissingSnapin){
            write-warning "Missing Windows PowerShell snap-ins Detected:"
            $missingSnapins | % {write-warning "($_)"}
            return $False
        }#End If
            Return $true
        }#End Else
    }#End Function

    At the beginning of the script, we check for the required snap-ins.

    if (!(Check-NeededPSSnapins "Citrix.Common.Commands","Citrix.Common.GroupPolicy","Citrix.XenApp.Commands")){
        #We're missing Citrix Snapins that we need
        write-error "Missing Citrix PowerShell Snap-ins Detected, check the console above for more information. Are you sure you are running this script on a XenApp 6.5 Server? Script will now close."

    If the snap-ins do not exist because the script is not being run on a XenApp 6.5 server, we get the following.

    WARNING: Missing Windows PowerShell snap-ins Detected:
    WARNING: (Citrix.Common.Commands)
    WARNING: (Citrix.Common.GroupPolicy)
    WARNING: (Citrix.XenApp.Commands)
    E:\test.ps1 : Missing Citrix PowerShell Snap-ins Detected, check the console above for more information. Are you sure y
    ou are running this script on a XenApp 6.5 Server? Script will now close.
    At line:1 char:11
    + .\test.ps1 <<<<
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1

    If the snap-ins are not loaded in the current PowerShell session, they are loaded.

    Loading Windows PowerShell snap-in: Citrix.Common.Commands
    Loading Windows PowerShell snap-in: Citrix.Common.GroupPolicy
    Loading Windows PowerShell snap-in: Citrix.XenApp.Commands

    The original script would just stop working if the Citrix.GroupPolicy.Commands module was not loaded into the current PowerShell session before the script was run. Jeff Wouters supplied a function to make sure the Citrix.GroupPolicy.Commands module was loaded. Michael B. Smith modified the function so it worked if the module is not installed on the server. And Andrew Morgan suggested an improvement to MBS’ update to make it even better.

    Function Check-LoadedModule
    #function created by Jeff Wouters
    #@JeffWouters on Twitter
    #modified by Michael B. Smith to handle when the module doesn't exist on server
    #modified by @andyjmorgan
    #bug fixed by @schose
    #This function handles all three scenarios:
    # 1. Module is already imported into current session
    # 2. Module is not already imported into current session, it does exists on the server and is imported
    # 3. Module does not exist on the server
    	Param( [parameter(Mandatory = $true)][alias("Module")][string]$ModuleName)
    	#$LoadedModules = Get-Module | Select Name
    	#following line changed at the recommendation of @andyjmorgan
    	$LoadedModules = Get-Module |% { $_.Name.ToString() }
    	#bug reported on 21-JAN-2013 by @schose
    	#the following line did not work if the citrix.grouppolicy.commands.psm1 module
    	#was manually loaded from a non default folder
    	#$ModuleFound = (!$LoadedModules -like "*$ModuleName*")
    	$ModuleFound = ($LoadedModules -like "*$ModuleName*")
    	if (!$ModuleFound)
    		$module = Import-Module -Name $ModuleName –PassThru –EA 0
    		If( $module –and $? )
    			# module imported properly
    			Return $True
    			# module import failed
    			Return $False
    		#module already imported into current session
    		Return $true

    If the Citrix.GroupPolicy.Commands module is already loaded into the current session, the script continues. If the Citrix.GroupPolicy.Commands module is not loaded into the current session and the module exists on the server, the module is loaded and the script continues. If the Citrix.GroupPolicy.Commands module does not exist on the server, the script will issue a warning and ends gracefully. Citrix farm policy processing is the last thing the script does.

    WARNING: The Citrix Group Policy module Citrix.GroupPolicy.Commands.psm1 does not exist
    (http://support.citrix.com/article/CTX128625), Citrix Policy documentation will not take place.

    There were no changes made to the Farm or Configuration Logging sections.

    , ,

    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

    No comments yet.

    Leave a Reply