nant / nantcontrib

NAntContrib is the project for tasks and tools that haven't made it into the main NAnt distribution yet or for whatever reason don't belong there.
nantcontrib.sourceforge.net
GNU Lesser General Public License v2.1
51 stars 35 forks source link

Powershell script task #5

Open patrickfarry opened 12 years ago

patrickfarry commented 12 years ago

I wrote a small extension task that embeds a powershell script. We will be using it for complex build tasks. The script can access the Nant project object (get and set properties etc.). It also supports named powershell runspaces - so you can continue executing a script after setting up the parameters.

Anyone interested in this? I haven't contributed anything before - not sure if it is worthy or how to go about it.

Here is an example of the task in NAnt

<?xml version="1.0"?>

The top level build file. $var = "this is the script" $myvar.Properties["tmpLog"] = "Hello" $myvar.Project.ProjectName $var = "running from a new runspace" $var $var
patrickfarry commented 12 years ago

Sorry - that looks ugly - here is my test build file

<?xml version="1.0"?>

The top level build file. ``` $var = "this is the script" $myvar.Properties["tmpLog"] = "Hello" $myvar.Project.ProjectName $var = "running from a new runspace" $var $var
patrickfarry commented 12 years ago

Here is the source - -

using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using NAnt.Core; using NAnt.Core.Attributes; using System.Management.Automation; using System.Management.Automation.Runspaces;

namespace PowershellPlugin { [TaskName("powershell" )] public class PowershellTask : Task {

  private string _runspaceName = string.Empty;
  private string _taskVarName = "task";
  private bool _isNamedRunspace = false;
  private string _property = string.Empty;
  static private Dictionary<string, Runspace> _namedSession;

  [TaskAttribute("runspace", Required = false)]
  [StringValidator(AllowEmpty = false)]
  public string RunspaceName
  {
      get { return _runspaceName; }
      set { _isNamedRunspace = true; _runspaceName = value; }
  }

  [TaskAttribute("taskvar", Required = false)]
  [StringValidator(AllowEmpty = false)]
  public string TaskVar
  {
      get { return _taskVarName; }
      set { _taskVarName = value; }
  }

  [TaskAttribute("property", Required = false)]
  [StringValidator(AllowEmpty = false)]
  public string Property
  {
      get { return _property; }
      set { _property = value; }
  }

    public PowershellTask()
    {
        _runspaceName = String.Empty;
        if (_namedSession == null)
        {
            object l = new object();
            lock (l)
            {
                if (_namedSession == null)
                {
                    _namedSession = new Dictionary<string, Runspace>();
                }
            }
        }

    }

  protected override void ExecuteTask()
  {
      Runspace runspace = null;

      try
      {

          StringBuilder scriptText = new StringBuilder();
          scriptText.Append(XmlNode.InnerText);
            object l = new object();
            lock (l)
            {

                if (!_namedSession.TryGetValue(_runspaceName, out runspace))
                {
                    InitialSessionState iss = InitialSessionState.CreateDefault();
                    SessionStateVariableEntry thisTask = new SessionStateVariableEntry(_taskVarName, this, "The task being called in nant");
                    iss.Variables.Add(thisTask);
                    runspace = RunspaceFactory.CreateRunspace(iss);

                    if (_isNamedRunspace)
                    {
                        _namedSession.Add(_runspaceName, runspace);
                    }
                    runspace.Open();

                }
            }
          PowerShell ps = PowerShell.Create();
          ps.Runspace = runspace;
          ps.AddScript(scriptText.ToString());
          Collection<PSObject> results = ps.Invoke();
          StringBuilder resultString = new StringBuilder();
          if (_property != String.Empty)
          {
              foreach (PSObject po in results)
              {

                 resultString.AppendLine(po.ToString());

              }
              this.Properties[_property] = resultString.ToString();
          }
      }
      finally
      {
          if (!_isNamedRunspace && runspace != null)
          {
              runspace.Close();
              runspace.Dispose();
          }
      }

  }

} }

dguder commented 12 years ago

Here is the source - -
(now using github markdown)

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace PowershellPlugin
{
    [TaskName("powershell" )]
    public class PowershellTask : Task
    {

      private string _runspaceName = string.Empty;
      private string _taskVarName = "task";
      private bool _isNamedRunspace = false;
      private string _property = string.Empty;
      static private Dictionary<string, Runspace> _namedSession;

      [TaskAttribute("runspace", Required = false)]
      [StringValidator(AllowEmpty = false)]
      public string RunspaceName
      {
          get { return _runspaceName; }
          set { _isNamedRunspace = true; _runspaceName = value; }
      }

      [TaskAttribute("taskvar", Required = false)]
      [StringValidator(AllowEmpty = false)]
      public string TaskVar
      {
          get { return _taskVarName; }
          set { _taskVarName = value; }
      }

      [TaskAttribute("property", Required = false)]
      [StringValidator(AllowEmpty = false)]
      public string Property
      {
          get { return _property; }
          set { _property = value; }
      }

        public PowershellTask()
        {
            _runspaceName = String.Empty;
            if (_namedSession == null)
            {
                object l = new object();
                lock (l)
                {
                    if (_namedSession == null)
                    {
                        _namedSession = new Dictionary<string, Runspace>();
                    }
                }
            }

        }

      protected override void ExecuteTask()
      {
          Runspace runspace = null;

          try
          {

              StringBuilder scriptText = new StringBuilder();
              scriptText.Append(XmlNode.InnerText);
                object l = new object();
                lock (l)
                {

                    if (!_namedSession.TryGetValue(_runspaceName, out runspace))
                    {
                        InitialSessionState iss = InitialSessionState.CreateDefault();
                        SessionStateVariableEntry thisTask = new SessionStateVariableEntry(_taskVarName, this, "The task being called in nant");
                        iss.Variables.Add(thisTask);
                        runspace = RunspaceFactory.CreateRunspace(iss);

                        if (_isNamedRunspace)
                        {
                            _namedSession.Add(_runspaceName, runspace);
                        }
                        runspace.Open();

                    }
                }
              PowerShell ps = PowerShell.Create();
              ps.Runspace = runspace;
              ps.AddScript(scriptText.ToString());
              Collection<PSObject> results = ps.Invoke();
              StringBuilder resultString = new StringBuilder();
              if (_property != String.Empty)
              {
                  foreach (PSObject po in results)
                  {

                     resultString.AppendLine(po.ToString());

                  }
                  this.Properties[_property] = resultString.ToString();
              }
          }
          finally
          {
              if (!_isNamedRunspace && runspace != null)
              {
                  runspace.Close();
                  runspace.Dispose();
              }
          }

      }

   }
}
patrickfarry commented 12 years ago

Do you what the whole solution?

dguder commented 12 years ago

First of all I wanted to see the whole code. Do you have any tests? Some review:

rmboggs commented 12 years ago

I like the idea. If you are wanting to submit this task to NAntContrib, I would ask if you could submit this via a pull request, details can be found here.

Documentation for this task would also be very helpful. :)

patrickfarry commented 12 years ago

I don' t have anything else. Happy to spend some time bringing it up to
standard.

I will look at the other contrib projects and figure out what to do. Will
send an update when I get it done.

Cheers.

Connected by DROID on Verizon Wireless

-----Original message----- From: Dominik Guder
<reply+i-2528372-b66055b90339b6ceec05f59b133e8fb0fc42c4db-1258583@reply.githu b.com> To: patrickfarry patrick.farry@endicia.com Sent: Mon, Dec 12, 2011 23:01:25 GMT+00:00 Subject: Re: [nantcontrib] Powershell script task (#5)

First of all I wanted to see the whole code. Do you have any tests? Some review:


Reply to this email directly or view it on GitHub: https://github.com/nant/nantcontrib/issues/5#issuecomment-3114629

patrickfarry commented 12 years ago

Will do. I got mail from Dominik. I will be upgrading what I did to fit the
project and will get back to you guys.

Connected by DROID on Verizon Wireless

-----Original message----- From: Ryan Boggs
<reply+i-2528372-b66055b90339b6ceec05f59b133e8fb0fc42c4db-1258583@reply.githu b.com> To: patrickfarry patrick.farry@endicia.com Sent: Mon, Dec 12, 2011 23:14:02 GMT+00:00 Subject: Re: [nantcontrib] Powershell script task (#5)

I like the idea. If you are wanting to submit this task to NAntContrib, I
would ask if you could submit this via a pull request, details can be found
here
.

Documentation for this task would also be very helpful. :)


Reply to this email directly or view it on GitHub: https://github.com/nant/nantcontrib/issues/5#issuecomment-3114801

rmboggs commented 12 years ago

Sounds great.

andrewducker commented 6 years ago

Did this ever get merged in?