Nant run exec task under different user - nant

It is possible to run Exec task with different domain and user ?
I need to restart iis on 10 load balancers , can this be achieved with Nant exe task ?
For now I have script like
<exec programm='iisreset'>
<arg line='${balancer}'/>
<arg line='/restart' />
</exec>
This is working on Integration environment (Since the same domain) , and on test it fails with Acces Denied..
Thanks

You could use the command runas in you exec call and use the the /netonly argument for remote access to your balancers.
I guess this could look something like this:
<exec program="runas">
<arg line="/netonly" />
<arg line="${'/user:' + domain + '\' + username}" />
<arg line="${'"iisreset ' + balancer + ' /restart"'}" />
</exec>
This could work for you but I am not sure how you are going to give him the password automatically. You could run runas with /savecred in your cmd once though. But be careful about saving your passwords...
Note that I could not test this as I don't have the required environment to do so.
Source: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/runas.mspx?mfr=true

Related

Can't run psql from an ant target running in NetBeans 8.0.2

I'm running PostgreSQL 9.2 on Windows 7. I'm trying to run an Ant target using an apply tag with the executable property set to psql from a NetBeans 8.0.2 build file. I have created a pgpass.conf file in the right place with the correct password for the postgres user and I can run psql at a command prompt without having to enter a password. But when I run the Ant target, I get an error message in the output file saying the target failed because no password was supplied. What am I doing wrong? The target looks like this:
<filelist id="create-dbfiles" dir="${root}" files="createdb.sql"/>
<target name="create-db">
<apply executable="psql" addsourcefile="false" output="output.txt">
<arg value="-U postgres" />
<arg value="-w" />
<filelist refid="create-dbfiles"/>
<redirector>
<inputmapper type="glob" from="*" to="${root}\*" />
</redirector>
</apply>
</target>
a_horse_with_no_name got me thinking about the exec tag but trying to run psql directly via an exec tag or an apply tag still threw up errors about a password not being supplied. Then I realised that psql ran smoothly from the cmd prompt. I started playing around with calling cmd.exe and passing a command to the command line, and found a solution:
<filelist id="clean-dbfiles" dir="${root}" files="cleandb.sql"/>
<target name="clean-db">
<apply executable="cmd.exe" addsourcefile="true" >
<filelist refid="clean-dbfiles"/>
<env key="PGPASSWORD" value="rootpassword"></env>
<arg value="/c"></arg>
<arg value="psql -w -U postgres -f " />
<srcfile />
</apply>
</target>
<filelist id="create-dbfiles" dir="${root}" files="createdb.sql"/>
<target name="create-db">
<apply executable="cmd.exe" addsourcefile="true" >
<filelist refid="create-dbfiles"/>
<env key="PGPASSWORD" value="rootpassword"></env>
<arg value="/c"></arg>
<arg value="psql -w -U postgres -f "/>
<srcfile />
</apply>
</target>
Here are the two key targets for creating a build script for a postgres database. Note the following points:
Run cmd.exe not psql directly
Set addsourcefile to true because I want to call neat little self-contained SQL files for each target.
Use apply with a filelist because for my createtables or populate targets I may have a directory of separate SQL files
Give up on hoping to invoke the pgpass.conf file. For some reason Ant in NetBeans can't access it. Resort to the PGPASSWORD environment key and set it to the desired password. This is running locally for development purposes so security isn't an issue.
You need to pass the /c switch to cmd.exe so that you can then pass a command line. I didn't separate the psql command line into separate arguments because I think the complete line is being passed to cmd.exe as a single argument.
addsourcefile is set to true so each file in the filelist is appended to the psql command line just after the -f switch and everything works a treat.
Voilà! What a fuss! I had no similar difficulty with MySql because you can pass the password to the command line directly.

EXEC timeout not work with matlab application

I have used EXEC task to open matlab in build.xml file. I have added timeout in EXEC task for terminate the task after some time. But problem is that, matlab is open and model is also building in matlab but after timeout the exec task not terminate.
<property name="BuildEngine.calc.matlabApp" value="C:\MATLAB\R2010bSP2\bin\matlab.exe"/>
<property name="modelProjectDirectory" value="${basedir}\..\${Config.ModelProject}"/>
<exec executable="${BuildEngine.calc.matlabApp}" dir="${modelProjectDirectory}" timeout="60000">
<arg value="-r"/>
<arg value="OutputResolvedParameters"/>
</exec>
after 1 min EXEC task not terminate and matlab still running.
One thing is sure: you cannot yet set up a timout on an RTC build: the Enhancement 106064 (you need a jazz account to see it) is "triaged".
Regarding the ant exec task, try adding a spawn=true attribute:
If you run Ant as a background process (like ant &) and use the <exec> task with spawn set to false, you must provide explicit input to the forked process or Ant will be suspended because it tries to read from the standard input.

Exception running powershell script from MSBuild Exec Task

i´m having a problem with MSBuild and Powershell. There is a PS-script that i want to execute within the MSBuild exec-Task.
The Problem: Running the Script direct from CMD works, but running the script within MSBuild I get an error.
Here the MSBuild script:
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<PathToSvnClient>C:\Program Files (x86)\CollabNet\Subversion Client</PathToSvnClient>
</PropertyGroup>
<ItemGroup>
<!-- set Folder to Svn Repository for svn info command-->
<SvnFolder Include="$(MSBuildProjectDirectory)\.."/>
</ItemGroup>
<Target Name="SvnInfo">
<!-- get SVN Revision and Repository Path -->
<SvnInfo LocalPath="%(SvnFolder.FullPath)" ToolPath="$(PathToSvnClient)">
<Output TaskParameter="Revision" PropertyName="Revision" />
<Output TaskParameter="RepositoryPath" PropertyName="RepositoryPath" />
</SvnInfo>
</Target>
<Target Name="SetProductVersion" DependsOnTargets="SvnInfo">
<Exec Command="powershell -file "Scripts\SetSth.ps1" -PARAM "$(PathToSth)" -SVNID $(Revision) -SVNFOLDER "$(RepositoryPath)"" LogStandardErrorAsError="true" ContinueOnError="false"/>
</Target>
The Command is executed exactly the same way as on CMD, but i get an exception from the Powershell Script for the SVNFOLDER param.
The Command that is executed looks like this:
powershell -file "Scripts\SetSth.ps1" -PARAM "C:\abc\cde" -SVNID 1234
-SVNFOLDER "https://domain/svn/rep/branches/xy%20(Build%2012)"
So from CMD it works, from within MSBuild not. I have no idea why. I hope you got an idea.
What about this approach playing with double and singles quotes:
<Target Name="SetProductVersion" DependsOnTargets="SvnInfo">
<Exec Command="powershell -command "& {Scripts\SetSth.ps1 -PARAM '$(PathToSth)' -SVNID '$(Revision)' -SVNFOLDER '$(RepositoryPath)'}"" LogStandardErrorAsError="true" ContinueOnError="false"/>
</Target>
Double check your paths.
Remember, powershell invoked in this way runs as Msbuild.exe under whatever user is executing the build. To msbuild.exe, a straight call to cmd.exe is going to start in the working directory where msbuild lives.
Assume -file "Scripts\SetSth.ps1" references C:\users\yourusername\Scripts\SetSth.ps1
So for you, calling cmd.exe and running that may work just fine, b/c your working directory is going to match C:\users\yourusername
For msbuild.exe, its likely unable to find that file, as its starting in something like *C:\Windows\Microsoft.NET\Framework\v4.0*
So it's looking for C:\Windows\Microsoft.NET\Framework\v4.0\Scripts\SetSth.ps1
I would try making that file path fully qualified. If that still doesn't work, have cmd.exe dump its results into a property and have msbuild log it. Then you can review the paths.

deploy tools: get a list of actions the tool will execute without executing the deploy script

We're in the process of evaluating MSBuild and Nant for deploys. We may roll our own tool. One thing that a different business unit -- let's call it DeptA -- would really like to have (as in it better have it) is the ability for someone in DeptA to read the script and see what it will do. Currently we do this with .bat files. We hates the bat files. Nasty nasty bat files's. But if we ask DeptA to learn a new script language (nant, msbuild) they may be resistant.
Ideally the build tool of choice would be able kick out a list of actions without doing anything else. Along the lines of:
Stop service ABC on server Z
Stop service DEF on server Z
Copy all files from
\server\dirA\dirB to \server2\dirC
Start service ABC on server Z
Start service DEF on server Z
Run all scripts in dir
\server\dirA\dirC
Is it possible to do this with MSBuild? NAnt? Without me re-learning XSL?
If I was you I would actually blend MSBuild and MSDeploy. You should have your MSBuild script perform the actions like start/stop service etc. Then let MSDeploy to the file copy. With MSDeploy you can use the -whatif switch to indicate that you only want a report of the actions to be executed instead of actually executing it. MSBuild unfortunately doesn't offer such an option out of the box you will have to "build" that into your scripts. You can do this with properties and conditions. For example it might look something like this:
<Project ...>
<PropertyGroup>
<!--
Create the property to use, and declare a default value.
Here I've defaulted this to true because it is better to force the
caller to explicitly specify when to perform the action instead of it
being the default.
-->
<SimulateExecution Condition= '$(SimulateExecution)'==''>true</SimulateExecution>
</PropertyGroup>
<Target Name="Deploy">
<Message Text="Deploy started" />
<Message Text="Stop service ABC on server Z"/>
<WindowsService ... Condition=" '$(SimulateExecution)'=='false' "/>
<Message Text="Stop service DEF on server Z"/>
<WindowsService ... Condition=" '$(SimulateExecution)'=='false' "/>
<!-- Call MSDeploy with the Exec task. -->
<PropertyGroup>
<MSDeployCommand>...\msdeploy.exe YOUR_OPTIONS_HERE</MSDeployCommand>
<!-- Append the -whatif to the command if this is just a simulation -->
<MSDeployCommand Condition= '$(SimulateExecution)'=='false' ">$(MSDeployCommand) -whatif</MSDeployCommand>
</PropertyGroup>
<Exec Command="$(MSDeployCommand)" />
... More things here
</Target>
</Project>
For the service actions you can use the WindowsService task from the MSBuild Extension Pack. You will have to fill in the blanks there.
When you call MSDeploy you should just use the Exec task to invoke msdeploy.exe with your parameters. If you pass the -whatif it will not actually perform the actions, just report what it would have done. These will be logged to the msbuild log. So if you invoke msbuild.exe with /fl you will get those actions written out to a file. The only issue that I've seen when taking this approach is that for msdeploy.exe you many times have to use full paths (those without ..) which can sometimes be tricky so be wary of such paths.

What's a good way to consume a PowerShell Cmdlet in a NAnt build system?

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?
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>
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.
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>
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>