How to use C# to perform cluster administration in “Velocity”

This article talks about using Microsoft project code named “Velocity” PowerShell cmdlets in C# code for distributed cache cluster administration.

1) Go through the following blog to get started with using Exchange Management Shell commands in managed code.

 https://msdn.microsoft.com/en-us/library/bb332449.aspx

2) To use the Velocity Powershell cmdlets in the C# application install “Velocity” first.

3) Velocity Powershell cmdlet namespace:

When you install on the host, the Velocity cmdlets get registered with the Powershell. “Velocity” cmdlets are available in the namespace System.Data.Caching.Commands which you’ll need to give to the RunspaceConfiguration as it is explained in the above blog to use the “Velocity” cmdlets. For the list of “Velocity” cmdlets and their paramters, refer to “Velocity” help doc or run “Get-CacheHelp” from the Powershell admin tool.

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();

PSSnapInException snapInException = null;

PSSnapInInfo info = rsConfig.AddPSSnapIn("System.Data.Caching.Commands", out snapInException);

Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);

myRunSpace.Open();

4) Use cluster:

Always add the "Use-CacheCluster" command first, before any other command in the pipeline.

Pipeline pipeLine = myRunSpace.CreatePipeline();

Command myCommand = new Command("Use-CacheCluster");

myCommand.Parameters.Add(new CommandParameter("ConnectionString", @"<network share path> or connection string"));

myCommand.Parameters.Add(new CommandParameter("Name", @"<cluster name>"));

myCommand.Parameters.Add(new CommandParameter("Provider", @"<provider>"));

pipeLine.Commands.Add(myCommand);

5) Running “Velocity” cmdlet:

Add the “Velocity” cmdlet to be executed to the pipeline after the "Use-CacheCluster" command. Then invoke the pipeline. “Velocity” comdlets thow exception, CmdletInvocationException with inner exception System.Data.Caching.CacheException, when there is an error.

Command myCommand1 = new Command("Get-CacheHost");

pipeLine.Commands.Add(myCommand1);

Collection<PSObject> commandResults = pipeLine.Invoke();

6) Return value:

Some cmdlets return a value or list of values if they are successfully executed. The return value is a collection of objects. Convert these return values into appropriate types (return type for each cmdlet can be obtained from Powershell admin tool help. E.g. “help Get-CacheHost –full”) to use them. These types are available with the CacheAdminLibrary.dll which comes with “Velocity” installation and it is available in the install folder (e.g. C:\Program Files\Microsoft Distributed Cache\V1.0). Add this assembly to your .NET project references.

foreach (PSObject host in commandResults)

{

System.Data.Caching.AdminApi.HostInfo hostInfo = (System.Data.Caching.AdminApi.HostInfo) host.BaseObject;

Console.WriteLine("Name {0} ", hostInfo.HostName);

}

7) Run as administrator: “Velocity” cmdlets require administration privileges on the cluster hosts in order to function properly. .NET applications using those cmdlets require administrator privileges.

 

Sample C# code for Get-CacheHost cmdlet (Network share as config store):

using System;

using System.Collections.Generic;

using System.Text;

using System.Diagnostics;

using System.Management;

using System.Management.Automation;

using System.Management.Automation.Host;

using System.Management.Automation.Runspaces;

using System.Collections.ObjectModel;

namespace Cmdlets

{

    class Program

    {

        static void Main(string[] args)

        {

            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();

            PSSnapInException snapInException = null;

            PSSnapInInfo info = rsConfig.AddPSSnapIn("System.Data.Caching.Commands", out snapInException);

            Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);

            myRunSpace.Open();

            Pipeline pipeLine = myRunSpace.CreatePipeline();

            Command myCommand = new Command("Use-CacheCluster");

            // ConnectionString example: "data source =\\myMachine\abc\ClusterConfig.sdf"

            myCommand.Parameters.Add(new CommandParameter("ConnectionString", "data source =\\MyShare\ClusterConfig.sdf"));

            myCommand.Parameters.Add(new CommandParameter("Name", @"MyCluster"));

            myCommand.Parameters.Add(new CommandParameter("Provider", @"System.Data.SqlServerCe.3.5"));

            pipeLine.Commands.Add(myCommand);

            Command myCommand1 = new Command("Get-CacheHost");

            pipeLine.Commands.Add(myCommand1);

            Collection<PSObject> commandResults = pipeLine.Invoke();

            foreach (PSObject host in commandResults)

            {

                System.Data.Caching.AdminApi.HostInfo hostInfo = (System.Data.Caching.AdminApi.HostInfo) host.BaseObject;

                Console.WriteLine("Name {0} ", hostInfo.HostName);

            }

        }

    }

}

Sample C# code for Get-CacheHost cmdlet (SQL server as config store):

using System;

using System.Collections.Generic;

using System.Text;

using System.Diagnostics;

using System.Management;

using System.Management.Automation;

using System.Management.Automation.Host;

using System.Management.Automation.Runspaces;

using System.Collections.ObjectModel;

namespace Cmdlets

{

    class Program

    {

        static void Main(string[] args)

        {

            RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();

            PSSnapInException snapInException = null;

            PSSnapInInfo info = rsConfig.AddPSSnapIn("System.Data.Caching.Commands", out snapInException);

            Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);

            myRunSpace.Open();

            Pipeline pipeLine = myRunSpace.CreatePipeline();

            Command myCommand = new Command("Use-CacheCluster");

            // ConnectionString example: "Data Source=myMachine\SQLEXPRESS; Integrated Security=true;Initial Catalog=nonmdf"

            myCommand.Parameters.Add(new CommandParameter("ConnectionString", " Data Source=<sql-server>; Integrated Security=true;Initial Catalog=<catalog>"));

            myCommand.Parameters.Add(new CommandParameter("Name", @"MyCluster"));

            myCommand.Parameters.Add(new CommandParameter("Provider", @"System.Data.SqlClient"));

            pipeLine.Commands.Add(myCommand);

            Command myCommand1 = new Command("Get-CacheHost");

            pipeLine.Commands.Add(myCommand1);

            Collection<PSObject> commandResults = pipeLine.Invoke();

            foreach (PSObject host in commandResults)

            {

                System.Data.Caching.AdminApi.HostInfo hostInfo = (System.Data.Caching.AdminApi.HostInfo) host.BaseObject;

                Console.WriteLine("Name {0} ", hostInfo.HostName);

            }

        }

    }

}

Shankar Reddy Sama & Rahul Kaura

(Microsoft project code named "Velocity" Team)