Categorías: powershell

SharePoint 2013 Cómo ejecutar comandos PowerShell desde nuestras soluciones de SharePoint

PowerShell se ha convertido en una herramienta indispensable hoy en día en nuestros desarrollos, es una herramienta que hace de «pegamento» entre developers e IT Pros. Los IT Pros están contentos porque se ejecuta en una consola en blanco y negro, mientras que los developers utilizan un lenguaje de programación para poder realizar todas las tareas que anteriormente no podían realizar.

Más allá de su uso, PowerShell es relativamente importante en SharePoint porque podemos realizar operaciones de forma mucho más rápida que sin la necesidad, bien de generar una aplicación de consola, o un proyecto en Visual Studio. Con la ventaja añadida de que si te equivocas no debes de volver a generar el código fuente, instalarlo, desplegarlo, reiniciar el IIS, etc. De alguna forma, se puede comparar al modo en que se utiliza JavaScript.

Si observamos la cantidad de comandos que podemos ejecutar, prácticamente tenemos la misma funcionalidad que con el modelo de objetos servidor (hablo naturalmente de soluciones OnPremise) más todas las operaciones de Administración del servidor (Copias de seguridad, creación de WebApplication, levantar servicios, et..). En un principio, podemos pensar que no tengo la necesidad de ejecutar ningún comando PowerShell desde ninguna solución de SharePoint, esto es la teoría.
Según empiezas a utilizar PowerShell y vas comprobando de su potencia, su uso es mucho mayor, empiezas por pequeñas funciones hasta que incluyes algún Cmdlets (podéis ver este artículo del gran Maestro Gustavo Velez de cómo implementarlo).

Ahora bien, el uso de PowerShell o la forma en que los departamentos de IT se organizan, no tiene porqué ser la misma forma que tú consideras más optima o la que debería de ser adecuada para un entorno SharePoint. En este momento, es cuando te das cuenta que tu forma de trabajar no encaja con la exigida por el cliente. Tienes dos formas: una perder el cliente y otra, adaptarte al requisito del cliente. Naturalmente, la opción 1 no esta ni mucho menos contemplada salvo que realmente sea un disparate lo que propone.

Ahora bien, dentro de los entornos en los que nos encontramos tenemos 3 opciones:

  1. Todos los despliegues de la solución es mediante PowerShell
  2. Todos los despliegues son haciendo uso de un WSP y desplegarlos mediante PowerShell.
  3. Un entorno hibrido:  utilizar bien WSP o PowerShell dependiendo de qué es mejor en cada momento.

La opción 3 es la mejor, pero como todo en esta vida, quizás no escojas la mejor opción.

Ahora bien, si necesitamos realizar todo con PowerShell está claro que podemos utilizar nuestra DLL en PowerShell de una forma muy simple. Mirar este ejemplo:

$dll="C:\Encamina.Enmarcha.ALM.dll"
$dllCommon="C:\ENCAMINA.Sharepoint.Common.dll"
[System.Reflection.Assembly]::LoadFile($dll)
[System.Reflection.Assembly]::LoadFile($dllCommon)
$site= "http://democolabora"
[Encamina.Enmarcha.ALM.Run]::ExtractContent($site, $null);

Pero en el caso contrario, ¿Cómo lo podemos hacer? Pues también es posible. Gracias a mi compañero Adrian Del Rincón en ENCAMINA hemos implementando una funcionalidad para conseguir tal efecto. Para ello bastaría con el siguiente código:

public static Collection<PSObject> RunPowerShell(string scriptFile, string scriptParameters = "")
  {

      var runspaceConfiguration = RunspaceConfiguration.Create();
      var runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
      runspace.Open();
      var scriptInvoker = new RunspaceInvoke(runspace);
      scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
      var pipeline = runspace.CreatePipeline();
      var scriptCommand = new Command(scriptFile);           
      if (!string.IsNullOrEmpty(scriptParameters))
      {
          foreach (var commandParm in scriptParameters.Split(' ').Select(scriptParameter => new CommandParameter(null, scriptParameter)))
          {
              scriptCommand.Parameters.Add(commandParm);
          }
      }
      var commandParam = new CommandParameter("IsOutsideCmd", true);
      scriptCommand.Parameters.Add(commandParam);
      pipeline.Commands.Add(scriptCommand);
      try
      {
          var results = pipeline.Invoke();
          return results;
      }
      catch (Exception)
      {
          return null;
      }
  }

La función no tiene más misterio que, por un lado, se solicita la ruta donde esta ubicado el fichero PowerShell. Ahora bien, a la hora de implementar este fichero PowerShell hay que tener con cuidado con los mensajitos que se muestran por la consola, dado que no estamos en el mismo contexto producirán un fallo. Es decir, si escribimos Write-Host «…» no funcionara. El motivo es claro porque no tiene ubicación para mostrar el mensaje. Para solucionar esta limitación en lugar de utilizar Write-Host mejor utilizar Write-Output y mostrar estos mensajes en un fichero para posteriormente comprobar si la ejecución ha ido correctamente.

¿Por qué necesito ejecutar PowerShell dentro de un WSP?

Principalmente para adaptarnos a todos los entornos posibles, y hacer que nuestra forma de trabajar sea la misma independientemente del entorno en el que nos encontremos y podamos sacar el máximo provecho a la situación. Nosotros disponemos de un framework propio «ENMARCHA» que su funcionalidad es establecer unos patrones, unas funciones, una ayuda para que podamos conseguir nuestro desarrollo más ágil y que pueda guiar a trabajar de la forma que pensamos que es más eficiente y correcta, en algunas ocasiones tendremos que ejecutarlo desde PowerShell, otras veces desde la solución, pero independientemente de donde se invoca, siempre se esta comportando de la misma forma y con el mismo código.

Compartir
Publicado por
Adrián Díaz

Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continuas navegando, estás dando tu consentimiento para aceptar las cookies y también nuestra política de cookies (esperemos que no te empaches con tanta cookie 😊)