Big discussions are happening in August and will you be part of it? Over three days in August a XenDesktop Ask the Architect TechTalk series will be delivered focusing on analyzing, designing and implementing a VDI solution.
This particular series is focusing on the questions I hear over and over again: # I'm interested in VDI but I'm not sure where to start?
- I already use XenApp but don't know if and when I should be using XenDesktop instead.
- I've decided to go with XenDesktop as my VDI solution, but how do I design the environment correctly?
I believe many of you have similar questions. Instead of answering these questions on a one-by-one basis, we've decided to do an Ask the Architect TechTalk series.
Part 1: Virtual Desktops or Virtual Applications: Selecting Your Best Solution*(August 11 @ 1PM EDT)*
We've heard the debate from numerous people across numerous platforms... Should I use TSE or VDI for my organization? When should I use XenDesktop if I already have XenApp? What type of virtual desktop do my users require? What options do I even have?
This is a big question and one that deserves the entire time. I encourage you to attend this session as it sets the stage for the rest of the week. If you can only attend one session, then this is the one to attend.
Part 2: Creating an Enterprise VDI Solution with XenDesktop (August 12 @ 1PM EDT)
Once you decided to use XenDesktop as your VDI solution, how do you create your enterprise design? Would you believe there are essentially 4 things you need to know in order to create your XenDesktop design? Based on those four items, you can design the entire infrastructure. We will cover the design decisions for# Virtualization Infrastructure
- OS Delivery
- Application Delivery
- Desktop Delivery
- Virtual Desktop Design
Part 3: Successfully Migrating Users to Virtual Desktops(August 13 @ 1PM EDT)
Once the environment is designed and built, its time to move users over to the virtual system. The cutover needs to be smooth and seamless for the users or else they will need to recreate their entire personalized desktop environment. This will not only take time, but will also give the users a bad first imipression of the overall solution.
This TechTalk session focuses specifically on how to migrate user environments into the virtual desktop world. It will cover the options, ramifications, and approaches.
This should be a great series with lots of good information. Hope to see you there!
Daniel - Lead Architect - Worldwide Consulting Solutions
Follow me on Twitter: http://www.twitter.com/djfeller
Follow me in the Blogs: http://community.citrix.com/blogs/citrite/danielf
The Burton Group Catalyst Conference has always been a highly technical and packed-full of practical recommendations. This year's event, July 27-31 in San Diego, California looks to be no exception. More importantly, this year's event will focus heavily on VDI and VDI architecture as Chris Wolf from Burton highlights. Some of the key VDI sessions are:
- Building a Business Case for VDI
- VDI on the Large-Scale: From Business Case to Support
- Desktop Virtualization - Five Years Forward
- Starting Over: New Management Trends for Virtualized Desktops
How you can help?
As you know from my blog, I focus on defining the next generation VDI architecture. I'm not interested in hearing more opinions on whether VMware View is better than XenDesktop or hearing one company bash another. I let others do that, which you can watch the Thrilla in California between Simon Crosby and Scott Drummonds (should be entertaining). I want to understand how different companies are architecting for VDI.
Unfortunately, because of other commitments, I'm unable to attend Catalyst and I know the VDI information is going to be extremely valuable. So I'm asking to see if any of you plan on attending.
Reporting from Burton Catalyst
If so, I have a request. I'm looking for the following information from the VDI session:
- Key points
- Lessons learned
- Decision criteria
- Photos
- How are companies architecting VDI
- Reference architecture diagrams
If you are game, send me an email and let me know. After the conference I would compile the notes into blog post(s) and provide a huge shoutout for your help. I know this is a different approach, but none of us can be at all the events that we want. Remember, even though I work for Citrix, my goal is to advance the VDI concept. Everyone has a lot to learn about VDI and it is in the best interest of the industry to share the latest knowledge, regardless of vendor.
If you would like to contribute, please contact me by emailing me.
Thanks and I look forward to hearing from you
Daniel - Lead Architect - Worldwide Consulting Solutions
Follow me on Twitter: http://www.twitter.com/djfeller
Follow me in the Blogs: http://community.citrix.com/blogs/citrite/danielf
Provisioning Services High Availability Considerations - Part 3
In the previous Provisioning Services High Availability Considerations blog, I spoke about placing your vDisks on a Windows Network Share (CIFS). Now I will talk about placing your vDisks on a Network Attached Storage (NAS).
Placing your vDisks on a Network Attached Storage (NAS)
Using a single Network Attached Storage (NAS) to store the vDisks is an easy way of implementing a central vDisk store at moderate cost. This solution will enhanced reliability and give you a greater degree of scalability to support an increasing number of Target Devices.
What should we consider with this solution?
- No redundancy for NAS outages (all PVS Target Devices stop responding).
- Requires software to manage the storage array. RAID arrays must be configured on the storage array and assigned to each PVS Server.
- I/O for vDisk input (loading from the share) and vDisk output (delivering to the Targed Devices) is handled by the same network link. This affects the overall performance of the solution.
What are the recommendations?
- Network Interface Card (NIC) - Teaming should be used to increase the reliability and the I/O between PVS Servers, File Server and Target Devices.
- Where feasible dedicated NICs should be used for loading the vDisks and for delivering the vDisks to the Target Devices.

Elisabeth Teixeira. Follow me on Twitter:http://twitter.com/lizteixeira
One of the most common questions I've heard on Workflow Studio is how you can initiate the execution of workflows from an ASP.NET web page. The web is a great platform for delivering applications to end-users, and more and more applications are being delivered by a web browser each day. How cool would it be to kick off a workflow within Workflow Studio based on a user-action performed inside a web application? In this blog I'm going to show you how to do it and I'll give you the tools to customize this further to meet the needs of your application.
Example Usage
Before I go into the details about how the sample web application works, I want to quickly provide an example of why you may want kick off workflow execution from a web page. As you think about your business, ask yourself what it takes to get a new hire set up with new credentials across all of the systems in your environment. You need an Active Directory account, application accounts, HR accounts, credentials supplied to your single sign-on solution, etc.
To accommodate this scenario, you can build a web page that presents a form to an admin to gather details about a new user, what groups they should belong to, and what applications/resources they need to access. This web page can call a workflow within Workflow Studio passing in the details about the user, and the workflow can automate the provisioning of the Active Directory account and application accounts across various systems. That's a pretty powerful system and would greatly simplify a lot of the complexities for performing those actions manually. Building that type of workflow might take some custom development effort, but Workflow Studio 1.1 already provides activities for provisioning user accounts in Active Directory to help get you started.
ASP.NET Web Application Overview
The sample web application that I'm providing here is functionally equivalent to the sample Windows application that I provided in the last blog. To compare and contrast the differences between automating workflows with a Windows and Web application, I wanted to keep the functionality and UI mainly the same. The web version of the application is shown below.
I describe my adventures for coding this application in the bottom of this article. To sum up, this application really has two parts. You have the ASP.NET application that contains the ASPX page and code-behind page. You also have a COM object that you need to install inside Component Services. (I have steps for doing all this below).
When you click the Execute Workflow button inside the web page, the ASPX page gathers what workflow you are executing and what runtime it is deployed on. It then calls the COM object to actually execute the workflow. The COM object uses the Workflow Studio Powershell cmdlets for communicating with Workflow Studio. I was getting security issues when I tried to run those functions within the context of IIS. By creating a COM object and placing that object within Component Services, I was able to overcome the issues I was having.
For more information on how this application works, feel free to check out the previous article of this blog series. I described in great detail how the Windows version of this application functions, so I'll refer you to that article for the extra details. For more information on why I needed to build the COM object, refer to the Lessons Learned section at the bottom of this article.
Downloads:
Download the ASP.NET web application IIS files
Download the ASP.NET web application source code
Prereqs for using the ASP.NET application:
Before you set up this web application on your Workflow Studio machine, you will need to have the following installed and/or configured beforehand:
- Workflow Studio 1.1
- Powershell 1.0
- IIS installed with ASP.NET enabled
- IIS configured with the ASP.NET v2.0.50727 web service extension set to Allowed
- Determine or specify an account within the Workflow Studio Console for executing the workflows. This is done within the Security section.
- Pre-deploy the Workflow you want to execute within the Workflow Studio Console. See Part 1 of this blog series for more information.
Setting up the ASP.NET application:
To set up this sample web application, follow the steps in the sections below.
Application Setup
- Copy the IIS files from the ZIP above to C:\Citrix (or any accessible location on your Workflow Studio machine)
- Update the web.config file with the appropriate impersonation account. This account should have permissions to execute workflows within Workflow Studio and should be the same account that is added to Component Services later in these steps.
IIS Setup
- Open IIS and create a virtual directory for the application. Point the virtual directory to the folder specified above. Enable script execution on the directory.
- View the properties of the virtual directory in IIS. In the ASP.NET tab, set the ASP.NET version to 2.0.50727.
Component Services Setup
- Launch Component Services by navigating to Start->All Programs->Administrative Tools->Component Services
- Within Component Services, navigate to Computers->My Computer->COM+ Applications. Right-click COM+ Applications and select New->Application
- The wizard now starts. Create an empty application
- Specify a name such as "WFSCOM" and select Server Application
- Set the application identity to a Workflow Studio admin account
- Create a new role called "Access"
- Add the Workflow Studio admin account to the Access role
- Complete the wizard
- After the COM+ application is created, add a new component to the COM+ application. Navigate to Computers->My Computer->COM+ Applications->WFSCOM->Components. Right-click Components and select New->Component.
- The wixard now starts. Choose to install a new component
- Browse to the WFSCOM.dll file (C:\Citrix\WFSWebClient\bin\WFSCOM.dll).
- Complete the wizard
You should now see the WFSCOM.WFSAction COM object listed within the Components section. In the Interfaces section, there is an inteface called IWFSAction that contains the methods of our COM object. The ASP.NET code calls the COM object to execute these methods. Since this object resides inside Component Services, these methods run outside the context of IIS under the Workflow Studio admin account that we specified above.
Lessons learned from developing this application
Developing an ASP.NET web application that executes workflows actually turned out to be a little more difficult than building the equivalent Windows application. With a Windows application, the application runs under the context of the logged-on user account. If that logged on user had permissions to execute workflows inside Workflow Studio, that user would be able to use the custom Windows application without issues. With a Web application, the application runs under the context of IIS. You can modify the account that runs a web application in a few places. (1) Editing the properties of the virtual directory or (2) Including a <identity impersonate="true"> tag inside the web.config file of the ASP.NET application.
Armed with that knowledge I set out to build the ASP.NET application. The approach I initially took was to take all of the code I had inside the Windows application and paste it into the ASPX page and code-behind page. The only thing I changed was I replaced all of the Windows controls with Web controls and I changed how I sent messages back to the user. When debugging this application inside Visual Studio, my application actually ran fine. However when I deployed it to IIS and ran it, that was a different story. I kept on getting Access Denied messages whenever I wanted to retrieve the workflow list or execute a workflow. Something inside those functions was causing me issues...
After much debugging, I deduced that the code that was causing the Access Denied messages was when I was trying to get a reference to the deployed workflow inside my PowerShell SDK code. For whatever reason, IIS just did not have the permissions to execute the Workflow Studio Powershell cmdlet called get-deployedworkflow. I put this section of code below so you are aware of which section I was having issues with.
//Get reference to the deployed workflow. We are executing the Powershell command below: //$workflow = get-deployedworkflow -workflowruntime $runtime -workflowname $strWorkflowName -includeschedule l_objPipeLine = l_objRunspace.CreatePipeline(); l_objCommand = new Command("get-deployedworkflow"); l_objCommand.Parameters.Add("workflowruntime", l_objRuntime); l_objCommand.Parameters.Add("workflowname", l_strWorkflowName); l_objCommand.Parameters.Add("includeschedule"); l_objPipeLine.Commands.Add(l_objCommand); l_objCommandResults = l_objPipeLine.Invoke(); //Get Access Denied here when running this code in IIS PSObject l_objWorkflow = l_objCommandResults[0]; l_objPipeLine = null
After playing with the Virtual Directory account settings and web.config impersonation settings for a while, I still was not able to get past the Access Denied message. I would have thought that setting the web.config <identity> tag to the Workflow Studio admin account would have done the trick, but I still received that error message. So I then I went to Plan B and thought of a different approach. What if I take that particular code outside of IIS and put it into a more controlled environment where I can run it under whatever account I want and not have to worry about IIS getting in the way?
That solution was Component Services. I'm not an everyday developer (probably have one development project a year), but I remembered using Component Services many years back with a MFCOM application I wrote. (MFCOM is the XenApp API). With that application, I wanted to be sure that my MFCOM code would run under the context of a XenApp admin account and not the logged on user account. So creating a COM object and placing that object within Component Services allowed me to run it under whatever account I needed. With Component Services, you also have the choice of running the COM object in-process as a library application or out-of-process as a server application. When you run it out of process, it is executed within a different memory space than the calling application. Creating a COM object and executing it as a server application under the context of a Workflow Studio admin account was the missing ingredient for the Web Application that I was building. Since it runs out-of-process, IIS can't get in the way and mess with those security permissions any more!
Although most of the Workflow Studio cmdlets functioned fine when running within IIS, I decided to move the entire Powershell SDK functions themselves to the COM object that I would run within Component Services. Although this sounds really complicated, the good news is that I've done all the work for you. The COM object that I am providing within this article has all the functions you need for executing a workflow. If you want to create your own ASP.NET application that executes workflows, you just need to add my COM object to Component Services on your Workflow Studio machine, and then call the methods of the COM object inside your ASPX page. If you are reading this article, I would venture to guess that you might have quite a bit of experience in working with ASP.NET so you should have the tools you need to proceed from here.
About the source code:
The source code above includes both the ASP.NET web application and the COM object for executing the workflows. Your development machine will need Visual Studio 2008, Workflow Studio, Powershell 1.0, Powershell SDK, and IIS.
If you want to step through the code within Visual Studio, you'll need to place the COM object within Component Services on your development machine. You can follow the manual steps above for doing this or use the regsvcs utility. To use regsvcs.exe, open the Visual Studio command prompt and type a command such as this:
regsvcs /c "C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\WFSWebClient\WFSCOM\bin\Debug\WFSCOM.dll"
I tried to code the COM object so that you wouldn't need to make any changes to it if you just wanted to execute workflows on Workflow Studio. If you do need to make changes to the COM object for any reason, remove the COM object from Component Services. If you placed the COM object within the global assembly cache (GAC), remove it from the GAC as well. (The GAC resides in C:\Windows\Assembly. Just right-click on the WFSCOM assembly to un-install it). Then open the Visual Studio solution and make changes to the WFSCOM project as you need to. Re-compile the project. When you are ready to re-deploy the COM object, add WFSCOM.dll to the global assembly cache (GAC) to get a new type library (.tlb file). To add it to the GAC, just execute a command such as below. Then re-add WFSCOM.dll back to Component Services using the regsvcs command above. If you open Component Services, you should now see the WFSCOM COM+ application listed.
gacutil.exe /i "C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\WFSWebClient\WFSCOM\bin\Debug\WFSCOM.dll"
I hope this blog series on automating Workflow Studio will help you out with your projects. Happy coding!
Blogs in this series:
Using Powershell to automate workflow execution within Citrix Workflow Studio
Passing parameters into a workflow within Citrix Workflow Studio
Automating workflow execution for Citrix Workflow Studio using a .NET windows application
Automating workflow execution for Citrix Workflow Studio using an ASP.NET web application (this one)
This is the third part of a four-part series on automating workflow execution within Citrix Workflow Studio. In the first two parts of the series, I discussed how you can create Powershell scripts to execute workflows. Part 1 provided a high-level overview of creating Powershell scripts for automating workflow execution and Part 2 expanded on those scripts to discuss how to pass parameters into the workflow. In this blog, I will discuss how you can automate workflow execution with a custom Windows application. The sample .NET application I built is shown below. I am providing both the executable and full source code to allow you to expand upon this solution to meet the needs of your environment.
When would I need to use a custom application for executing workflows?
A lot of you might be asking the question - "If we can use the Workflow Studio Console to execute workflows, why would I need a custom application to do that for me?". The answer really comes down to how you need to execute certain workflows in your environment. If you need to execute workflows "on-demand" or "on a schedule", the Workflow Studio Console would meet those needs. Just open the Workflow Studio Console and schedule a job to run immediately or on a pre-determined schedule. However, if you need "event-driven" automation where a third-party application kicks off the execution of a workflow based on an event happening, that is where you need to be able to hook into Workflow Studio with a custom solution to perform that type of automation.
The custom application provided in the Downloads section below provides a sample for how you can tie any .NET windows application to Workflow Studio for executing workflows. Feel free to try out the sample application on your Workflow Studio machine. The full source code is also provided to allow you to customize and extend the application further based on what you need to do.
Downloads:
Download the application executable here
Download the application source code here
Preparing your Workflow Studio environment to use the custom application:
The custom application needs to run on a machine that contains Workflow Studio since it ties into Powershell and calls the Workflow Studio cmdlets for performing various actions on Workflow Studio. In your Workflow Studio Console, you will need to pre-deploy the workflow that you want to automate (see Part 1 for more information on pre-deploying workflows). The workflow that you want to automate can include parameters as well. Parameters for a workflow are defined in the Workflow Studio Designer under the Global Properties section (see Part 2 for more information on defining workflow parameters).
This custom application functions as any typical Windows application in that it runs under the context of the logged-on user account. The logged-on account needs to have permissions in Workflow Studio to execute workflows. These permissions are defined in the Security section of the Workflow Studio Console. For simplicity, I typically add the user accounts as a "Workflow-Admin", but you can play with the security roles here to determine what roles are actually needed.
Using the custom application:
To use the custom application, log onto your Workflow Studio machine with an account that has permissions to execute workflows within Workflow Studio. Place WFSWorkflowExecute.exe on your Workflow Studio machine. When you launch the application, the initial view is shown below.
Click the Get Runtimes button to get the Workflow Studio runtimes that are installed on the local machine. The runtimes are listed within the combo-box below and the name of the runtime specifies which account the runtime is running under.
When a runtime is selected, all of the workflows that are deployed on that runtime are listed as well. To execute a certain workflow, you need to know which runtime you deployed the workflow on. This sample application also provides the version of the workflow as you may have deployed two different versions of the same workflow to the same runtime. Using the version numbers helps you keep them straight.
When you want to execute a workflow, you need to know if that workflow requires any parameters. The workflow parameters are defined in the Workflow Studio Designer in the Global Properties section of the workflow. As mentioned above, Part 2 of this blog series goes into detail on how to define and use parameters inside a workflow.
When specifying workflow parameters inside the custom application, the parameter name is case sensitive. (Notice how I kept the parameter name as "gMessage"). If you mistype the parameter name or use the wrong case, you will get an error message when executing the workflow stating that the parameter name is not recognized. Just keep this in mind as you type the name of the parameters into the application.
Click the Execute Workflow button to execute the workflow. If the workflow was successfully executed, you'll get a pop-up message indicating success.
To verify the workflow was executed, you can open the Workflow Studio Console and check out the Jobs section.
Understanding the source code:
A lot of you out there will want to customize this application in your own environment. I developed this application with C# using Visual Studio 2008 and the Powershell SDK. Your development machine will also need Powershell 1.0 and Citrix Workflow Studio. For advice on setting up your Visual Studio environment, check out this article. If you follow the steps in that article, you'll just need to add the Powershell SDK and you should be all set.
The Powershell SDK is included as part of the Windows Software Development Kit. You can get information on the Poweshell SDK here. I downloaded the full ISO and it took me quite a while to get it. When you are ready to install, you don't need everything in the setup wizard. The Powershell SDK link provided above actually tells you what you specifically need to install to just get the Powershell SDK. To use the Powershell SDK inside your Visual Studio project, the project will need to reference System.Management.Automation.dll.
Once you get your development machine set up, you can open the solution that I provided above inside Visual Studio. Essentially all this custom application does is use the Powershell SDK APIs to execute cmdlets on Powershell. Since Workflow Studio provides Powershell cmdlets to automate various tasks, we can use the Powershell SDK to automate many Workflow Studio functions.
From my personal experience, using the Powershell SDK takes a little time getting used to. What I found to be helpful is to first write out the Powershell commands in Notepad and test them within Powershell to make sure they are functioning as expected. If you are working with Powershell variables, use the echo statement frequently to understand the current value of the variable. Then when you are ready to use the Powershell SDK in your Visual Studio project, you can convert each of your Powershell statements to the equivalent Powershell SDK code. In the source code that I provided for this custom application, I put comments into the code to explain what Powershell command I was trying to execute within that code block. Reviewing those comments should help you to get started with understanding how to use the Powershell SDK. For example, here is the ExecuteWorkflow() function that is used by the custom application. Stepping through this code inside Visual Studio and watching the variables is another great way to learn this code.
public string ExecuteWorkflow(Hashtable objFunctionParameters, Hashtable objWorkflowParameters) { try { //Declare local variables string l_strReturn = "Executing workflow"; string l_strWorkflowName = objFunctionParameters["WorkflowName"].ToString(); string l_strRuntimeName = objFunctionParameters["RuntimeName"].ToString(); Hashtable l_objWorkflowParameters = objWorkflowParameters; //Create a runspace containing the Workflow Studio snap-ins RunspaceConfiguration l_objRSConfiguration = RunspaceConfiguration.Create(); PSSnapInException l_objSnapInException = null; l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.Azman", out l_objSnapInException); l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.Core", out l_objSnapInException); l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.DataStore", out l_objSnapInException); l_objRSConfiguration.AddPSSnapIn("Citrix.WorkflowStudio.Installer", out l_objSnapInException); Runspace l_objRunspace = RunspaceFactory.CreateRunspace(l_objRSConfiguration); l_objRunspace.Open(); //Get reference to the Workflow Studio runtime that was passed in. //We are executing the Powershell command below: //$rt = Get-WorkflowRuntime -ServiceName $ServiceName Pipeline l_objPipeLine = l_objRunspace.CreatePipeline(); Command l_objCommand = new Command("get-workflowruntime"); l_objCommand.Parameters.Add("ServiceName", l_strRuntimeName); l_objPipeLine.Commands.Add(l_objCommand); Collection<PSObject> l_objCommandResults = l_objPipeLine.Invoke(); PSObject l_objRuntime = l_objCommandResults[0]; l_objPipeLine = null; //Get reference to the deployed workflow that was passed in. //We are executing the Powershell command below: //$workflow = get-deployedworkflow -workflowruntime $rt -workflowname $strWorkflowName -includeschedule l_objPipeLine = l_objRunspace.CreatePipeline(); l_objCommand = new Command("get-deployedworkflow"); l_objCommand.Parameters.Add("workflowruntime", l_objRuntime); l_objCommand.Parameters.Add("workflowname", l_strWorkflowName); l_objCommand.Parameters.Add("includeschedule"); l_objPipeLine.Commands.Add(l_objCommand); l_objCommandResults = l_objPipeLine.Invoke(); PSObject l_objWorkflow = l_objCommandResults[0]; l_objPipeLine = null; //Schedule the workflow to run immediately. //We are executing the Powershell command below: //schedule-workflow -workflowruntime $rt -workflowstrongname $workflow.WorkflowStrongName -workflowparameters $wfparameters -runimmediately l_objPipeLine = l_objRunspace.CreatePipeline(); l_objCommand = new Command("schedule-workflow"); l_objCommand.Parameters.Add("workflowruntime", l_objRuntime); l_objCommand.Parameters.Add("workflowstrongname", l_objWorkflow.Properties["WorkflowStrongName"].Value.ToString()); l_objCommand.Parameters.Add("workflowparameters", l_objWorkflowParameters); l_objCommand.Parameters.Add("runimmediately"); l_objPipeLine.Commands.Add(l_objCommand); l_objCommandResults = l_objPipeLine.Invoke(); l_objPipeLine = null; //Close the runspace l_objRunspace.Close(); //Return success l_strReturn = "Job completed!"; return l_strReturn; } catch (Exception objException) { //Initialize error message string l_strError = ""; l_strError = "An error has occurred. The error is \"" + objException.Message.ToString() + "\". "; return l_strError; } }
Blogs in this series:
Using Powershell to automate workflow execution within Citrix Workflow Studio
Passing parameters into a workflow within Citrix Workflow Studio
Automating workflow execution for Citrix Workflow Studio using a .NET windows application (this one)
Automating workflow execution for Citrix Workflow Studio using an ASP.NET web application
In the previous Provisioning Services High Availability Considerations blog, I spoke about placing your vDisks Local on the Provisioning Server. Now I will talk about placing your vDisks on a Windows Network Share.
Placing your vDisks on a Windows Network Share (CIFS)
Using a single Windows Network share (CIFS) to store the vDisks is a very easy way of implementing a central vDisk store at minimal cost.
What should we consider with this solution?
- There is no redundancy for file server outages (all PVS Target Devices stop responding).
- Limited scalability to support a increasing number of Target Devices.
- I/O for vDisk input (loading from the share) and vDisk output (delivering to the Targed Devices) is handled by the same network link. This affects the overall performance of the solution.
What are the recommendations?
- Network Interface Card (NIC) - Teaming should be used to increase the reliability and the I/O between PVS Servers, File Server and Target Devices.
- Where feasible dedicated NICs should be used for loading the vDisks and for delivering the vDisks to the Target Devices.
The following diagram outlines a basic Provisioning Services + Windows File Share (CIFS) architecture:

Elisabeth Teixeira.
Follow me on Twitter:http://twitter.com/lizteixeira
This is the second part of a four-part series on automating the execution of workflows within Citrix Workflow Studio. In the first blog of the series, I discussed the basics for using Powershell to automate the execution of workflows. In this blog, we will expand on that topic to discuss how we can pass parameters into the workflow, making our workflows much more dynamic and flexible for supporting different types of situations.
Understanding Global Properties
The key to passing parameters into a workflow is to use the global properties of the workflow. You access the global properties within the Citrix Workflow Studio Designer by navigating to Workflow->Manage Global Properties from the file menu (shown below).
The Manage Global Properties dialog allows you to specify the global properties of the workflow. Essentially, all you need to do here is to define the names of the global properties and their property type (String, Boolean, Integer, etc.). I personally like to pre-fix my global properties with the letter "g" to make them easily identifiable when assigning them to activities. You can also optionally define a default value for a global property if you want to.
Then within your workflow, you bind the global properties to the activities within the workflow. When you edit a bindable property for an activity, you'll get an editor such as is shown below. On the left-hand side, select Global Properties within the drop-down. The global properties should all be listed and easily identifiable by the letter "g" in front of the name (if you named them this way). Just select a global property and add it to the text editor to use it.
When global properties are defined for a workflow, you define the values of the global properties when scheduling a job within the Workflow Studio Console.
Creating a Powershell Script that passes parameters into the workflow
If you want to automate the execution of the workflow with Powershell, the Powershell script can also set the values of the global properties to pass into the workflow being executed.
To pass parameters into the workflow, the Powershell script will have a structure similar to below. This sample script shows how to pass two parameters into the workflow. What we are doing here is creating a hash table that represents the name/value pairs of the global properties. This hash table is then provided as a parameter into the schedule-workflow cmdlet. Please note that the schedule-workflow cmdlet should be all on one line (it was split on two lines here for better readability).
#Set variables for the workflow $strWorkflowName = "Workflow1" $strParam1Name = "Name1" $strParam1Value = "Value1" $strParam2Name = "Name2" $strParam2Value = "Value2" #Add the Workflow Studio snap-ins to the current Powershell session Get-PSSnapin -registered | Add-PSSnapin #Get reference to the Workflow Studio runtime $rt = Get-WorkflowRuntime #Get reference to the deployed workflow $workflow = get-deployedworkflow -workflowruntime $rt -workflowname $strWorkflowName -includeschedule #Create hash table of parameter values to pass into workflow $params = @{$strParam1Name = $strParam1Value; $strParam2Name = $strParam2Value} #Schedule the workflow to run immediately schedule-workflow -workflowruntime $rt -workflowstrongname $workflow.WorkflowStrongName -workflowparameters $params -runimmediately
Example:
To illustrate how the passing of parameters works, let's use the SQL Server Activity Library within our workflow. This is an activity library that you can download and leverage yourself for communicating with a SQL Server database. The beginning point of our workflow is shown below.
In this workflow, we are using the SQLExecute activity for executing an UPDATE command on a SQL Server database. The initial SQL UPDATE command is shown below. Since we are hardcoding the Employee ID and Phone Number into the SQL statement here, the initial usability of this workflow is pretty limited. It would be much better if we could make this SQL statement adaptable for different employee IDs and phone numbers.
To make this SQL statement more dynamic, we need to create global properties to represent the Employee ID and Phone Number. Notice the prefix "g" we are using to denote the global properties. This will make them easy to find when applying them to an activity.
Once the global properties are defined, we can use them within the SQLExecute activity. In the screen shot below, the SQL Command is updated to reference the global Employee ID and Phone Number properties created above.
Our workflow is pretty dynamic now. We can pass the Employee ID and Phone Number as parameters into the workflow. When the workflow is executed, it will use the passed in values as part of this SQL statement.
The Powershell Script to automate the execution of this workflow is shown below. Please note that the schedule-workflow cmdlet should be all on one line (it was split on two lines here for better readability).
#Set variables for the workflow $strWorkflowName = "Workflow1" $strParam1Name = "gEmployeeID" $strParam1Value = "101" $strParam2Name = "gPhoneNumber" $strParam2Value = "555-123-4567" #Add the Workflow Studio snap-ins to the current Powershell session Get-PSSnapin -registered | Add-PSSnapin #Get reference to the Workflow Studio runtime $rt = Get-WorkflowRuntime #Get reference to the deployed workflow $workflow = get-deployedworkflow -workflowruntime $rt -workflowname $strWorkflowName -includeschedule #Create hash table of parameter values to pass into workflow $params = @{$strParam1Name = $strParam1Value; $strParam2Name = $strParam2Value} #Schedule the workflow to run immediately schedule-workflow -workflowruntime $rt -workflowstrongname $workflow.WorkflowStrongName -workflowparameters $params -runimmediately
Final thoughts:
If you want to try out these Powershell scripts yourself, you'll need to follow the setup instructions as outlined in the first blog of this series.
In the final two blogs of this series, we are going to take these Powershell scripts to the next level by converting them to an actual C# program. As you'll soon see, you'll use the information contained in these first few blogs to understand how the C# programs actually work. Stay tuned!
Blogs in this series:
Using Powershell to automate workflow execution within Citrix Workflow Studio
Passing parameters into a workflow within Citrix Workflow Studio (this one)
Automating workflow execution for Citrix Workflow Studio using a .NET windows application
Automating workflow execution for Citrix Workflow Studio using an ASP.NET web application
In the first part of this blog series we looked at specific details on Citrix Delivery Center and the Disaster Recovery demonstration for SAP NetWeaver. In this posting we will cover different High Availability solutions also demonstrated at SAP. In addition to this blog series, please refer the Reference Architecture document that provides all the technical details about Citrix and Marathon solutions implemented for SAP.
Getting back to High Availability, Citrix XenServer and Marathon Technologies everRun VM for XenServer provide solutions that covers a broad spectrum of High Availability requirements ranging from maintenance to complete system-level fault tolerance. Given the breadth of High Availability solutions, IT administrators are bound to find a Citrix XenServer High Availability solution to meet their application availability needs.
When looking for an HA solution, various factors such as application criticality and business impact must be considered before choosing a particular solution for an application. A more detailed report on determining availability requirements can be found here.
In our Proof Of Concept environment at SAP, we showcased all levels of High Availability offered by XenServer and everRun VM. First let's look at the out-of-the-box High Availability solutions that XenServer alone delivers:
- XenMotion: XenMotion supports live migration of running virtual machines from one XenServer to another. The primary purpose of XenMotion is to prepare for planned server maintenance. The end user will not experience any interruption in application performance in XenMotion.
- XenServer High Availability (HA) - Level 1: XenServer HA provides High Availability by automatically restarting failed virtual machines on a different XenServer host within the same resource pool. The end user will experience an interruption in service as the virtual machine restarts.
In addition, Marathon Technologies everRun VM for XenServer provides High and Continuous Availability for critical virtual machines hosting business applications like SAP NetWeaver Portal:
- everRun VM for XenServer-- Level 2: Marathon Technologies everRun VM Level 2 delivers High Availability from component-level fault tolerance, eliminating downtime caused by I/O component failures and guaranteeing recovery from system failures. The solution identifies faulty I/O pathways before they become a problem and responds to a wide range of I/O and component failures. Active validation of all components on primary and secondary hosts ensures smooth recovery following any primary host component failure.
- everRun VM for XenServer - Level 3: Marathon Technologies everRun VM Level 3 provides Continuous Availability from system-level fault tolerance, eliminating data loss, downtime and transaction loss. It offers all of the benefits of Level 2 and adds two important attributes:
a. Zero downtime, even with complete XenServer host failure.
b. Preservation of application and memory states during failure.
The following video features the Marathon everRun VM Level 3 High Availability solution demonstrated at SAP Co-Innovation Labs, Palo Alto. Again, for more technical details on the implementation, please take a look at the Reference Architecture.
When you begin learning Workflow Studio, you quickly learn that the Workflow Studio Designer can execute workflows for initial testing purposes and the Workflow Studio Console can execute workflows as a scheduled job. A lot of people have been asking about how you can automate the execution of a workflow from an external system, such as Powershell, a Windows application, and an ASP.NET web application. The real power of Workflow Studio is being able to execute a workflow when you want it to run, either manually, on a schedule, or on-demand when needed by external systems.
This is the first blog of a new series I'm starting on how you can automate the execution of workflows from external systems, beginning with Powershell. One thing I didn't realize when I started using Workflow Studio was how much this product was connected to Powershell. Essentially, any action you can perform within the Workflow Studio Console has an equivalent Powershell cmdlet for it. Using these cmdlets allows us to automate the various tasks within the Workflow Studio Console, such as executing the workflows themselves.
Workflow Setup:
If you want to execute a workflow with Powershell, the workflow needs to be in the Ready state within the Workflow Studio Console. One thing that I prefer to do to keep the Powershell script fairly short is to pre-deploy the workflow to the Jobs section in the Workflow Studio Console. When you pre-deploy a workflow, you are just making it available to execute as a Job without actually executing it yet. By doing this simple step ahead of time, we can actually cut our Powershell script in half. Please note that this is just a one time step - once you deploy it to the Jobs section you really don't have to open the Workflow Studio Console again (unless you want to make changes to your workflow itself). The two screen shots below demonstrate how to pre-deploy the workflow to the Jobs section.
Registration of Xceed DLLs:
The Workflow Studio cmdlets leverage a few Xceed DLLs on the system. These Xceed DLLs are part of the Workflow Studio installation and need to be present within the global assembly cache (GAC) in order for several of the Workflow Studio cmdlets to run properly. Workflow Studio 1.1 does not actually place these DLLs into the GAC so you need to do that manually for this release. I was told in future releases that this step will already be done for us.
There are three Xceed DLLs you need to place into the GAC: Xceed.Compression.dll, Xceed.FileSystem.dll, and Xceed.ZIP.dll
Drag these DLLs from the C:\Program Files\Citrix\Workflow Studio folder to the C:\Windows\Assembly folder. This process adds them to the GAC. The end result is shown below.
Powershell Setup:
An interesting thing to note about Powershell is that scripting is turned off by default. You can't execute a Powershell script until you enable scripting at a desired level. I'm not exactly sure why Microsoft chose to do that since Powershell is supposed to be a scripting language, but it is fairly easy to enable scripting.
Launch Powershell (Start->Programs->Windows Powershell 1.0->Windows Powershell) and type the following command to get the current execution setting:
Get-ExecutionPolicy
If the execution policy is set to Restricted, you need to enable script execution by typing the following command:
Set-ExecutionPolicy RemoteSigned
Powershell Script:
The table below is a sample Powershell script for executing a workflow on your Workflow Studio machine. I've tested the Workflow Studio cmdlets pretty extensively and this seems to be the simplest script I was able to create to execute a workflow.
To use this script in your environment, just copy and paste this script into Notepad, and rename the file as a .PS1 file. Then update the value of the $strWorkflowName variable to be the name of the workflow you want to execute. In my next blog, I'll explain how you can tweak this script to pass parameters into the workflow. The script below will work for any workflow that does not require parameters.
#Set variables for the workflow $strWorkflowName = "Workflow1" #Add the Workflow Studio snap-ins to the current Powershell session Get-PSSnapin -registered | Add-PSSnapin #Get reference to the Workflow Studio runtime $rt = Get-WorkflowRuntime #Get reference to the deployed workflow $workflow = get-deployedworkflow -workflowruntime $rt -workflowname $strWorkflowName -includeschedule #Schedule the workflow to run immediately schedule-workflow -workflowruntime $rt -workflowstrongname $workflow.WorkflowStrongName -runimmediately
Executing the Powershell script:
After the PS1 file is created, place it within an accessible place on your Workflow Studio machine. For example, I've placed my scripts within C:\Citrix\PowershellScripts. One thing I found out is that you want the path to the script to have no spaces, so keep that in mind as you place your PS1 file into a directory.
Next, open the Run window and type the statement below to execute your Powershell script (my script was called ExecuteWorkflow.ps1)
powershell.exe -noexit C:\Citrix\PowershellScripts\ExecuteWorkflow.ps1
The -noexit switch above keeps the Powershell window open after the script is executed. If the script execution was successful, you should see a Job ID as noted below. This tells you that the workflow was successfully executed.
Troubleshooting the Powershell script:
If you are having issues with your Powershell script, the approach I typically take for troubleshooting is to launch Powershell and execute each line of the script manually until you come across the error. Powershell can be launched from the Start Menu (Start->Programs->Windows Powershell 1.0->Windows Powershell) or by typing Powershell.exe in the Run window.
If you receive Access Denied errors, there is a good chance that the account you are running Powershell under is not a Workflow Studio admin, or does not have permissions within Workflow Studio to execute various workflow actions. Check that your logged on user account is either a Workflow Studio admin or has these permissions. These permissions are set inside the Workflow Studio Console within the Security section.
Most of the commands in the script above use variables. To see the value of a variable, use the echo statement. For example:
echo $strWorkflowName
If the variable is an object, you can also display the value of its individual properties. For example:
echo $workflow.WorkflowStrongName
If you want to see the list of all the Workflow Studio cmdlets, use this statement:
Get-Command -PSSnapin citrix*
The output of the above statement is shown below:
If you want more information on how to use a specific Workflow Studio cmdlet, use a statement such as this:
Get-Help schedule-workflow
Blogs in this series:
- Using Powershell to automate workflow execution within Citrix Workflow Studio (this one)
- Passing parameters into a workflow within Citrix Workflow Studio
- Automating workflow execution for Citrix Workflow Studio using a .NET windows application
- Automating workflow execution for Citrix Workflow Studio using an ASP.NET web application
I have been working with Provisioning Services (PVS) for a while and one of the questions that keep coming up is around Provisioning Services High Availability (HA).
What is HA? Maintaining access to a service or resource is probably the best explanation for this type of functionality.
What does HA provide? Within the context of the Provisioning Services resource, we are referring to the target devices ability to maintain an active connection to a vDisk. This is different to redundancy, which I will cover in another topic. This ability manifests itself in the customers' expectation for the target device to maintain constant uptime. What we have seen in the latest release is instant availability (first error move to next PVS server providing vDisk) as opposed to failover if the system doesn't recover itself.
Types of HA: There are many ways of doing it, they all work, but which one is right for you? That depends. Let's take a look at the location of your vDisks.
Placing your vDisks Local on the Provisioning Server - "Distributed Store":
Using the local hard disk subsystem of the Provisioning Server to store the vDisks provides the easiest way of implementing vDisk High Availability without additional cost.
What should we consider with this solution?
- Although it is easy to implement and maintain vDisks need to be manually synchronized between the PVS Servers.
- I/O performance depends on the capabilities of the hard drive subsystem (usually equal to NAS).
What are the recommendations? Network Interface Card (NIC) - Teaming should be used to increase the reliability and to I/O between PVS Servers and Target Devices. You can also add more PVS streaming servers and heavier reliance on load-balancing.

You might be thinking about the vDisk lock files. Would failover work properly redirecting the target device to another server without a vDisk access failure? Yes, vDisk locks should not be a problem. Let's say you are using the vDisk in Private Image mode, the lock file holds the information of the Target Device accessing it. If it fails from Server 1 to Server 2, Server 2 should not have an associated lock file yet because no other vDisk has accessed it. It will then create a new one. If it fails back over to Server 1 from Server 2, the lock file will have the Target Device information and re-connect it. If you are using the vDisk in Standard Image mode the lock files should not prevent any read only access.
Now you might be concerned about the write cache. Server Side caching is not supported, unless the cache is re-directed to a share. If cache is being stored on the Server's local drive and becomes unavailable after failover, the Target Device will eventually blue screen when it tries to access needed information on the cache file.
Elisabeth Teixeira.
Follow me on Twitter: http://twitter.com/lizteixeira
I just recently posted a SQL Server activity library to the Citrix Developer Network (CDN). The SQL Server activity library allows you to execute SQL statements (SELECT, INSERT, UPDATE, DELETE, etc.) on a Microsoft SQL Server database as part of a workflow within Citrix Workflow Studio. The activity library, setup instructions, and full source code can be downloaded here.
I actually needed this type of library for a Workflow Studio project I'm currently on. I coded the activity library to be general enough for anyone to use within their own environments. The environment I've been using with this activity consists of Workflow Studio 1.1 and SQL Server 2005. I haven't tested with other versions of SQL Server, but I am providing the full source code to this library in case you need to tweak anything.
There are two activities within the SQL Server activity library:
- SQLSelect activity - used to run SELECT queries on a database. The output of this activity is a collection containing the query results. Since the output is a "collection" type object, you can loop through this collection within Workflow Studio using the For Each Object activity and dump the collection contents to an XML file via the ExportToXML activity.
- SQLExecute activity - used to run INSERT, UPDATE, and DELETE queries on a database. The output of this activity is a string containing the number of records affected by the SQL statement.
There are five properties that need to be set on the SQLSelect/SQLExecute activities:
- Database Server - SQL Server machine hosting the database
- Database Name - Name of the database to connect to
- SQL Command - SQL statement to execute on the database
- SQL Username - SQL Server username for connecting to the database
- SQL Password - SQL Server password for connecting to the database
The SQL Command property will be set differently based on which SQL activity you are using. The SQLSelect activity will expect a SELECT statement here. The SQLExecute activity will expect an INSERT, UPDATE, or DELETE statement here (essentially any non-SELECT query).
The SQL Server activity library was developed using the Workflow Studio SDK:
If you need to review the code and make changes, I highly recommend reviewing my previous blog series on using the Workflow Studio SDK. This blog series will help you get your Visual Studio development environment up and running so you can make changes to the code.
For the programmers out there, the activities themselves leverage the standard ADO.NET objects for connecting to a SQL Server database and executing a command. If you are familiar with ADO.NET, then the code should be fairly straightforward to walk through.
Finally:
When you check out the CDN you'll see the full setup and usage instructions so I didn't restate them here. The SQL queries you execute can be static (using hard-coded values) or dynamic (based on the bindable properties of other activities within the workflow). This makes this activity pretty flexible to use in any kind of situation or query you may encounter. Have fun and I hope this helps you out as well!
I am very excited to announce the release of a Reference Architecture for an enterprise XenDesktop environment. Many times when you see reference architectures, the paper is very high-level and provides minimal details. Well, this document is completely different. It is based on a customer environment with 10,000 users spread across four data centers. It includes many of the challenges we architects must design around including, multiple data centers, worldwide design, thousands of users, remote users, etc.
The design focuses on the following topics:
• Virtualization Infrastructure
• OS Delivery
• Application Delivery
• Desktop Delivery
• Desktop Design
• Business Continuity
Within the subsections, you can read about the environment design, capacity planning, hardware design and storage design as well as a host of other items. As this is based on a customer environment, some details had to be removed and generalized.
As you read through the document, you might think "Why did they do it that way?" Where possible, we tried to follow best practices, but with any environment, the nuances required we deviate from the preferred path to alternate paths. You will probably have questions, comments and challenges with the way we designed the environment, which is why I'm going to start a blog series around the key design areas so all of you can comment and we can discuss. Should be an interesting series. Make sure you grab the design document (CTX121478), and Stay Tuned...
Daniel - Lead Architect - Worldwide Consulting Solutions
Follow me on Twitter: http://www.twitter.com/djfeller
Follow me in the Blogs: http://community.citrix.com/blogs/citrite/danielf
In Provisioning Services for XenApp Best Practice #5, I wrote about application streaming integration. I talked about two different options:
1. Stream on-the-fly: which results in the vDisk write cache growing as the application is streamed
2. Pre-cache: which stores the application cache within the vDisk, but helps to reduce the size of the vDisk
Both of these options had their issues. Option 1 would grow your write cache quickly, especially on XenApp servers hosting tons of applications. Option 2 creates a link between the vDisk and applications, which adds another step to application updates.
I received many suggestions and alternatives, some were quite interesting
. The one that resonated the most was to store the application streaming cache on another disk that is not delivered via Provisioning services.
- Physical Servers: You would use the physical disks installed into the physical servers
- Virtual Servers: You would use a virtual disk assigned to the virtual machine (preferably shared storage so you can still do XenMotion).
This setup doesn't really change our architecture in that many implementations have a non-Provisioning Services disk associated with each server to store items like event logs, local databases, write cache and pagefile (as explained in BP 8?).
Honestly, I haven't had the opportunity to set up an environment like this in a large environment, so I didn't want to offer it as a best practice yet. But I've had many of you say that this is about the only way you deliver XenApp images with Provisioning Services and have had no issues with the environment from configuration or maintenance. I've always thought this provided the best solution as it overcomes many of the lingering challenges of option 1 and option2. So, how do you do this? It is actually pretty easy:
- Make sure you have an NTFS disk associated with the physical server (physical disk) or virtual server (virtual disk)
- With the Provisioning Services image in private-image mode, change the location of the Application streaming cache location
- Launch C:\Program Files\Citrix\Streaming Client\ClientCache.exe
- Change the client cache directory to the virtual or physical disk
- Shut down and place vDisk back into standard image mode

When you boot, and launch your applications, your application cache is now stored on the physical/virtual disk that is not erased during reboot. What does this get you?
- Faster application launch after server reboots because the application cache is not erased
- Easier application maintenance because the application cache is not included within the vDisk
But this configuration does come at a price. You have to have a persistent disk associated with each physical and virtual server. Although this cost is pretty small as most Provisioning Services/XenApp implementations already have a local disk to store local monitoring databases, event logs, etc.
My list is now empty, but will post new topics as they come in. Feel free to tweet me some ideas on Twitter.
- vDisk Type
- vDisk Cache
- Active Directory
- Application Integration
- Application Streaming Cache
- System-level settings: Page file, drive remapping and multiple drive
- Image Management
- Local Database Storage (event viewer, EdgeSight, AntiVirus updates)
- Plus more
By the way, if you haven't done so already, take a look at the Provisioning Services for XenApp TechTalk presented by yours truly. I'm a little biased, but I think it is a good one.
Daniel - Lead Architect - Worldwide Consulting Solutions
Follow me on Twitter: http://www.twitter.com/djfeller
Follow me in the Blogs: http://community.citrix.com/blogs/citrite/danielf
Provisioning Services (PVS) solves many of the existing problems of datacenter and desktop administrators by reducing the number of unique images that need to be managed. Rather than dealing with application installs, conflicts, patches and errors on hundreds of different servers and/or desktops, they can deal with a single streamed golden image that remains pristine regardless of the changes made by users.
However, even though this new approach solves many of the issues that have been plaguing IT administrators for years, a new concern comes up. In my role on the Consulting Solutions team, I've been asked the same question by clients and coworkers alike: "If I have a pristine, unchangeable image, how do I deal with antivirus updates and patching?"
The admin guide (page 109) gives detailed instructions on how to do exactly that. It goes, on a high level, something like this:
- Load a machine with a copy of the production vDisk in private mode
- Make your updates
- Shut it down and put it into standard mode
- Finally, increment the version number
It's simple, and the process is easy to do manually - if you only have to add updates to a single vDisk every once in a while, then there's no problem. However, Microsoft comes up with security updates on an almost weekly basis, and new anti-virus definitions come out nightly - most companies aren't comfortable leaving machines unprotected for extended periods of time, and IT administrators don't want to spend time doing a manual, repetitive task on a daily basis. Add in a few different vDisks for different workloads, and this can quickly grow into a time consuming process. How do we reduce the time-cost of keeping vDisks fully updated?
Enter Workflow Studio. Workflow Studio (WFS) is designed to reduce repetitive tasks into easy-to-manage workflows that can be run either on-demand or on a scheduled basis. Using Workflow Studio and PVS's built-in CLI, we're able to create a script that automates the entire process of updating vDisks, allowing for easy nightly or weekly scheduling with less chance for human error.
In order to be device/hypervisor agnostic, the script utilizes an always-on machine designated as an "update" machine, which allows PVS to use its own functionally to restart the machine when necessary. Updates can come in and automatically be implemented during the course of the day or week, and applications can be added or removed by any vDisk admin. Then, at the scheduled point or on a manual call, the script shuts down the server, makes a copy for future updates, and switches out the disks using the Auto-Update feature. After the next reboot, desktops will switch to the newest disk, no additional manual intervention required.
Additionally, the "update" machine can be given a "personality" that then executes scripts inside the image that aren't run on other machines - such as perhaps automatically copying files from a share, or enabling Microsoft's Auto-Update, or any number of other actions. Workflow Studio is a component of making the script function appropriately, and it has the added benefit of allowing role-based access to the Workflow, as well as built-in scheduling. However, if Workflow Studio cannot be deployed, then the components of the script can be broken apart and used solely with Windows Scheduler.
Grab the script at the Citrix Developer Network. If you have questions, comments, or ideas for improvement, leave me a comment or ping me on Twitter @mcbogo.
Best,
Michael Bogobowicz
Senior Consultant @ Citrix Consulting Solutions
One of my biggest gripes about Terminal Services and XenApp was that once I disconnected from the network, I could no longer use my applications. This was a major pain as I spent a lot of time on airplanes. During my 3-4 hours flights as well as 1-3 hrs sitting in the terminal, I was unable to get any work done (although I did get a lot of reading done). My problems with XenApp wasn't just limited to airports and airplanes, but also included remote connectivity. As I'm a remote employee, I spend most of my time working from my home office. There were many cases where I just wanted to spend 1 minute to look something up in a local file. But because my applications are hosted from XenApp, that 1 minute actually took 3-5 minutes (authenticate to employee portal, launch XenApp application, open file and wait for the file to be transferred from local workstation to XenApp server).
I got frustrated and installed my applications locally. This was wonderful. All of the frustrations I've had were almost gone. But this now caused new challenges. I now had to manage and maintain my applications. I had to install appropriate hotfixes/service packs. I also had to troubleshoot application issues, not something I enjoy doing. (Why does it always seem like your applications fail when you need to use them the most?) Well, believe it or not, XenApp actually allows offline access to your applications. You get to use your XenApp applications while your network is not connected, while you have absolutely no connection to the XenApp infrastructure. This sounds like a good deal. I get local usage and I don't have to worry about maintenance.
How does it work? How do you implement it? What best practices should be followed? All of these questions are the basis for an upcoming TechTalk on offline mobility with XenApp. In this TechTalk session, you'll learn about:
• How XenApp users can take their applications with them, disconnected
• How offline XenApp users are kept current
• How to eliminate app conflicts without stress
• How to follow the best practices while delivering offline applications
• How application streaming can help simplify your Vista and Windows 7 migration
Hope to see you at this TechTalk on Friday, June 5th at 1PM Eastern time.
Daniel - Lead Architect - Worldwide Consulting Solutions
You can follow Daniel at http://twitter.com/djfeller
You can read Daniel's blogs at http://community.citrix.com/blogs/citrite/danielf
XenApp admins are a creative group of people. I used to be a XenApp admin and I remember having to do tons of things to an application to get it working correctly on XenApp (but back then it was called WinFrame and MetaFrame, not even MetaFrame XP). Back in the day, applications were not built to execute on a multi-user system like XenApp. In fact, many applications today, especially those home-grown applications, are problematic on XenApp. This is where the creative XenApp admins come in. They developed numerous tweaks, configurations, hacks and custom solutions in order to get an application functioning properly. Of course this made the environment much more complex to build and maintain.
But just getting applications functioning on XenApp is just part of the problem. I remember hearing people ask about running different high-graphics or video applications on XenApp and thought, ARE YOU NUTS? ICA was built to only send those screen changes down to your video display, but with video the entire screen is changing. Talk about chaos.
THAT WAS THEN. THIS IS NOW. Things have changed for the better. Application issues are more of a myth nowadays. With new XenApp features, many of the application challenges that plagued XenApp environments are being eradicated. But unfortunately, many of you have experienced application issues years ago and haven't looked at those applications since. So I'm asking that we spend an hour going through the XenApp features focused on application compatibility in an upcoming TechTalk session.
I plan to discuss the technologies that make application compatibility easier, which will also help simplify your XenApp architectures. We will go through many of the challenges you all have experienced and talk about how these are now easily overcome. So I encourage you to attend this TechTalk session called: Fact vs. Fiction - The Truth About Application Compatibility and XenApp.
Can't wait to see you there on Wednesday, May 27, 2009 at 1PM eastern time.
Daniel - Lead Architect - Worldwide Consulting Solutions
"Learn from the past, live in the moment, and plan for the future"
Follow me in the blogs: http://community.citrix.com/blogs/citrite/danielf
Follow me in Twitter: http://www.twitter.com/djfeller
After attending Citrix Synergy last week, I wanted to come back and complete this 5 part series that I started before the conference began. In the last article (Part 3), I discussed the anatomy of a Workflow Studio project. The information in that article should help you get started in coding your activities. Next on the list is to discuss how to test your activity project within Workflow Studio once you've completed a bulk of the code in Visual Studio.
If you want to follow along with me, you should create the AdvancedDelay activity project as outlined within the Workflow Studio Developers Guide. The AdvancedDelay activity inserts a delay into your workflows for a specified amount of time. As discussed in the Developers Guide, the code that you add is pretty straightforward. You are just adding a property to specify the delay time and a sleep command in the execution section to perform the actual delay.
To make the testing process simple, I'll break it up into the following sections. Each section is discussed in more detail below.
• Before you begin
• Build your solution in Visual Studio
• Copy the activity DLL to the Workflow Studio activities folder
• Launch Workflow Studio and create a new workflow project
• Add the activity to the workflow project and run/test the workflow
Before you begin
Before you compile your project, you should check out a few settings that are placed at the top of your activity file. If you are following the AdvancedDelay example, open the AdvancedDelay.cs file and check out the activity settings at the top.
• DisplayNameAttribute - this is the name of the activity as it will appear in the Workflow Studio Designer.
• ActivityTreePath - this is the location that the activity will be placed in within the Workflow Studio Designer activity pane. In the example below, I'm placing this activity within the General/Custom Activities folder. You can place this activity anywhere in the activity pane.
Build your solution in Visual Studio
You build the solution like any other Visual Studio project. Just navigate to Build-->Build Solution in the file menu. Verify that the build succeeds within the Output window at the bottom of Visual Studio.
Copy the activity DLL to the Workflow Studio activities folder
After you compile the project, a DLL is produced that contains your activity project code. This DLL is typically found in a sub-directory where your Visual Studio project resides on the system. In my environment, this DLL was found in my user profile since my Visual Studio projects are all written to my user profile ("C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\ProjectsAdvancedDelay\AdvancedDelay\bin\Debug").
Copy the activity DLL (AdvancedDelay.dll in this example) and paste into "C:\Program Files\Citrix\Workflow Studio". Your DLL will need to be here in order for Workflow Studio to use it.
Note: If your project happens to reference other 3rd party DLLs that you added manually to the project (for example, mfcom.dll for tying into XenApp), you'll need to add these extra DLLs to the above folder as well. This allows the Workflow Studio Designer and Runtime to pick up these references to allow you to run the activity. In our example here, our AdvancedDelay activity project is pretty simple and we didn't add a reference to another 3rd party DLL so we can bypass this action.
Launch Workflow Studio and create a new workflow project
With your activity DLL now in the right location, launch Workflow Studio and create a new workflow project. I typically like to create new workflow projects for testing activities, but you can also edit existing workflow projects if you desire.
Add the activity to the workflow project and run/test the workflow
The Workflow Studio Designer should now be displayed. If this is your first time testing the activity, the activity will not yet be displayed within the activity pane. To add the activity as an available activity within the pane, navigate to Tools-->Choose Activities. Browse to the activity, verify it is selected, and close the Choose Activities dialog. Notice the "Toolbox Location" field on this dialog. This is the location we specified in our code where this activity will be placed within the activity pane.
Verify the activity is now listed within the activity pane. Drag the activity to the designer surface and configure the properties as needed. Start the activity and verify that it runs as expected.
In the example below, I configured the AdvancedDelay activity to run for 5000 milliseconds (5 seconds). I then placed a message box beneath the delay. When running the activity, it should take about 5 seconds for the message box to pop up. If it does, I know this activity is running as expected.
One final note:
If you find that you need to make code changes to your activity, just open up Visual Studio, update your code, and recompile your project. You'll then need to place the updated DLL back in the C:\Program Files\Citrix\Workflow Studio folder in order for Workflow Studio to pick it up. If you get an "Access Denied" type message, this typically means that you'll need to close Workflow Studio (Console and Designer) in order to successfully overwrite the existing DLL that is in that location. The Workflow Studio executables will have a lock on that DLL if you just used a previous version of that DLL in a workflow.
Once you can copy the updated DLL to that location, re-open Workflow Studio, and edit your workflow project. When you edit your project, your workflow will automatically be referencing the new DLL. You don't have to re-browse for the activity and add it to the activity pane. Make the appropriate property changes and workflow changes and re-execute your workflow.
In the next blog, I'll explain how you can step through your code in real-time in case you wanted to perform more robust troubleshooting at this stage. Stay tuned!
Blogs in this series:
• Getting Started
• Setting up your Visual Studio development environment
• Anatomy of a Workflow Studio activity project
• Testing your Workflow Studio activity project (this one)
• Stepping through your Visual Studio code
The whole concept of a standard image used across multiple end points is a great idea. Think about it, 1 image for hundreds/thousands of servers. Talk about simplicity. I only have to make updates once and every server has the same update. Every server is identical. This makes scaling up the environment easy. Of course there are some challenges, as many of you have pointed out after my very first blog posting where we spoke about vDisk type. That challenge is that the "write cache" is destroyed upon server reboot.
For the most part, this is a good thing. Those changes gives each XenApp server a personality. I don't want my XenApp server to have personalities. Its kind of like running Microsoft Word one day and it is using United States English and then the next day it uses United Kingdom English. This little personality change doesn't seem to be a big deal, but it is. For example, I like my words to use the letter Z. I believe you spell color without the letter U. I believe neighborhood is spelled without the letter U too. Of course this is a simple change for a user, but we shouldn't make our users do this. But there are some changes on XenApp servers which are valuable (many of you have pointed them out to me) like event logs and performance metrics.
So how do I use a standard image but still allow these important items to remain persistent across server reboots? Some of you have raised good points on this, especially around the use of differential disks, but the problem with differential disks is that the differential cache will go away if the base vDisk is changed. So, differential disks do not really help us out that much. What we can do instead, which again some of you alluded to, is to use a local disk.
Now I bet some of you have alarms going off in your head and are thinking, "Hey, I thought the benefit of Provisioning Services is that I don't need local disk". Well, you are 100% correct, that is one of the benefits, but there are more like standardization and synchronization but will leave that for a marketing-type blog. But with standard images you do lose some items like persistent storage of event logs, metric databases, etc. But if we allocate a local disk to the server, we can redirect the storage of the persistent data. BTW, this works when XenApp is virtualized on XenServer and when XenApp is on bare-metal.
You do this by doing the following:
- Your virtual machine must have 2 virtual disks assigned. Remember if you want to do XenMotion, the second virtual disk must be on shared storage. How large you might ask? For XenApp, a 4GB partition is a good starting recommendation, but with most decisions, it depends.
- Build XenApp on the first disk and format the second disk NTFS so it shows up in your system (use basic disk and not dynamic).
- Change the storage paths of your persistent databases, event logs and anything else to the second virtual disk.
- Build your vDisk from the C drive, but not the second drive. When done, shut down the virtual machine.
- Detach the OS virtual disk from the virtual machine, but leave the second virtual disk attached.
- Clone the virtual machine including the virtual disk.
- Now stream the vDisk image to this new virtual machine. Your event log should be stored on the virtual disk instead of within the write cache.
So now we are using a base vDisk for our image and still allowing persistent data storage. And what's more, you can also use that persistent disk to be the write cache storage location as well. Just tell Provisioning Services to store the write cache on local storage, and the persistent disk will hold that information for the server's session.
My list is now empty, but will post new topics as they come in. Feel free to tweet me some ideas on Twitter.
- vDisk Type
- vDisk Cache
- Active Directory
- Application Integration
- Application Streaming Cache
- System-level settings: Page file, drive remapping and multiple drives
- Image Management
- Local Database Storage (event viewer, EdgeSight, AntiVirus updates)
- Plus more if we get some good ideas on other areas of focus.
By the way, if you haven't done so already, take a look at the Provisioning Services for XenApp TechTalk presented by yours truly. I'm a little biased, but I think it is a good one.
Daniel - Lead Architect - Worldwide Consulting Solutions
Follow me on Twitter: http://www.twitter.com/djfeller
Follow me in the Blogs: http://community.citrix.com/blogs/citrite/danielf
When we talk about the Citrix Delivery Center, we are talking about an end-to-end application delivery infrastructure solution. A solution which represents a family of Citrix product lines: Citrix XenServer, Citrix XenApp, Citrix NetScaler and Citrix XenDesktop. It also represents products that add integrated security, management and networking functions, products such as: Citrix Access Gateway, Citrix Branch Repeater and Citrix Desktop Receiver. Overall, the Citrix Delivery Center gives customers the power to adopt virtualization that meets their specific requirements. Customers can choose to optimize delivery of their Web Applications, Windows Applications, Desktop Delivery, Data Center Optimization - individually or in combination. How about all of them?

Now according to a recent Forrester study "49% of enterprises surveyed that are implementing or interested in virtualization solutions indicate that improving disaster recovery/business continuity continues to be a very important motivation for adoption". So what better way to pique their virtualization/business continuity interest than by demonstrating an end-to-end Citrix and Marathon combined solution onsite at the world's largest business software company SAP.
Recently the Citrix Worldwide Consulting Solutions and Business Development teams did just that. We built and demonstrated a Proof of Concept environment that delivered a highly available and virtualized SAP infrastructure using a complete Citrix Delivery Center solution. Within a two week period, the Citrix, Marathon, and SAP teams built and demonstrated a complete Proof of Concept environment. For a quick project overview please refer the data sheet here.
So how did we do it....First we virtualized every Citrix Delivery Center component and the backend SAP NetWeaver application servers using Citrix XenServer. Then we showcased what a remote SAP NetWeaver user would experience accessing the SAP NetWeaver Portal via Citrix Delivery Center while focusing on the high availability/fault tolerant solutions Citrix and Marathon provide. Finally, we simulated a complete failure in the primary site and used the combined NetScaler Global Server Load Balancing feature in conjunction with Marathon's everRun DR product to failover SAP to a secondary data center.
Let's go through the steps that describe the demonstrated user experience:
- Remote SAP NetWeaver Portal user securely connects to the SSL VPN provided by Citrix Access Gateway Enterprise Edition.
- All connections from the remote user client are accelerated using Citrix Branch Repeater Plug-in.
- Remote user is seamlessly presented with the Citrix Web Interface website with on-demand access to virtual desktops, applications, bookmarks and other corporate resources.
- From the Citrix Web Interface page, the remote user launches a virtual Windows XP desktop hosted by Citrix XenDesktop. This desktop is a private virtual image of Windows XP running within a secure data center and maintained from a centralized Windows XP image provisioned dynamically with Citrix Provisioning Server.
- From the secure virtual Windows XP desktop, the remote user launches a published SAP NetWeaver Portal delivered by Citrix XenApp. The published NetWeaver Portal application is separated from the virtual Windows XP Operating System allowing optimal user performance.
- As the remote user navigates the application, all SAP NetWeaver Portal connections pass through a Citrix NetScaler configured to optimize SAP NetWeaver Portal application delivery.
We also demonstrated the following high availability and recoverability solutions provided by Citrix XenServer and Marathon everRun software:
- Level 1: XenServer delivers out-of-the-box high availability, including cost-effective core failover, recovery and restart capabilities for SAP applications running in the virtual environment.
- Level 2: Marathon everRun VM delivers high availability of component-level fault tolerance, eliminating downtime caused by I/O component failures and guaranteeing recovery from system failures.
- Level 3: Marathon everRun VM's Lockstep Technology delivers continuous availability from system-level fault tolerance, eliminating data loss, downtime and transaction loss.
- Disaster Recovery: Marathon everRun DR provides a robust and flexible remote disaster recovery solution providing automated and reliable long-distance protection for critical data and applications, in this case, SAP.
Each piece of the demonstration was broken down into small video segments for this blog. The first video features the Citrix Delivery Center environment for SAP from top to bottom including the remote user login, virtual desktop access, and SAP NetWeaver Portal launch. Then a complete site failure is simulated and the secondary site recovery is shown using Marathon's everRun DR solution with Citrix NetScaler's Global Server Load Balancing feature.
Stay tuned for a detailed reference architecture and video blogs on different High Availability scenarios including everRun VM also demonstrated at SAP Co-Innovation Lab.
Here's the video:
When you create a new Workflow Studio activity project within Visual Studio, the templates provide you with a pretty comprehensive and documented activity class file. In the screen shot below, I minimized a lot of the code, but you can see the primary sections of the activity file within the project.
The primary sections of this file are listed below:
- Using statements
- General activity properties
- Class constructor
- Standard properties
- Dependency properties
- Activity execution section
- Property validation section
In this blog, I'll discuss at a high level each of these primary sections. I won't detail the meaning of all of the attributes and properties that are present as they are pretty well documented within the Activity Developers Guide and within the comments of the class file itself. This blog is really meant to give you an overview of what is actually in here so you can navigate to the appropriate section as you develop your activity.
1. Using statements:
There is a long list of using statements at the top that define the references for the class. What you should notice here is that the last five all come from Workflow Studio. If your activity references a third party DLL, you'll most likely need to add more using statements to make sure your references are all in place.
using Citrix.WorkflowStudio.Common;
using Citrix.WorkflowStudio.CustomActivities.Designers;
using Citrix.WorkflowStudio.CustomActivities.Editors;
using Citrix.WorkflowStudio.CustomActivities.Serializers;
using Citrix.WorkflowStudio.User;
2. General activity properties:
Right beneath the using statements is a section called "Attribute Definitions and Comments". This section contains a series of general properties for the activity. The comments provided within this section explain these settings pretty well. A few of them you should take note of are below.
[DisplayNameAttribute(@"AdvancedDelay")]
This is the name of the activity displayed within the Workflow Studio Designer.
[Description(@"This activity will delay for a specified amount of time")]
This is the description of the activity displayed within the Workflow Studio Designer. When you select the activity in the Activity pane, the description is shown in the lower-left corner of the Designer.
[ActivityTreePath(@"Windows PowerShell/Utilities")]
This is the folder location for where the activity is placed within the Activity pane of the Workflow Studio Designer. A forward slash is used to specify a subfolder.
3. Class constructor:
The class constructor is next. This code gets executed when the activity is placed on the drag-and-drop surface within the Designer. The most common thing you'll need to do in the constructor is to initialize the values of your properties.
4. Standard properties:
The section for standard properties is listed after the class constructor. A sample one is provided in the template which is commented out. This sample is mainly here to give you the syntax for defining a sample property if you would like to use one within your code.
What you really need to know is that there are two types of properties you can define within the class - standard properties and dependency properties. The primary difference between them is that dependency properties are "bindable" to other activities whereas standard properties cannot be bound. Dependency properties have much more flexibility than standard properties due to being bindable. In the Designer, bindable properties allow their values to come from other activities. Bindable properties can also be used as input to properties of other activities. Due to this flexibility, dependency properties are much more common to use than standard properties and you should probably define all of your properties as dependency properties first, then fall back to being standard if the bindable behavior is not desired.
5. Dependency properties:
The dependency property section is listed after the standard property section. As stated in the section above, dependency properties are much more common to use than standard properties since they can be bound to the properties of other activities. Their flexibility makes them a much better choice in most cases.
The activity template gives you a series of sample dependency properties that are commented out. I won't go into all of the code for this property here (it's explained pretty well within the Activity Developers Guide). I'll just highlight a portion of the settings here...
[DefaultValue("0")]
This is the default value of the property. Default values can also be set within the class constructor. When using the Workflow Studio Designer, if the property value is ever set to something different than this default value, the value is shown as bold within the Designer to indicate it has changed.
[DisplayName(@"DelayTime")]
This is the name of the property as shown within the Workflow Studio Designer. This name should be intuitive and easy for admins to understand.
[Description(@"Amount of time to sleep in ms")]
This is the description of the property as shown within the Workflow Studio Designer. When you select the property in the Designer, this text is shown in the lower-right corner of the Designer.
[Browsable(true)]
This setting defines whether this property is visible within the Workflow Studio Designer. If set to true, it is displayed within the Designer when the activity is selected. If you don't want admins to know about this property or see it within the Designer, you can set browsable to false.
[InputAttribute]
A property can either be an input property or output property. Input properties define some value that is inputted into the activity. Output properties define something that is returned by the activity after the activity is executed. The use of the [InputAttribute] or [OutputAttribute] declaratation defines what icons should be used for this property in the Workflow Studio Designer.
6. Activity execution section:
After all of the properties are defined, the next section is the Execute() function. This function gets called when the activity is executed by Workflow Studio. All of the execution logic should go into this function.
The Execute() function provides a try/catch block. Put all of your execution logic in the try block. Don't touch the ExpandStringProperties() call at the top as this function will dynamically retrieve the property values set within the Workflow Studio Designer at runtime so that you can use them within the try block.
7. Property validation section:
The last section of the file defines how property validation is performed within the Workflow Studio Designer. If you have used the out-of-the-box activities within the Designer, you may have noticed that some activities have required properties that need to be set in order for them to be valid. These properties provide a red X or yellow warning icon to inform admins that they are required or desired to be set. You can set up the same type of functionality for your properties through the code in this section. There are a lot of comments within this section to explain how to set up your properties for validation, so I won't go into this here. I may blog about this in the future as it could be a big discussion on its own.
Blogs in this series:
- Getting Started
- Setting up your Visual Studio development environment
- Anatomy of a Workflow Studio activity project (this one)
- Testing your Workflow Studio activity project
- [Stepping through your Workflow Studio activity project code]