Digging in to Citrix Configuration Logging: Setting up the Database

This is the second part in a series on Citrix XenApp Configuration Logging. When Citrix XenApp Configuration Logging is enabled, all changes are written to a back end database. In this part, we will look at the details of how to create the database, logins, and users.

In part 1 of the Digging in to Citrix Configuration Logging series, we looked at what XenApp configuration logging was and how it worked.  Now, we are going to focus on how to set up the Citrix XenApp configuration logging database.

All Citrix XenApp farm changes are written to a back end database. The back end database can be:

  • Microsoft SQL 2000 and above (Microsoft SQL Express works too)
  • Oracle 9.2 or 10.2 

We will be using Microsoft SQL Server 2005 for this example.

Creating the Database

The first step in setting up the back end database for configuration logging is to create the database and user account(s).  This is pretty easy.  Just open up Microsoft SQL Server Management Studio, right-click Databases, and select New Database…  Give the database a name and accept the defaults.

New Database

Creating the Database Login(s)

The next step is to set up the database authentication.  In SQL Server Management Studio, expand Security, right-click Logins, and select New Login…

NewSQLLogin

Citrix XenApp Configuration Logging supports both SQL Server authentication and Windows authentication.

If using SQL Server authentication, you can make up any login name and password you want.  Keep in mind though that Citrix Configuration Logging does not support blank passwords.

If using Windows authentication, you can type a user name or group name in the form of domain\username or domain\group in the Login name field.  You can also select the “Search…” button to browse Active Directory for users or groups.

SQLSelectObject Tip: by default, only objects of type “User or Built-in security principal” are searched when using the “Search…” button.  You will need to add Groups to the search by clicking the “Object Types…” button.

In either case (using Windows or SQL Server authentication), be sure to change the Default database to the database created earlier.

Mapping the Login to a Database User

Even though you have created a database and a login, the two entities are not yet linked.  In other words, the login you created cannot log on to the database.  That is because a login is not equal to a database user.  The next step in the process is to map the created login to a database user and assign appropriate rights. 

In Microsoft SQL Server Management Studio, expand the Databases node, expand the database you created above, expand the Security node, right-click Users, and select New User…

newDBUser

newUser

Type a name in the Username field and type (or select) the login you created earlier in the Login name field.  The name you type in the User name field does not have to match the name in the Login name field, but I usually keep them the same for simplicity.

You will also have to tick the db_owner box under the Role Members section for now.  This is because the first time the Citrix XenApp farm tries to connect to the Configuration Logging database, the database schema will get created.  After the schema gets created, you can dial back the permissions.  I’ll explain the minimum permissions necessary in the next article.

Digging in to Citrix Configuration Logging – Part 1

This is the first part in a series on Citrix XenApp Configuration Logging. Citrix XenApp Configuration Logging helps keep track of changes made to your server farm. This feature can tell you what changes were made to your server farm, when they were made, and who made them. Part 1 in this series will further define where changes are logged and how the changes are logged.

I have presented on this topic in the past at BriForum and I wanted to share more about Citrix XenApp Configuration Logging here.  This will be a multi-part series that inspects each aspect of Citrix Configuration Logging and some creative ways of extending Citrix Configuration Logging.  So, let’s get started…

What is Citrix Configuration Logging?

According to the Citrix XenApp Administrator’s guide, “the Configuration Logging feature allows you to keep track of administrative changes made to your server farm environment. By generating the reports that this feature makes available, you can determine what changes were made to your server farm, when they were made, and which administrators made them. This is especially useful when multiple administrators are modifying the configuration of your server farm. It also facilitates the identification and, if necessary, reversion of administrative changes that may be causing problems for the server farm.” (emphasis added)

When I worked for Citrix, we had a load evaluator that had no available login times.  If a server was acting up, we could apply this “unavailable” load evaluator to it and figure out what was going on.  Oftentimes, we would discover that the “unavailable” load evaluator was applied to a new server and not know who did it or why they did it. So, we would have to resort to sending out an email asking why this server was assigned to the load evaluator.  Now, Citrix XenApp Configuration Logging tells you who did what and when.  That should be enough information to find out why.

Where are Changes Logged?

Changes that you make to the Citrix XenApp farm are logged to a database.  The back end database can be:

  • Microsoft SQL 2000 or Microsoft SQL 2005 (Microsoft SQL Express works too)
  • Oracle 9.2 or 10.2 

We will explore the details of the database schema in depth later on.

How are Changes Logged?

There are several ways to make changes to a Citrix XenApp Farm:

In order to facilitate logging changes made by any of these methods, Citrix introduced an IMA hook called CitrixLogServer.dll.  As you know, any change made to the data store has to go through IMA first. So, introducing an IMA hook makes sense.

Here are the facts about CitrixLogServer.dll:

  • Located in %ProgramFiles%\Citrix\System32
  • it is a Microsoft .Net assembly
  • it uses ADO.NET to write changes to the database.  Once a connection is made to the database, it will automatically disconnect after 5 minutes of inactivity.
  • Uses a XSD schema that is optimized for writes

 

Citrix XenApp Configuration Logging Architecture

When a change is submitted to IMA, the change is written via a transaction to the configuration logging database and data store.  It is possible to require all changes be written to the configuration logging database before they are allowed to be written to the data store.  This ensures all changes are logged.  Since the change is written via a transaction, a failure writing to the logging database or data store rolls back the transaction and no change is made or logged.

Citrix XenApp Configuration Logging Architecture

Bonus tip: if you clone servers in your Citrix XenApp farm and cannot join the cloned server to the farm, you may have to disable configuration logging.  Once the server joins the farm, you can re-enable configuration logging.

My other Blogs

When I first started this site, it was my goal to write technical articles and have a platform to distribute custom written software. I think I have kept true to that, but that makes for sparse updates. What you may or may not know is that I do contribute to 2 other blogs out there on a more regular basis

When I first started this site, it was my goal to write technical articles and have a platform to distribute custom written software.  I think I have kept true to that, but that makes for sparse updates.  What you may or may not know is that I do contribute to 2 other blogs out there on a more regular basis:

 

  • blog.Xcentric.com
    • I just started blogging here (I currently work for Xcentric as a system architect).  My goal with this blog is to focus on high level concepts surrounding virtualization, cloud computing, application delivery, etc.

 

I still try to keep this site focused on extending virtual environments.  What that means is I focus on tearing down software to get to the nuts and bolts and then try to figure out ways to uniquely extend the boundaries.

How to Save Web Interface Usernames in a Cookie

In the article titled “How to Enable AutoComplete for Web Interface Logon”, I explained how to enable the AutoComplete functionality of web browsers in order to save usernames and/or passwords for Citrix Web Interface. As the article explained, there are a lot of moving parts to the solution such as web browser settings, Protected Storage, JavaScript workarounds, etc. In this article, I will explain how to accomplish something similar by using cookies to remember the last username entered for Web Interface.

In the article titled “How to Enable AutoComplete for Web Interface Logon”, I explained how to enable the AutoComplete functionality of web browsers in order to save usernames and/or passwords for Citrix Web Interface. As the article explained, there are a lot of moving parts to the solution such as web browser settings, Protected Storage, JavaScript workarounds, etc. In this article, I will explain how to accomplish something similar by using cookies to remember the last username entered for Web Interface.

How it Works (if you do not really care how it works, you can just download the modification at the end of this post)

There are really only two parts to this solution. Part 1 – store the username in a cookie. Part 2 – get the username from the cookie and populate the “user name” field at logon. There is a little Web Interface SDK work to obtain the username, but I will explain what is going on.

 

Part 1 – Storing the Username in a Cookie

There are two steps to accomplish this part.

First, we need to get the username after it is validated by Web Interface. An ideal place to get the authenticated username is applistView.ascx. applistView.ascx is the user control in Web Interface that is responsible for displaying a list of applications a user has access to. So, we know if we got to applistView.ascx in the Web Interface logon/application enumeration process that a username should be available.

Second, we need to store the username in a cookie (this is pretty easy in comparison to getting the username).

Here is the code:

Modify applistView.ascx

Find the following text (around line 10):

<!–#include file=”../serverscripts/include.aspxf”–>

Paste the following right after this line

<%

//----------------------------------------------------------------
// WI mod
//----------------------------------------------------------------

string username = String.Empty;

// Get username
com.citrix.authentication.tokens.AccessToken accessToken = com.citrix.wi.pageutils.Authentication.authGetPrimaryAccessToken(wiContext.getWebAbstraction());
if(accessToken != null)
{
if(accessToken is com.citrix.authentication.tokens.GuestToken)
{
// Guest
username = wiContext.getString("Guest");
}
else
{
username = accessToken.getUserIdentity();
}
}

HttpCookie userCookie = Request.Cookies.Get("WI_username");

if(userCookie == null)
{
// Cookie doesn't exist, so create it
userCookie = new HttpCookie("WI_username");
}
else if(userCookie.Value != username)
{
// Need to update the cookie value
Response.Cookies.Set(Request.Cookies.Get("WI_username"));
}

userCookie.Value = username;
userCookie.Expires = DateTime.Now.AddDays(100);
Response.Cookies.Add(userCookie);	

//----------------------------------------------------------------
// End WI mod
//----------------------------------------------------------------

%>

Code explanation:

First, we need to get an AccessToken (see line 10 above). In the Web Interface object model, an AccessToken “…encapsulates information that may be used for authorization and authentication when a Subject requires access to a resource.” What that means in layman’s terms is an AcessToken basically holds your username, password, domain, identity, etc. (you can actually use the PasswordBasedToken Interface to get the password of a user if you wanted to as described in this article).

After we get the AccessToken, we can test to see if this is an anonymous user or not (an anonymous user would have a GuestToken) on lines 12-23 above. If the token is not a GuestToken, then we know we have an authenticated user. There are currently 3 methods you can use to get the user details from the AccessToken:

  1. getAccountIdentity() – gets an AccountIdentiy object.
  2. getShortUserName() – returns the username as a string. Example – if your user identity was domain\jasonco, getShortUserName() returns “jasonco”.
  3. getUserIdentity() – returns the entire logon identity as a string. Example: domain\username or [email protected] (if using UPN). I chose getUserIdentity() in the code above.

The rest of the code is pretty straight forward – it just creates or updates the cookie named WI_username. You could actually name this cookie anything you wanted.

Part 2 – Retrieving/Populating the Username from the Cookie

This part is quite a bit easier than the first part. All we need to do is to get the cookie, if any, from the previous code and populate the username field on the log on screen. The logon screen code can be found in loginMainForm.inc.

Here is the code:

Modify loginMainForm.inc

Find the following text (around line 106):

<td colspan="2">
    <input type='text' name='<%=Constants.ID_USER%>' id='<%=Constants.ID_USER%>'
        class='loginEntries<%=viewControl.getExplicitDisabled()?" loginEntriesDisabled":""%>'
        maxlength='<%=Constants.LOGIN_ENTRY_MAX_LENGTH%>' <%=viewControl.getExplicitDisabledStr()%>
        tabindex='<%=Constants.TAB_INDEX_FORM%>'

Paste the following right after this text:

<%
//----------------------------------------------------------------
//       WI mod
//---------------------------------------------------------------- 

HttpCookie userCookie = Request.Cookies.Get("WI_username"); 

if(userCookie != null)
{
%>
    value='<%=userCookie.Value %>'
<% 

} 

//----------------------------------------------------------------
//       End WI mod
//----------------------------------------------------------------
%>

Code explanation:

The <input… tag above is the field where you fill in your username in loginMainForm.inc. The code inserted above sets the value of the input tag to whatever was stored in the WI_username cookie (if there was anything stored in the cookie at all).

If you want to implement this in your environment and do not feel like copying and pasting all this code, you can download the modified files below:

download Modification for Web Interface 5.1

How to Enable AutoComplete for Web Interface Logon

The logon page for Citrix Web Interface explicitly disables the web browser functionality of saving form data. But, what if you want to let your users save their username (especially if they have a particularly long UPN)? This article will show you how to re-enable this functionality for both Web Interface 4.x and 5.x.

The logon page for Citrix Web Interface explicitly disables the web browser functionality of saving form data. But, what if you want to let your users save their username (especially if they have a particularly long UPN)? This article will show you how to enable AutoComplete functionality for both Web Interface 4.x and 5.x.

Disclaimer – I would highly recommend only implementing this solution in a secure internal environment. You do not want your usernames or passwords floating around out there in the public.

 

Citrix Web Interface AutoComplete

 

 

How Web Interface disables AutoComplete
Web Interface hasn’t always disabled the AutoComplete functionality of web browsers.  I actually think it is wise Citrix did start disabling AutoComplete by default because a lot of Web Interface sites are external-facing and AutoComplete can be a bad thing in an external scenario. The way Web Interface disables AutoComplete is by adding a property to the <form> tag in the HTML.  Simply adding autocomplete=”off” will disable AutoComplete for all <input> elements within the <form>. If you look at the rendered WI login page’s HTML, you will see <form… autocomplete=”off”>.

Enabling AutoComplete for Web Interface 4.x
Enabling AutoComplete for Web Interface 4.x is actually quite simple.  All you really need to do is get rid of the autocomplete=”off” property in the <form> tag.  To do this:

Modify loginView.ascx

Change this:  <form method="POST" action="<%=PAGE_LOGIN%>" name="NFuseForm" autocomplete=”off”>

To this:  <form method="POST" action="<%=PAGE_LOGIN%>" name="NFuseForm">

A possible downside to this is that passwords will be saved as well.  If you do not want passwords to be saved, you can tell just the password field to disable AutoComplete.  To do this:

Modify loginMainForm.inc

Change this: <input type='password'…

To this: <input autocomplete="off" type='password'…

Enabling AutoComplete for Web Interface 5.x
Enabling AutoComplete for web Interface 5.x is the same as enabling AutoComplete in Web Interface 4.x with one exception.  Web Interface 5.x does not use a <input type=”submit” /> button to submit form data.  Instead, Web Interface 5.x uses JavaScript to submit the form data.  This causes an issue with AutoComplete because AutoComplete only commits data to Protected Storage via a <input type=”submit” /> button.  So, to get around this bug “feature”, we need to do some trickery.

Since AutoComplete only works with <input type=”submit” /> buttons, we need to add one of these buttons to our login page.  We do not actually want to see this button since it is just there to facilitate the AutoComplete functionality, so we set the display style on the submit button to none (<input type=”submit” style=”display: none” />)

Finally, we need to manipulate the Web Interface JavaScript code that submits to form to tell it to “virtually press” our hidden submit button (this will cause AutoComplete to save the data).  Here are all the steps necessary to implement AutoComplete in Web Interface 5.x:

Step 1 – Modify layout.ascx

Change this:  <form method="post" action="<%=FormAction%>" name="<%=Constants.ID_CITRIX_FORM%>" autocomplete="off">

To this: <form method="post" action="<%=FormAction%>" name="<%=Constants.ID_CITRIX_FORM%>">

 

Step 2 – Modify loginMainForm.inc

Add the following to the bottom (right after </table>):

<input type="submit" value="submit" id="hiddenSubmitButton" style="display:none" />

This is our hidden fake submit button that will trigger AutoComplete to save the data.

Step 3 – Modify login.js

Change this:

function submitForm() {
    if (!isSubmitted) {
        changeLoginBtnColor(false);

        isSubmitted = true;

        var loginBtn = document.getElementById("loginButtonWrapper");
        if(loginBtn){
            loginBtn.style.color = "#aaaaaa";
        }

        disableLinks();

        document.forms[0].submit();
    }
}

To this:

function submitForm() {
    if (!isSubmitted) {
        changeLoginBtnColor(false);

        isSubmitted = true;

        var loginBtn = document.getElementById("loginButtonWrapper");
        if(loginBtn){
            loginBtn.style.color = "#aaaaaa";
        }

        disableLinks();

        var hiddenSubmitBtn = document.getElementById("hiddenSubmitButton");
        if(hiddenSubmitBtn.click) {

                hiddenSubmitBtn.click();
        }
        else {
                document.forms[0].submit();
        }
        return false;
    }
}

The highlighted code basically tells the JavaScript submit function to “virtually click” the hidden submit button we added to loginMainForm.inc.
Again, if you want to disable passwords from being saved, add autocomplete=”off” to all the <input type=’password’ … /> fields in loginMainForm.inc.

 

 

Other factors of using AutoComplete
In order for AutoComplete to save form data, the feature needs to be turned on in your web browser.  For Internet Explorer, this can be found by going to Tools -> Internet Options -> Content tab.

Internet Explorer AutoComplete

For Firefox, this can be found by going to Tools -> Options -> Privacy.

FF-AutoComplete

AutoComplete stores form data in Protected Storage – which means that the Protected Storage service needs to be running.   Protected Storage can, on occasion, get corrupted.  See this Microsoft support article about this situation: http://support.microsoft.com/kb/306895

Citrix turns 20

Citrix turns 20 today. In this post, I will tell you how I got introduced to Citrix several years ago.

Citrix Citrix is 20 years old today (still under the drinking age in the Unites States). I remember when I was first introduced to Citrix. It was back around 1999 when I used to work for an integrator. Most of the work I did was Novell related(yes I was a CNE back in the day). Anyway, one of the projects that came down the pipeline was something totally different. My role in the project was to visit a multitude of nursing homes throughout Mississippi and Louisiana, install a Cisco router and switch (I was actually a CCNA then too), install NICs in computers, and install this thing called a Citrix client on the PCs. My final test was to make sure the Citrix client could “talk” to the Citrix server in the main location. I didn’t really realize what was going on with this Citrix thing until about the 5th install I did. It was then that I started to think this was some pretty cool stuff. By the way, this was all WinFrame 1.x (based on Windows NT 3.51).

I started to learn more about Citrix and later got certified as a CCEA. The integrator I was working for became part of the Citrix channel and I soon found myself working with some really cool SEs like Barry Flanagan. Barry still tells a story from the first time we met – I showed him where I installed a Java Citrix client on a Novell server (Novell supported Java by then). I was like – “Barry, look – you can run NWadmin directly from the Novell server console (NWadmin was a Windows app you used to administer Novell servers).” I guess he thought that was cool, because he still talks about it.

A lot has happened since then. I went to work for Citrix in Fort Lauderdale for a while. I started this Citrix-focused website. Citrix greatly diversified their product portfolio. I’ve written thousands of lines of code (for free) to extend Citrix products. I became a CTP. And, I’ve done quite a bit of technical public speaking (mostly Citrix focused).

So, I guess it is a good thing that I had to travel to all those nursing homes to setup that Citrix thing. By the way, I still remember some of those roads in Louisiana. I remember driving down “Devil’s Swap Road”. I also had to drive down a road that didn’t have a name, but I was told I would recognize it because the sugar cane was really tall that time of year. Also, as it turns out, nursing home food isn’t that bad.

Web Interface for Resource Manager is Dead

I have gotten several comments (online and offline) and emails asking about future developments surrounding Web Interface for Resource Manager. Well, Web Interface for Resource Manager as you know today is officially dead. There are actually several reasons for this. Read on for more information…

I have gotten several comments (online and offline) and emails asking about future developments surrounding Web Interface for Resource Manager. Well, Web Interface for Resource Manager as you know today is officially dead. There are actually several reasons for this. Read on for more information…

MFCOM
The last update I gave on Web Interface for Resource Manager indicated that MFCOM (MetaFrame COM – the Citrix XenApp API) support would be included in order to get real-time statistics. As it turns out, MFCOM is being re-architected with PowerShell technology. So, there will be some re-writes for this type of integration. This also means no remoting (for the time being).

EdgeSight
Going forward, Citrix Resource Manager is being re-architected with EdgeSight technology. This means that the back-end database schema will be drastically different. The EdgeSight schema has a lot of the same information as the Resource Manager schema, but queries required to get that information will be a lot different. That means a lot of code re-writing.

This shift also got me to thinking whether I should focus on writing SQL Server Reporting Services Reports, or stick with the ASP.NET (web application) route. I finally concluded that the ASP.NET route is still the best way to go in order to take advantage of AJAX, Silverlight (I am looking at some Silverlight charting to replace the Flash charts), Web Services (although SSRS does support Web Services to an extent), etc. FYI: since EdgeSight is built around Microsoft SQL Server Reporting Services (SSRS), you can say goodbye to Oracle support.

What does this mean for the future of this project?
To boil things down to the main point – yes, Web Interface for Resource Manager is dead, but out of the demise of WIRM a new project is underway. This new project is called “Project Raley” for the time being. The components of Project Raley were first displayed at BriForum 2008 in a session I did with Kevin Goodman titled “The Data Puzzle – Putting the Pieces Together”. The “Pieces” in that session were Web Services. Putting those “pieces” together involved writing little to no code (although the Web Services require quite a bit of code). All that being said, Project Raley uses these Web Services to create a composite application. The Web Services developed so far are:

  • Active Directory
  • Configuration Logging
  • Event Logging
  • MFCOM
  • Resource Manager
  • RTO PinPoint

Web Services currently under development are:

  • Citrix Licensing (via the Citrix Licensing WMI Provider)
  • General System WMI
  • EdgeSight

 

The inevitable question – “When is this going to be released?”
The broad answer is – “this year”. Using these SOA techniques has required quite a bit of ground-up work. But, on a positive note, I am able to knock out two projects at the same time. The Configuration Logging Web Service will be consumed by both Project Raley and Project S-Bend. I will also try to post some videos of alpha code to let you see some of this in action as well.

Please feel free to shoot me an email if you would like to beta test.

Silverlight Web Interface Sneak Peak

What do you get when you combine Citrix Web Interface, Microsoft Silverlight, and AJAX? You get my latest Web Interface modification. Read on to find out more…

I have been preparing for some Citrix Synergy and BriForum sessions where I will be presenting on Web Interface internals and customizations. One of the customizations I put together is an adaptation of Narenda Wicaksono’s Silverlight TSWeb Access for Windows Server 2008 Terminal Services. I created a similar application built around the Citrix Web Interface API. I am using Microsoft Silverlight 2.0, AJAX, Web Interface APIs, and Citrix XenApp 4.5. Check out this short video to see more:

I know it was hard to tell a lot of details from the video, but I will post more details soon.

Template updates for Citrix Web Interface 4.6

Two of my most popular posts (“Super Easy Customization of Citrix Web Interface 4.x” and the “Citrix Web Interface SharePoint Look and Feel Template” download) have been updated to include support for Citrix Web Interface 4.6.

In preparing for some Citrix Synergy and BriForum sessions, I made some updates to the following two articles:

The Super Easy Customization of Citrix Web Interface 4.x article has been updated to include a “bare bones” template for Web Interface 4.6.

The Citrix Web Interface SharePoint Look and Feel Template download has been updated to include a SharePoint look and feel template for Web Interface 4.6.

Feel free to use/modify these templates for your own use.

Web Interface for Resource Manager 3.0 Architecture Update

When the Web Interface for Resource Manger Roadmap was posted, I mentioned that Web Interface for Citrix Resource Manager version 3.0 would include a major architectural shift toward a Service Oriented Architecture (SOA). This shift is well underway and the purpose of this post is to share some of the progress as well as some of the nuts and bolts behind the architecture.

When the Web Interface for Resource Manger Roadmap was posted, I mentioned that Web Interface for Citrix Resource Manager version 3.0 would include a major architectural shift toward a Service Oriented Architecture (SOA). This shift is well underway and the purpose of this post is to share some of the progress as well as some of the nuts and bolts behind the architecture. Disclaimer – the following may get a little boring.

Web Services
I have been toying with this idea for a while and finally made the decision to move everything to Web Services. Web Services allow for a greater separation of presentation and data. The thought behind creating sets of Web Services in Web Interface for Citrix Resource Manager is to allow other applications to consume the data WIRM produces. Other applications such as Microsoft SQL Server Reporting Services, SharePoint, custom portals, Project S-Bend, etc. can all consume these Web Services. And remember, WIRM is moving beyond the bounds of the Citrix Resource Manager Summary Database so there will be Web Services for the Configuration Logging database, Active Directory, MFCOM, WMI providers, third party data sources, etc. as well as the Web Services for the Citrix Resource Manager Summary Database.  Here is a screen shot of some of the Resource Manger Web Service’s rendered WSDL:

Web Services


Generic Database Access, DAL, and DAAB

One of the challenges of querying the Citrix Resource Manager Summary Database from a generic application is that the database can be Microsoft SQL or Oracle. What I have done in the past with Web Interface for Citrix Resource Manager is maintain separate data access blocks – one for SQL and one for Oracle. Depending on the database provider specified in the database connection string in web.config, I would utilize the System.Data.SqlClient or System.Data.OracleClient namespace. This has proven to be a cumbersome and time consuming process to code and test.

Enter the Microsoft Enterprise Library Patterns and Practices Data Access Application Block (a.k.a. DAAB). Web Interface for Citrix Resource Manager implements a Data Access Layer (DAL) which is a common SOA component. The DAL is responsible for physically getting the data from the source(s) and delivering the data to the Web Service(s) – sometimes there is a façade’ in between, but that is another discussion. One of the major pieces of the DAL for Web Interface for Citrix Resource Manager is the DAAB. The DAAB allows for generic database access which means one (reduced) set of code that allows access to either Microsoft SQL or Oracle (or any other ODBC compliant database for that matter).

SOA Architecture

“Sneak Peek” of Version 3.0
The above mentioned architecture makes the information aggregation possible in version 3.0.  To get a better idea of how this all fits together, I have included this screen shot of the new configuration page.  The more information you provide on the configuration page, the more information you get in the Web Interface.

So, stay tuned, there is still more to come…

Get email alerts for your Citrix PS 4.5 Farm with Project S-Bend

Project S-Bend fills the gap in Citrix Presentation Server 4.5 Configuration Logging by alerting you via email when changes happen in your farm.

Citrix introduced a new feature in Citrix Presentation Server 4.5 called Configuration Logging. Configuration Logging keeps track of every change to every object in your Citrix Presentation Server Farm. This information is kept in a back end database and you have the ability to run reports on these changes via the Report Center in the Access Management Console. For more details on setting up Configuration Logging and running reports, check out this article by Al Solorzano.

I think this is a really cool feature that lets you know who did what and when they did it. But, in order to get this information, you have to run a report from the Report Center in the AMC. Granted, you can automate reports, but it would be nice if there was some mechanism to alert you when a change was made. This is where Project S-Bend Phase I comes in to play. Project S-Bend was originally created as an exercise for my session titled “Digging into Citrix Presentation Server 4.5 Configuration Logging” at BriForum Europe 2007.

Project S-Bend Phase I consists of 3 main parts; an “Alerts” table added to the Configuration Logging database, a SQL trigger, and a Windows Service. Project S-Bend uses these parts to send email alerts whenever a change is written to the Configuration Logging back end database.

download JasonConger.com_SBend.zip

Alerts Table
This is a very simple table that is populated by the SQL trigger.

SQL Trigger
The SQL trigger is added to you Citrix Configuration Logging database and fires any time a change is written to the database. The trigger writes the ID of the change to the Alerts table.

Windows Service
The Windows Service reads the Alerts table populated by the SQL trigger. For each row in the table, the Windows Service sends an email to the specified email address with details concerning the object changed.

How it all works
The process is actually quite simple.

  1. When a change is made in your Citrix Presentation Server 4.5 farm, a log entry is created in the Configuration Logging database.
  2. When the log entry is created, the SQL Trigger fires and writes an entry to the Alerts table.
  3. The Windows Services reads the Alerts table on a configurable timed interval. When the Windows Service encounters unprocessed alerts in the Alerts table, it sends and email with details of what was changed.

Project S-Bend flow

What about Phase II?
I guess it is quite obvious that there is a Phase II in the works since I named this thing Phase I. Actually, Phase II is a provider. “A provider for what?” you may ask. Phase II is a provider for reports. Web Interface for Resource Manager will consume this provider as mentioned in the Web Interface for Resource Manager Roadmap.

Project S-Bend Setup Instructions

Project S-Bend sends alerts when changes happen on your Citrix Presentation Server 4.5 farm.

Note: The setup instructions and screenshots shown below are for use with Microsoft SQL Server 2005. However, the steps are similar for Microsoft SQL Server 2000.

 download Download Project S-Bend Phase I

Step 1 – Set up the Database

Open SQL Server Management Studio (or SQL Enterprise Manager for SQL 2000).
Right click on your Citrix Configuration Logging database and select “New Query”.

New Query

In the Query window paste the following SQL Script:

Press F5 to execute the query.  This will create the Alerts table and the SQL Trigger.

Step 2 – Set up the Windows Service

Copy the following files to your preferred destination directory (something like C:\Program Files\CitrixConfigAlert\):

  • CtxConfigAlert.exe
  • CtxConfigAlert.exe.config

Edit CtxConfigAlert.exe.config with the appropriate values for your environment. Set values for the following:

  • connectionString – Tip: visit www.connectionstrings.com for help with this value.
  • PollInterval – This is how often (in seconds) the Windows Service will poll the Alerts table.
  • MailToAddress – The destination email address to send the alerts.
  • SMTPServer – The name or IP address of your SMTP server.
  • SMTPPort – The port of your SMTP server (defaults to 25).
  • MailSubject – This will be the subject line of the email sent.
  • MailFromAddress – The email address used to send the alert.
Step 3 – Install the Windows Service

 

  • Open a command prompt and change the directory to C:\Windows\Microsoft.NET\Framework\v2.0.x
  • Perform the following command:
         InstallUtil /I path_to_CtxConfigAlert.exe
  • This will install a new Windows Service called “Citrix Change Alerts (S-Bend)”.
  • Start the service.

Any errors that occur while starting the service, or during the operation of the service, will be logged to the Windows Application event log.

Note: Changes made to CtxConfigAlert.exe.config require a service restart to take effect.

Script to Manipulate APPSRV.INI

What happens when you need to make mass changes to APPSRV.INI? Use this script to make changes to your user’s APPSRV.INI file via login script. The script adds or modifies .INI file key/value pairs and sections.

Use this script to make changes to your user’s APPSRV.INI file via login script. The script adds or modifies .INI file key/value pairs and sections.

  Download mod_appsrv script v1.1

The Scenario
So, you have been combing through the various support forums all day long trying to find a solution for an issue. You finally find the solution, but it involves modifying every user’s APPSRV.INI file located on their workstation. One common solution that matches the above scenario has to do with Single Sign On issues with Citrix Web Interface. One of the most recommended solutions is to add the following two lines to the [WFClient] section of APPSRV.INI:

SSOnUserSetting=On
EnableSSOnThruICAFile=On

Reference: http://support.citrix.com/article/ctx368624

The Dilemma
So, you try this and it fixes the issue for the user. What do you do now? Manually modify each user’s APPSRV.INI? Tell your users to perform the modification themselves? Script the change? Tell your boss there is no fix for the issue?

The Solution
Script the change sounds good to me, but how do you do that? That is where this article comes in. I mentioned I had a script to manipulate APPSRV.INI in the comments of this article. I have received many emails requesting the script. So, I decided to “spruce up” the script a little by adding more comments and logging and then share it. The script is written in such a way that you can add or modify any key/value pair to any section in APPSRV.INI (or any .INI file for that matter). Just modify the following section of the script to suit your needs:

'**********************************************************
' Add/modify key/value pairs
' modINISection takes 3 parameters:
'    Section name
'    Key
'    Value
'**********************************************************
modINISection "WFClient", "SSOnUserSetting", "On"
modINISection "WFClient", "EnableSSOnThruICAFile", "On"

The above example shows how to implement the solution to the delimma discussed earlier.

Here is another useful one to add that addresses clipboard issues:

modINISection "WFClient", "CbChainInterval", "2000"

From the Citrix Client 9.100 Readme http://support.citrix.com/article/CTX107650

“This fix introduces support for a mechanism to check at periodic intervals the client’s ability to receive clipboard change notifications. If the mechanism finds the client to be unable to receive such notifications, the client will attempt to register itself to receive future notifications. To enable this functionality, you must modify users’ appsrv.ini files as follows: 1. Open the appsrv.ini file located in the user profile directory using a text editor. 2. In the WFClient section, locate or add the entry: CbChainInterval=<value>, where value is the interval, in milliseconds, at which checks are to be performed. Supported values range from 0 to 2,000, inclusive.”

Think of it as an auto RepairCDBChain.exe

Some quick things to note about the script:

  • If you specify a section for modINISection that does not exist, the section will be created.
  • If you specify a key that does not exist, the key will be created at the end of the section.
  • Curretnly, there is no implementation to delete key/value pairs (I’m not sure that would even be useful for the intended usage)
  • A log file is created in the same directory as the APPSRV.INI file. The log file is named the same as the script name. If you change the script name to match you company’s naming convetion, the log file name will change automatically.

Good luck and have fun. But, as always, test test test. Make sure this script works in your environment before you throw it out there on your global login script.