Citrix_farm.ps1 - non power-manged machine catalogs

While trying to implement the citrix_farm.ps1 plugin for Citrix Delivery Controllers, I noticed it reported the correct data for the controllers, but absolutely none for the registered machines.

This is because the original plugin uses the property HostedMachineName for the cmdlet Get-BrokerSession to query the available machines.

This isn’t ideal, since this property only describes the name used by the hypervisor. To quote the Citrix docs: “The friendly name of a hosted machine running the session, as used by its hypervisor. This does not necessarily match either the DNS or AD name of the machine.” If you have a Citrix environment that is not connected to a hypervisor (aka your machine catalogs are not power-managed), this property will always be empty - therefore, the plugin will not find any registered machines.

To fix this, I replaced every instance of the property HostedMachineName with DNSName and added a line to cut off the domain part at the end (the same trick is used with the controller name).

The changed parts of the script then look like this:

$XASessions = Get-BrokerSession -Property DNSName,Sessionstate -MaxrecordCount $maxusers | Group-Object DNSName, Sessionstate | Sort-Object Name | select-object Name,Count
$XAmachines = Get-BrokerMachine  -MaxRecordCount $maxmachines
$Controllers = Get-BrokerController

foreach ($Controller in $Controllers) {
 --- unchanged ---
}

	foreach ($XAmachine in $XAmachines) {

		# Column Name of Machine / Gets machines with the specific machine name known to the hypervisor.
		$DNSName = $XAmachine | %{ $_.DNSName }
		if([string]::IsNullOrEmpty($DNSName)) {
			continue;
		}
        $DNSName = $DNSName.Replace($DNSdomain,$null)
		"<<<<$DNSName>>>>"
		"<<<citrix_state>>>"
		# Column CatalogNameName / Gets machines from the catalog with the specific name.
		$CatalogName = $XAmachine | %{ $_.CatalogName }
		"Catalog $CatalogName"

		# Column Controller / Gets machines with a specific DNS name of the controller they are registered with.
		$Controller = $XAmachine | %{ $_.ControllerDNSName }
		"Controller $Controller"

		# Column DesktopGroupName / Gets machines from a desktop group with the specified name.
		$DesktopGroupName = $XAmachine | %{ $_.DesktopGroupName }
		"DesktopGroupName $DesktopGroupName"

		# Column FaultState / Gets machines currently in the specified fault state.
		$FaultState = $XAmachine | %{ $_.FaultState }
		"FaultState $FaultState"

		# Column HostingServerName / Gets machines by the name of the hosting hypervisor server.
		$HostingServerName = $XAmachine | %{ $_.HostingServerName }
		"HostingServer $HostingServerName"

		# Column MaintenanceMode / Gets machines by whether they are in maintenance mode or not.
		$MaintenanceMode = $XAmachine  | %{ $_.InMaintenanceMode }
		"MaintenanceMode $MaintenanceMode"

		# Column PowerState / Gets machines with a specific power state. Valid values are Unmanaged, Unknown, Unavailable, Off, On, Suspended, TurningOn, TurningOff, Suspending, and Resuming.
		$PowerState = $XAmachine  | %{ $_.PowerState }
		"PowerState $PowerState"

		# Column RegistrationState / Gets machines in a specific registration state. Valid values are Unregistered, Initializing, Registered, and AgentError.
		$RegistrationState = $XAmachine  | %{ $_.RegistrationState }
		"RegistrationState $RegistrationState"

		# Column VMToolsState / Gets machines with a specific VM tools state. Valid values are NotPresent, Unknown, NotStarted, and Running.
		$VMToolsState  = $XAmachine | %{ $_.VMToolsState }
		"VMToolsState $VMToolsState"

		# Column AgentVersion / Gets machines with a specific Citrix Virtual Delivery Agent version.
		$AgentVersion  = $XAmachine | %{ $_.AgentVersion }
		"AgentVersion $AgentVersion"

		# Column Serverload / Gets machines by their current load index.
		$Serverload = $XAmachine  | %{ $_.LoadIndex }
		if(-NOT ([string]::IsNullOrEmpty($Serverload))) {
		    "<<<citrix_serverload>>>"
		    "$Serverload"
		}

		# Column SessionCount / Count of number of active / inactive sessions on the machine.
		$Sessions = $XAmachine | %{ $_.SessionCount }
		"<<<citrix_sessions>>>"
		if ($XASessions -match $DNSName) {
		"sessions $Sessions"
			$active_sessions = $XASessions | Where-Object {$_.Name -like "$DNSName, Active"} | %{ $_.Count }
			if (!$active_sessions) {$active_sessions = 0}
		"active_sessions $active_sessions"
			$inactive_sessions = $XASessions | Where-Object {$_.Name -like "$DNSName, Disconnected"} | %{ $_.Count }
			if (!$inactive_sessions) {$inactive_sessions = 0}
		"inactive_sessions $inactive_sessions"

		}
		else {
		"sessions $Sessions"
		"active_sessions 0"
		"inactive_sessions 0"

		}
		 "<<<<>>>>"
		if ($HostingServerName) {
            $HostingServerName = $HostingServerName.Replace($DNSdomain,$null)

		    "<<<<$HostingServerName>>>>"
            "<<<citrix_hostsystem>>>"
		    "VMName $DNSName"

		    # Column HypervisorConnectionName / Gets machines with a specific Citrix Virtual Delivery Agent version.
		    $HypervisorConnectionName  = $XAmachine | %{ $_.HypervisorConnectionName }
		    "CitrixPoolName $HypervisorConnectionName"
		    "<<<<>>>>"
        }
	}
"<<<<>>>>"

A few other things I learned while tinkering with the script:

  • You should configure the rule “Run plug-ins and local checks using non-system account” to run the plugin with a dedicated Citrix user - however keep in mind this will store the user password in plain text.
  • To reduce the security risk, the user for the plugin doesn’t need to be local admin on the delivery controller, he just needs the right “Allow log on locally”.
  • Contrary to the comment in the script, this user also doesn’t need to be a Citrix admin, the Read-Only permission is enough.
  • Make sure to replace the $DNSdomain variable in the script with your actual domain - keep in mind that it’s case-sensitive.

I hope this will help someone out there - feel free to comment your thoughts! :slight_smile:

Welcome back to the form @dafawe and thanks for sharing this!

Are you able to create a support ticket with the findings which could be considered a bug?