Let me start off this blog post by saying that as much as I want to be a 'developer', I just can't get my mind moving in that direction.  But the beauty with PowerShell is that it can take not even a weekend warrior of development like myself, and actually become useful with SDK's.  

Citrix has done an excellent job in the past few years really developing and providing a very useful policy engine and structure for not only XenApp, but also XenDesktop.  Personally, I have always love the Citrix policy engine, making it very easy to get to the end results I wanted - the look, feel and usefulness of a XenApp environment.  To me, storing the policies within the IMA database always left something to be desired.  Sure, it's always been there, and is a core component of the XenApp infrastructure.  Let's take for example a farm that consists of 20 various policies - printing, Flash management, TimeZone, etc, and consider the following scenarios.

<ul>
	<li>You have a separate test farm, and you need to bring over 2 new policies to the production farm - how do you do it?</li>
	<li>You have purchased a new company who currently runs a XenApp farm, and need to merge their policies into the main farm - how do you do it?</li>
	<li>You want to migrate all of the XenApp IMA polices into Active Directory, for a single point of policy management - how do you do it?</li>
</ul>

The simple answer is the XenApp SDK.  The XenApp <a href="http://community.citrix.com/display/xa/XenApp+6.5+Powershell+SDK">SDK</a> allows for complete PowerShell management of a XenApp farm.  This blog post isn't intended as an overview of the full XA SDK, but will focus on the 3 scenarios from above, managing policies with the SDK.  

<h2>
Brief Overview of XenApp SDK
</h2>
The XenApp SDK was released initially with XenApp 5.0, as a replacement for the MFCOM commands that were included with earlier editions of XenApp.  To be honest, MFCOM never seemed super useful with XenApp management, but with SDK and the usage of PowerShell, I started to see where the SDK was proving to give that little extra bit we were missing.  So how do we use it?  Well, every XenApp server v6.x and above includes PowerShell, so all that needs to be installed is the SDK itself (I wish Citrix would just install this as part of the XenApp install).  There are a ton of resources on the web that provide a greater background on the SDK usage, including some very excellent Farm Reports that will print out the entire farm configuration with best practices - Google is your friend…

Let's start the SDK to see what we've got available:

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-10.13-AM.png" alt="Image 8 26 13 at 10 13 AM" title="Image 8-26-13 at 10.13 AM.png" border="0" width="600" height="354" />

Citrix provides a good amount of cmdlets with the SDK, and includes the Citrix.Common.GroupPolicy snap in.  However, that doesn't give us the full spectrum of possibilities with the SDK.  There's an extra file needed to manage anything Policy related, whether it's IMA or GPO policies.  That can be found <a href="http://community.citrix.com/download/attachments/162955822/Citrix.GroupPolicy.Commands.psm1?version=1">here.</a>

<h2>
Policy Management
</h2>
Policy Management. Some people might say so what, we can do it from within the Citrix App Center.  Not a big deal to recreate a policy.  But why recreate manually when you can automate something?  With the SDK, the first scenario listed above can be done in 2 lines of code - <strong>Export-CtxGroupPolicy</strong>  and <strong>Import-CtxGroupPolicy</strong>.  The SDK provides a very flexible and easy method to not only export all of your policies (Think Backup here), but to also import the policies.  Let's take a look at exporting a XenApp policy.

<em>If you're new to PowerShell, or just dabble in it, remember the command <strong>get-help</strong>.  Excellent details per cmdlet.  </em> 

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-10.30-AM.png" alt="Image 8 26 13 at 10 30 AM" title="Image 8-26-13 at 10.30 AM.png" border="0" width="600" height="225" />

Exporting a XenApp policy is as simple as issuing the command <strong>Export-CtxGroupPolicy</strong>.  Notice from the above image on the <strong>Export-CtxGroupPolicy</strong> cmdlet, there are a number of additional parameters that we can expose.  If you want to export a single policy (Scenario 2 from above), you can use the <em><strong>-PolicyName</strong></em> parameter.  If you want to export either the Computer or User policies, use the <em><strong>-Type</strong></em> parameter.  Very simple, but very powerful.  

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-10.50-AM.png" alt="Image 8 26 13 at 10 50 AM" title="Image 8-26-13 at 10.50 AM.png" border="0" width="486" height="61" />

The results of running the export command are 3 editable .XML files, one with the policy names, one with configuration, and one with the filters.

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-10.51-AM.png" alt="Image 8 26 13 at 10 51 AM" title="Image 8-26-13 at 10.51 AM.png" border="0" width="597" height="72" />

The resulting .xml files could be taken to another XenApp farm, and the <strong>Import-CtxGroupPolicy</strong> cmdlet could be run, pointed to the directory of the files, and the new policies would be available in the new farm.  Simple yet powerful in my opinion. 

Ever needed to move a policy in the App Center from #12 to #3?  That takes clicking the Higher button in App Center 9 times.  Ever needed to disable all of the user policies for troubleshooting?  The XenApp SDK can handle it.  The cmdlet <strong>Set-CtxGroupPolicy</strong> takes 2 parameters that allow us to change the priority of the policy, or enable/disable the policy.    

<ul>
	<li><strong><em>-Priority: </em></strong>Enter a number to change the priority</li>
	<li><strong><em>-Enabled: </em></strong>Boolean value for Enabled/Disabled.  Can use $True or $False here, or 0/1</li>
</ul>
Why not just run the command <strong>Set-CtxGroupPolicy -Type User -Name "PolicyName" -Priority 3 -Type User</strong> for the above example to move from Priority of 12 to 3.  Very simple, and very efficient.   And not to be left out, you can create new policies - but no edits (<strong>New-CtxGroupPolicy</strong>) and remove policies (<strong>Remove-CtxGroupPolicy</strong>) thru the SDK.  

<h2>
Migrating IMA policies to AD Group Policies
</h2>
At a customer site a few years back, I ran into an issue where the customer was pushing upwards of 100 policies in the IMA database, and anytime they would need to add/modify/remove a policy, either the IMA database would become corrupted, or it would be incredibly slow - even to just change the priority of a policy.  Long story short, we found that moving the policy items into Group Policies did not exhibit the same issues when the large number of policies was in place.  Great news, but how can we get all 100 policies migrated from the IMA database into Group Policies.  Sure, there is the XenApp Migration Tool, but that won't work here since we aren't migrating to a new farm.  Well, we've already touched on the <strong>Export</strong> and <strong>Import CtxGroupPolicy</strong> cmdlets and how easy it was.  Well, with a few additional commands and an additional parameter to the Export and Import commands, we can migrate policies between IMA and AD seamlessly.

Citrix provides an excellent CTX article on the exporting and importing of policies <a href="http://support.citrix.com/article/CTX128625">here,</a> and it's piece #1 of moving to the export/importing of policies.  

To go from IMA to AD (Or Local Server to AD/IMA), or AD to IMA policies we need to add one line to our plan, and that's using a PSDrive (PowerShell Drive) to allow us to navigate into the AD world.  Whether we are exporting from AD, or importing to AD, we need to use the PSDrive command to establish a 'mapped drive' connection to an existing GPO.  

Running the following command:  <strong>New-PSDrive -Name  -PSProvider CitrixGroupPolicy -Root \ -DomainGpo </strong>

We need to know:
<ul>
	<li><strong>DomainGPODrive</strong> - what drive we want to use.</li>
	<li><strong>DomainGPO</strong> - what GPO we are wanting to work against.</li>
</ul>
To me, one of the really nice features of merging the XenApp policies into a Group Policy is a single point of management.  You can create a GPO with all of your Server specific settings for an OU (timeouts, start menu redirections, profile specific items, etc.), and tie specific XenApp items to that GPO as well.  One item to note though with the import of Policies from IMA to GPO.  With IMA, we have a filter option based on OU.  In some cases, an IMA Computer policy might be filtered based on OU of the server, especially if it is within a multi-site/customer AD structure.  Well, if your policies are set to filter on the OU, guess what?  The import of the policy will fail when coming into an AD GPO.  Why you ask?  That filter does not exist for a XenApp Policy derived from an AD GPO, well, because the GPO is already applied to an OU.  So for computer filter options, the only option remaining is a Worker Group.  That requirement/limitation might require some Farm modifications.  You can still filter your Worker Groups based on an OU though, so this is the easiest way to still use the OU as a baseline for filtering.

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-12.57-PM.png" alt="Image 8 26 13 at 12 57 PM" title="Image 8-26-13 at 12.57 PM.png" border="0" width="600" height="151" />

So to close out this post, let's setup an example of migrating policies from IMA into a Group Policy.  In my domain, I have my XenApp servers in a dedicated OU as per best practice, and currently I don't have any server specific GPO's applied.  In my XenApp farm, I have 3 computer and 2 user policies, and I have disabled the Unfiltered policy, as I tend not to use that.  For this example, we are going to pull over all of the Computer and User settings.

To export the IMA policies, we of course use our <strong>Export-CtxGroupPolicy</strong> command that we ran before.  We can use those same files to import the Policies into a GPO.  To import the files to a GPO, as we already covered, a new PSDrive needs to be created.  The following statement is what we need to get our first step of integration complete:

<strong>New-PSDrive -Name X -PSProvider CitrixGroupPolicy -Root \ -DomainGPO XenAppSpecific</strong>

<ul>
	<li><strong><em>-Name: </em></strong>We will use X for the drive</li>
	<li><strong><em>-PSProvider: </em></strong>PSProvider tells what kind of drive to make.  In this case, it's always CitrixGroupPolicy.  You can use the Get-PSDrive command to get a list of drive providers.</li>
	<li><strong><em>-Root: </em></strong>Tells what folder serves as the drive root, in our case it's always \.</li> 
	<li><strong><em>-DomainGPO: </em></strong> Tells the command which GPO to use.</li>
</ul>

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-11.41-AM.png" alt="Image 8 26 13 at 11 41 AM" title="Image 8-26-13 at 11.41 AM.png" border="0" width="600" height="80" />

Notice the issue when running our command.  If the GPO does not exist, the New-PSDrive command will fail.  Yes, it would be nice if this would have a <strong><em>-force</em></strong> or <strong><em>-create</em></strong> parameter to go along with it, but really, the assumption is that you already have a GPO that you want to add these XenApp items to.  Once the new PSDrive is established, you can navigate to it within the PowerShell session just like a standard drive, <strong>cd X:</strong> will allow you to navigate the folder structure just like DOS commands.  Although in this case, the folder structure returns either <em>Computer</em> or <em>User</em>.  Look familiar?

<img src="http://egroup.jasonmangone.com/wp-content/uploads/2013/08/Image-8-26-13-at-11.48-AM.png" alt="Image 8 26 13 at 11 48 AM" title="Image 8-26-13 at 11.48 AM.png" border="0" width="600" height="84" />

Now that our connection to the GPO has been established, all that is left is to import the .xml files we exported earlier.  The command to import is very similar, but we need to add the PSDrive  parameter for the DomainGPODrive we used in our PSDrive command.  Let's breakdown the command for the import - <strong>Import-CtxGroupPolicy -FolderPath FarmPolicies -DriveName X</strong>.
<ul>
	<li><strong>Import-CtxGroupPolicy: </strong>We've already touched on this cmdlet.  This is what drives the import of the .xml files to the desired location.</li>
	<li><strong><em>-Folder Path: </em></strong>This tells the <strong>Import-CtxGroupPolicy</strong> command where to get the .xml files.</li>
	<li><strong><em>-Drive Name: </em></strong>This tells the <strong>Import-CtxGroupPolicy</strong> command the location of where to put the imported files.  Remember here, we used there X drive as the PSDrive which maps to the desired GPO.</li>
</ul>

<h3>Additional Resources</h3>
<ul>
	<li>Microsoft PSDrive Details - <a href="http://technet.microsoft.com/en-us/library/ee176915.aspx">http://technet.microsoft.com/en-us/library/ee176915.aspx</a></li>
	<li>Citrix Export/Import Policies - <a href="http://support.citrix.com/article/CTX128625">http://support.citrix.com/article/CTX128625</a></li>
	<li>Citrix Additional Export/Import - <a href="http://community.citrix.com/display/xa/Exporting+and+Importing+XenApp+Group+Policies">http://community.citrix.com/display/xa/Exporting+and+Importing+XenApp+Group+Policies</a>
</ul>