Posts RSS Comments RSS 253 Posts and 411 Comments till now

Multiple Paths to the same End (Citrix)

Today I was asked this question

“Is there a more efficient way to list each published app and list out servers that are associated with it? In hope to give me an output that will display the ‘AppName’ objects once and display all the servers.”

He was referring to script I have posted somewhere (/shrug.)

I knew exactly what he wanted and thought “HEY! This would be a good time to blog about MFCom object Nesting.”

What do I mean by “MFCom object Nesting?” I simply mean that MFCom object model is nested in such a way that you can attain the same information from various code paths. For example, Farm objects contain Application objects which contain Server objects, but Farm objects also have Server objects which contain Application objects.

Farm -> Applications -> Servers
Or
Farm -> Servers -> Applications

Why is this important or why would Citrix do this? IMO, it is to provide a shorter code path for the information you want.

Here are some examples

In the case of the question I received, what he had required getting all the applications from each server and returning the information like this:

$mfarm.Servers | Select ServerName -expandproperty Applications | Select ServerName,
                                                                          AppName,
                                                                          DistinguishedName,
                                                                          @{n="Groups";e={$_.Groups | %{$_.GroupName}}}

What he wanted to get was all the applications and output the information directly like:

$mfarm.Applications | %{$_.LoadData(1);$_} | Select-Object AppName,
                                                           DistinguishedName,
                                                           @{n=‘Groups’;e={$_.Groups | %{$_.GroupName}}},
                                                           @{n=‘Servers’;e={$_.Servers | %{$_.ServerName}}}

 
Perhaps a more direct example would be collecting Sessions. If I want all the Sessions for a Server I could do one of the following:

$farm.Sessions | ?{$_.ServerNamematch "Server1"}

this works, but has to touch all my sessions… a better way would be like:

Get-CitrixServer  "Server1" | %{$_.Sessions}

 
More Info on LoadData()
If you are not familiar with the LoadData() method on the Application object it is critical that you get familiar, and get familiar quick.

LoadData() was introduced in MPS 4.0 (I believe) to allow the farm (or directly instantiated Application objects) to be returned with just a small bit of information. This allows you to quickly get basic application information without having to collect the entire data set, saving both time and network traffic. The problem is that most people do not know this and it can get quiet messy.

Why is it messy? If you get an application and set a property (like adding a user) and then commit the data back to the server using the SaveData() method, what do you think will happen? One could expect it would only update that which has change, but one would be wrong. When you call SaveData() it actually commits whatever is in local memory to the farm (yup, you got it… HOSED!) You just committed an effectively empty application and set it back to the Farm wiping out any existing information.

Moral of the story? USE LoadData().

Trackback this post | Feed on Comments to this post

Leave a Reply

You must be logged in to post a comment.