9

We use NAnt extensively for our build system. Recently, I've written a couple PowerShell Cmdlets to perform a few database related things. At first, the intent of these Cmdlets was not to necessarily run within our build process. However, this has recently become a need and we would like to run a few of these Cmdlets from our NAnt based build process.

These Cmdlets are written in C# and we have a SnapIn for them (if that matters at all).

A few ideas:

  • Use the exec task to call PowerShell? (not sure how this would work though)
  • Write a custom NAnt task that references and uses the Cmdlet?

What might be a good way to do this?

Community
  • 1
  • 1
Scott Saad
  • 17,962
  • 11
  • 63
  • 84

4 Answers4

12

You can use the below exec task in your nant script to call your ps cmdlets.

<exec program="powershell" workingdir="${BuildManagementDir}" verbose="true">
    <arg value="-noprofile"/>
    <arg value="-nologo"/>
    <arg value="-noninteractive"/>
    <arg value="-command"/>
    <arg value=".\xyz.ps1"/>
</exec>
JiBéDoublevé
  • 4,124
  • 4
  • 36
  • 57
VJ M
  • 121
  • 1
  • 3
5

You could certainly use the exec task, setting the program attribute to powershell.exe and passing in the command line something like "-Command { }".

Alternatively, you could create a custom NAnt task that internally uses the powershell hosting APIs to execute your cmdlets or scripts. There's a simple example of this (using the PS v1 APIs) here.

tomasr
  • 13,683
  • 3
  • 38
  • 30
3

Based on JiBe's answer its the other way around, here is the working solution. When running powershell that takes arguments you need to run the powershell script then the arguments.

PS yourscript.ps1 -arg1 value1 -arg2 value2

In NAnt:

<exec program="powershell" workingdir="${powershell_dir}" verbose="true">
    <arg value=".\yourscript.ps1"/>    
    <arg value="-arg1 ${value1}"/>
    <arg value="-arg2 ${value2}"/>
</exec>

The best way I think is to define the arguments in PS for NAnt is like

$value1=$args[0]
$value2=$args[1]

So in command line you will use:

PS yourscript.ps1 some_value1 some_value2

Then this translates in NAnt like:

<property name="Value1" value="some_Value1" />
<property name="Value2" value="some_Value2" />

    <exec program="powershell" workingdir="${powershell_dir}" verbose="true">
        <arg value=".\yourscript.ps1"/>    
        <arg value="${value1}"/>
        <arg value="${value2}"/>
    </exec>
Geddon
  • 1,266
  • 1
  • 11
  • 31
0

The best way is to use similar methods as one would use in task scheduler. That means run powershell with the -command argument and begin the command with &.

For example:

<exec program="powershell" workingdir="${ifscriptrequires}" verbose="true">
    <arg line="-Command" />
    <arg line="$amp; C:\scripts\somescript.ps1 -SwitchParam -someargument 'somevalue' 'somepositionalparameter'" />
</exec>
Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
  • Could you please clarify your use of the ampersand? Without an explanation, your answer looks pretty much the same as [VJ M's answer](http://stackoverflow.com/a/4311491/622391)? – Simon MᶜKenzie Dec 15 '15 at 23:12
  • The ampersand is the call operator in powershell. The following is from the 'get-help about_operators' command output under special operators: '& Call operator Runs a command, script, or script block. The call operator, also known as the "invocation operator," lets you run commands that are stored in variables and represented by strings. Because the call operator does not parse the command, it cannot interpret command parameters.' – Paladin.Michael Jan 28 '16 at 21:59
  • 1
    To further clarify, In my experience, not including it can cause arguments to be processed by powershell.exe instead of the script or just lost in general. – Paladin.Michael Jan 28 '16 at 22:13