Posts RSS Comments RSS 253 Posts and 408 Comments till now

Calculated Properties

nicad49 asked
“Can you explain the last part of each script? Specifically the @{n=’Servers’;…}etc. I understand that we are creating some sort
of an array, but if I run it as is, I don’t get any values returned.”

This is great question. I see examples like this used all the time without explanation. Unless you had the chance to review all the
help files from all the different CMDLets there is good chance you missed some REALLY cool stuff. This is one of those things
hidden in the bowels of Help files and Books.

Before I go into my specific example, lets look at this excerp from http://technet.microsoft.com/en-us/library/bb978655.aspx

“You can also use Select-Object to add calculated properties to an object. To add a calculated property, use the Property
parameter and type a hash table for the parameter value. Create an Expression key in the hash table and assign to the key an
expression that calculates a value. The hash table can also have a Name key.”

Basically what we can do is add a property to an object that is calculated. This calculation could be from other properties or just a
change to the way the data is configured. Here is how you use this feature @{name=”SomeName”;expression={“Script block used
to provide value(s)”}}.

Some important things to note:
* The Name can be anything, even a valid property name.
* Expression is a scriptblock. What does this mean? It means that you can put any code you want in there… even an entire script
and what ever is returned is put in the property you created.

Now that we have some foundation lets look back at my code. Here is the first example.

$MF = (New-Object -com MetaFrameCOM.MetaFrameFarm)
$MF.Initialize(1)
$MF.Servers | Select-Object ServerName -expand Applications | Select-Object ServerName,AppName,DistinguishedName,
  @{n=‘Users’;e={$_.Users | %{$_.UserName}}},
  @{n=‘Groups’;e={$_.Groups | %{$_.GroupName}}} | export-Csv C:\AppsByServer.Csv -noType

Now the first problem maybe cut/paste not working correct so make sure line three is all one big long line.

Next lets zoom in on the Important line… number three

$MF.Servers | Select-Object ServerName -expand Applications | Select-Object ServerName,AppName,DistinguishedName,
  @{n=‘Users’;e={$_.Users | %{$_.UserName}}},
  @{n=‘Groups’;e={$_.Groups | %{$_.GroupName}}} | export-Csv C:\AppsByServer.Csv -noType

First we have the $MF.Servers. This returns an array of Citrix Server Objects with all sorts of properties. We only really care about
the Applications and the Server name so we go to the next step.

Select-Object ServerName -expand Applications. This code takes each one of the MFCom Server objects and Strips out everything
but the ServerName and the Applications. The reason for -expand is because Applications is an array of MFCom Application
Objects and we want them all.

Here is the biggy
Select-Object ServerName,AppName,DistinguishedName,@{n=’Users’;e={$_.Users | %{$_.UserName}}},@{n=’Groups’;e={$_.Groups | %{$_.GroupName}}}
This section takes the object we Created with the ServerName and the Applications and Passes on the ServerName, but extracts
information about the applications we want to know like AppName and DistinguishedName. The problem is that we want the users
and groups to. The problem with this is these properties are (like Server and Application) arrays of MFCom User or MFCom Group
objects. Enter calculated fields.

Lets look each calculated field
@{n=’Users’;e={$_.Users | %{$_.UserName}}}
This basically says create a property named Users and add the values from $_.Users, but only give me the UserName… not all the
other properties.
@{n=’Groups’;e={$_.Groups | %{$_.GroupName}}}
Same thing except for with Groups.

Perhaps multilevel Citrix Nesting isn’t the best place to get your teeth wet on calculated properties, but I hope I cleared it up a bit
for you.

7 Responses to “Calculated Properties”

  1. on 31 Jan 2008 at 10:52 pmnicad49

    I had change the 3rd line to “load the application data” as follows:

    $MF.Applications | Select-Object AppName,DistinguishedName,@{n=”Servers”;e={%{$_.LoadData(1)}; $_.servers | %{$_.ServerName}}}

    in order to display the servers.

  2. on 31 Jan 2008 at 11:31 pmBrandon

    There are a large number of properties that do not populate unless you do LoadData(1) but you shouldn’t have to for these properties. Either way… good catch.

  3. on 05 Feb 2008 at 9:39 amAndy

    When I try your script Brandon it produces a blank csv file. What am I doing wrong? I simply cut and paste your code into a powershell window. Is this right?

  4. on 05 Feb 2008 at 10:32 amBrandon

    Funny… I did the same thing and both worked.
    What kind of farm are you using? I tested on XP and 4.5

  5. on 05 Feb 2008 at 12:26 pmAndy

    I used XP and our farm is 4.0. I launched powershell using “runas” with my citrix admin credentials. I get no errors, just a blank csv file.

  6. on 05 Feb 2008 at 12:58 pmBrandon

    hmmm… what if you do this?

    $MF = (New-Object -com MetaFrameCOM.MetaFrameFarm)
    $MF.Initialize(1)
    $MF.Servers

    Also… what do you get back if you remove the Export-Csv

  7. on 11 Feb 2008 at 10:50 amAndy

    Brandon, thank you very much for your help over the last few days.

    It was my fault that I couldn’t get your scripts to work, as I’d not configured MFCOM properly. I’d left out the dcomcnfg part and once this was set up, your scripts worked a treat.

    Thanks again and I apologise for being so dumb. Rest assured I’ve given myself a good slap ;-)

Trackback this post | Feed on Comments to this post

Leave a Reply

You must be logged in to post a comment.