Saturday, September 22, 2012

Write C# code in powershell scripts

Powershell is powerfull sciprting language which allows you to automate many administrative tasks. However in addition to own language, it allows you to embed C# code inside script and execute it with other script instructions. This feature is not used very often, and although it will be good that you will teach powershell syntax, knowledge of this technique may help you in different scenarios. In this post I will show how to use C# inside powershell.

Lets move the following simple C# function to powershell and call it from ps1 file:

   1: public static class ScriptExample
   2: {
   3:     public static void EnumerateWebs(string url)
   4:     {
   5:         using (var site = new SPSite(url))
   6:         {
   7:             foreach (SPWeb web in site.AllWebs)
   8:             {
   9:                 Console.WriteLine(web.Url);
  10:                 web.Dispose();
  11:             }
  12:         }
  13:     }
  14: }

It opens SPSite object using passed url and enumerates all sub sites in this site collection. It is quite easy to write the same code in powershell, but our purpose is to show how to embed it into ps1 file and execute it from here. Here is the code:

   1: $assemblies = (
   2:     "Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
   3:     )
   4:  
   5: $source = @"
   6: using System;
   7: using Microsoft.SharePoint;
   8:  
   9: namespace Test
  10: {
  11:     public static class ScriptExample
  12:     {
  13:         public static void EnumerateWebs(string url)
  14:         {
  15:             using (SPSite site = new SPSite(url))
  16:             {
  17:                 foreach (SPWeb web in site.AllWebs)
  18:                 {
  19:                     Console.WriteLine(web.Url);
  20:                     web.Dispose();
  21:                 }
  22:             }
  23:         }
  24:     }
  25: }
  26: "@
  27:  
  28: $url = "http://example.com"
  29: Add-Type -ReferencedAssemblies $assemblies -TypeDefinition $source -Language CSharp 
  30: [Test.ScriptExample]::EnumerateWebs($url)

At first we created list of imported assemblies (lines 1-3). In this case we need only Microsoft.SharePoint. If you will run this script from Sharepoint management shell, it is not needed, because this assembly is loaded automatically there, i.e. it is needed only if you run the script from regular powershell context. Then we write C# code and assign it to the local variable $source as string (lines 5-26). This is exact copy of our C# program shown above (it is important to add “using” directives there. Without them code won’t be compiled). After that we define url in local variable, load our C# code using Add-Type cmdlet with all additional assemblies which should be loaded into the context and call our function with parameter defined in powershell (lines 28-30). After running this scipt will print all sub sites of specified site collection.

As you can see it is quite easy to call C# managed code inside powershell. It may be helpful if you need to write some complicated code in ps1 file and don’t know how to move it to powershell syntax completely. Also it may be useful for developers who know C# and recently started working with powershell, although of course you anyway should teach powershell syntax in order to create more efficient code.

No comments:

Post a Comment