PowerShell Scripting for Microsoft project code named "Velocity"

Windows PowerShell allows you to invoke C# code directly from the PowerShell scripts. This offers a powerful way to “script” cache operations such as puts/gets etc. This can be used to prime the cache as part of an automated setup or to perform other management tasks such as exploring the cache etc. This blog shows some examples on how you can invoke the "Velocity" APIs directly from PowerShell scripts. Note that I will use product and "Velocity" interchangeably .

Let us see how we can do it step by step in this write up. Windows PowerShell let's you create .NET objects, you can create object with new-object cmdlet like this

[System.Random]$rand =new-object System.Random

Before creating any object make sure that the assembly for that class is loaded by PowerShell.

You can check the assemblies loaded by PowerShell by running this on PowerShell.

[System.Threading.Thread]::GetDomain().GetAssemblies()

By default, PowerShell loads a bunch of assemblies for you so that you can start working with the base types, and some common functions. If you want to use the functionality in an assembly that is not already loaded, you will have to load that assembly yourself.

you can load by doing something like this on PowerShell prompt

[Reflection.Assembly]::LoadFrom("CacheBaseLibrary, Version=1.0.0.0, " `

          + "Culture=neutral, PublicKeyToken=b77a5c561934e089")

It will be good idea to use PowerShell-based cache administration tool which will be installed as part of product installation. Let us now see how we can create DataCacheFactory object in a PowerShell Script.

[Microsoft.Data.Caching.DataCacheServerEndpoint ]$server =new-object

 Microsoft.Data.Caching.DataCacheServerEndpoint("machineName", 22233, "DistributedCacheService")

[ Microsoft.Data.Caching.DataCacheServerEndpoint[]]$serverarray = new-object Microsoft.Data.Caching.DataCacheServerEndpoint[] 1

$serverarray[0]=$server

 

[Microsoft.Data.Caching.DataCacheFactory ]$cacheFactory = new-object Microsoft.Data.Caching.DataCacheFactory($serverarray, $true, $false)

Once we have created this DataCachefactory we can use it as we do it in any C# client, what I mean is that you can call GetCache, GetDefaultCache etc. on this DataCacheFactory. In the following code

I am creating a cache with a random name and going the use it with the DataCacheFactory created  above by calling GetCache on it. Creating a region and putting a key and value in it. At last a get

 call is getting the value for key we inserted by calling get on cache we created, after that we are  testing the value for its correctness.

[System.random]$rand =new-object System.random

$cacheName = $rand.next(100,134)

#Creating a Named cache in product cluster

New-Cache -CacheName $cacheName -NotExpirable true -Eviction LRU -TTL 1400 -Secondaries 0 -NotificationsEnabled true -Verbose

start-sleep -seconds 60

[Microsoft.Data.Caching.DataCache]$cache= $cacheFactory.GetCache($cacheName)

$regionName = $rand.next(22,127)

$cache.CreateRegion($regionName, $true)

start-sleep -milliseconds 15000

$key=$rand.next(45,292)

$value=$rand.next(83,120)

$cache.put($key, $value, $regionName)

$item = $cache.get($key, $regionName)

# Testing the value we got is what we put

if ($value -eq $item)

{

      write-output("Test Passed")

}

In the above code snippet you can see that is helping you in many ways. Firstly you are able to mix cache administration cmdlets with the client code, secondly it is a script and you get all powers of script here. We will see how a Cache Administrator can solve some problems that he he/she may face.

1) Strating a product Cluster, Creating a Cache, Creating some regions and filling some data before giving it for other use.

# Starting Cluster

Start-CacheCluster

start-sleep -seconds 15

$errRegionAlreadyExists = [Microsoft.Data.Caching.DataCacheErrorCode]::RegionAlreadyExists

# Random Class I will use it to create random values for cachename, region name, keys and values

[System.random]$rand =new-object System.random

$cacheName = $rand.next(1,999)

#Creating a new cache using a cache administration cmdlet

write-output ($cacheName )

New-Cache -CacheName $cacheName -NotExpirable true -Eviction LRU -TTL 1400 -Secondaries 0 -NotificationsEnabled true -Verbose

start-sleep -seconds 60

# Product Exception handling block, this will handle all product exception in this script

trap [Microsoft.Data.Caching.DataCacheException]

{

  write-error $("TRAPPED: " + $_.Exception.Message);

  write-error $("TRAPPED: " + $_.Exception.ErrorCode)

  if($_.Exception.ErrorCode -eq $errRegionAlreadyExists)

  {

      $regionName = $rand.next(1,200)

      $cache.CreateRegion($regionName, $true)

  }

  if($_.Exception.ErrorCode -eq 12011)

  {

    exit

  }

  continue;

}

# Creating Cache Factory with one DataCacheServerEndpoint

[Microsoft.Data.Caching.DataCacheServerEndpoint]$server =

new-object Microsoft.Data.Caching.DataCacheServerEndpoint("machinename", 22233, "DistributedCacheService")

# This code Microsoft.Data.Caching.DataCacheServerEndpoint[] 1 creates a array of one

[Microsoft.Data.Caching.DataCacheServerEndpoint[]]$serverarray = new-object Microsoft.Data.Caching.DataCacheServerEndpoint[] 1

$serverarray[0]=$server

[Microsoft.Data.Caching.DataCacheFactory] $cacheFactory = new-object Microsoft.Data.Caching.DataCacheFactory($serverarray, $true, $false)

# This block will handle any kind of exception in this script if it not of product type

trap [Exception]

{

    write-error $("TRAPPED: " + $_.Exception.GetType().FullName);

    write-error $("TRAPPED: " + $_.Exception.Message);

    write-error $("TRAPPED: " + $_.Exception.StackTrace);

    write-error $("TRAPPED: " + $_.Exception.Source);

    write-error $("TRAPPED: " + $_.Exception.TargetSite);

    continue;

}

# Getting the cache object in here which we created earlier in this script.

[Microsoft.Data.Caching.DataCache]$cache= $cacheFactory.GetCache($cacheName)

$regionName = $rand.next(22,127)

# Creating region with a random name, which is in this case a integer

$cache.CreateRegion($regionName, $true)

start-sleep -milliseconds 15000

$key=$rand.next(4,292)

$value=$rand.next(8,120)

$cache.add($key, $value, $regionName)

# Putting data in the Region we created above

for ($i=1;$i -le 100;$i+=1)

{

      $key=$rand.next(4,292)

      $value=$rand.next(8,120)

      $cache.put($key, $value, $regionName)

}

In the code above you can see how product exceptions being handled, you can also choose try-catch style in PowerShell Script.

Function TryCatch() {

   &{#Try Block

              throw (new-object Microsoft.Data.Caching.DataCacheException)

   }

   #Catch Block

   trap [Microsoft.Data.Caching.DataCacheException] {

      Write-Host " $_.Exception"

      Write-Output "Failure!"

      continue

   }

}

 

References:

https://blogs.msdn.com/powershell/archive/2006/04/25/583273.aspx

https://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx

https://blogs.msdn.com/wriju/archive/2008/07/01/how-to-find-public-key-token-for-a-net-dll-or-assembly.aspx

 

Thanks,

Abhijeet Bhattacharya

(Microsoft project code named “Velocity” team)