Share via


Calling PowerShell from .NET

I have been working with Windows Server AppFabric caching lately and have found it to be very impressive.  The more that I work with it the more that I can see areas that it can be utilized.  One of the things that will become quite evident as you start using it is that much of the setup and configuration is done through PowerShell cmdlets.

I am in the process of putting together an application and I want the application to be able to create and pre-populate the cache.  As I looked into creating the cache I knew that it could be created through PowerShell directly but I wanted to call the PowerShell cmdlets from .NET.  So, lets look at what is needed to create the cache from PowerShell first and then we will look at the code to call the cmdlets from .NET.

This assumes that AppFabric has been installed and configured.

Open a PowerShell command window.  The first thing that we are going to do is to import two modules and then we can start issuing commands.  First, type "Import-Module DistributedCacheAdministration" (without the quotes) and hit enter.  This will import the cache administration cmdlets. Next type "Import-Module DistributedCacheConfiguration" and hit enter.  This will import the cache configuration cmdlets.

The next command will bring the current machines' cluster configuration into the PowerShell session context.  So, type in Use-CacheCluster and hit enter.  We have now entered all that we need to start interacting with the cache.  The first thing that we need to do is to ensure that the cache service is running.  Type "Get-CacheHost" and hit enter.  Look on the screen and see if the Service Status show UP.  If it shows DOWN then issue the following commands to start it.  Type "$hostinfo = Get-CacheHost" and hit enter.  Then type in "Start-CacheHost $hostinfo.HostName $hostinfo.PortNo".

At this point we are ready to create the cache using the New-Cache cmdlet.  Type "New-Cache <your cache name here>" and hit enter.  This will create a cache with your name that is ready to use. 

If you want to see the configuration for your newly created cache type in "Get-CacheConfig <your cache name here>" and hit enter.  You will see the following configuration attributes and their settings.

CacheName : MyCache
TimeToLive : 10 mins
CacheType : Partitioned
Secondaries : 0
IsExpirable : False
EvictionType : LRU
NotificationsEnabled : False

 

To do this all with code we need to add three references to our project.  Add the System.Management.Automation assembly as well as the Microsoft.ApplicationServer.Caching.Core and Microsoft.ApplicationServer.Caching.Client assemblies.  These two assemblies can be found in the Windows\System32\AppFabric directory.

To set up the environment in .NET to issue PowerShell commands we need to start with the InitialSessionState class.  This will create a session with the PowerShell runspace.  A PowerShell runspace is the operating environment where you can create pipelines which will run the cmdlets.

So, just as above we will need to start with importing the DistributedCacheAdministration and DistributedCacheConfiguration modules.  This can be seen below in the source code with the state.ImportPSModule method.  Once we have the session state created we can call the RunspaceFactory to create a new runspace.  At this point we can call the Open method can now start creating commands through a pipeline. 

In the code below we create two pipelines.  The first is our Use-CacheCluster command.  This is a command that doesn't take or return any arguments.  The next command is the New-Cache command.  This takes a set of arguments so we will create this a bit different.  First, we will create a Command object and then set parameters on the command object for each of the arguments we want to pass in.  In this example I am providing a name as well as telling the caching system that I don't want the cache items to expire.  Next, we need to pass the command object to the pipe and lastly, call the Invoke method as shown in the code below: 

private void CreateCache(string cacheName)
{
    //This can also be kept in a config file
    var config = new DataCacheFactoryConfiguration();
config.Servers = new List<DataCacheServerEndpoint>
{
            new DataCacheServerEndpoint(Environment.MachineName, 22233)
};

    DataCacheFactory dcf = new DataCacheFactory(config);

    if (dcf != null)
{
        var state = InitialSessionState.CreateDefault();
state.ImportPSModule(new string[] { "DistributedCacheAdministration", "DistributedCacheConfiguration" });
state.ThrowOnRunspaceOpenError = true;
        var rs = RunspaceFactory.CreateRunspace(state);
rs.Open();
        var pipe = rs.CreatePipeline();
pipe.Commands.Add(new Command("Use-CacheCluster"));
       
var cmd = new Command("New-Cache");
cmd.Parameters.Add(new CommandParameter("Name", cacheName));
cmd.Parameters.Add(new CommandParameter("Expirable", false));
pipe.Commands.Add(cmd);

var output = pipe.Invoke();
}
}

We now have a cache created for us from .NET code.

Comments

  • Anonymous
    April 07, 2010
    thanks ... this is really helpfull , i am doing asp.net / ironpython webinterface invoking powershell commands and i was looking for ImportPSModule