1

Possible Duplicate:
Any good PowerShell MSBuild tasks?

Powershell doesn't seem to have an easy way to trigger it with an arbitrary command and then bubble up parse and execution errors in a way that correctly interoperates with callers that are not PowerShell - e.g., cmd.exe, TeamCity etc.

My question is simple. What's the best way for me with OOTB MSBuild v4 and PowerShell v3 (open to suggestions-wouldnt rule out a suitably production ready MSBuild Task, but it would need to be a bit stronger than suggesting "it's easy - taking the PowerShell Task Factory sample and tweak it and/or becoming it's maintainer/parent") to run a command (either a small script segment, or (most commonly) an invocation of a .ps1 script.

I'm thinking it should be something normal like:

<Exec 
  IgnoreStandardErrorWarningFormat="true"
  Command="PowerShell &quot;$(ThingToDo)&quot;" />

That sadly doesn't work:-

  1. if ThingToDo fails to parse, it fails silently
  2. if ThingToDo is a script invocation that doesn't exist, it fails
  3. if you want to propagate an ERRORLEVEL based .cmd result, it gets hairy
  4. if you want to embed " quotes in the ThingToDo, it won't work

So, what is the bullet proof way of running PowerShell from MSBuild supposed to be? Is there something I can PsGet to make everything OK?

Community
  • 1
  • 1
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249

2 Answers2

2

You can use the following example:

<InvokeScript Condition="..."
              PowerShellProperties="..."
              ScriptFile="[PATH TO PS1 FILE]"
              Function="[FUNCTION TO CALL IN PS1]"
              Parameters="..."
              RequiredOutputParams="...">
  <!-- You can catch the output in an Item -->
  <Output TaskParameter="OutputResults"
          ItemName="Output" />
</InvokeScript>

This can be used in MSBuild.

Arpit
  • 6,212
  • 8
  • 38
  • 69
  • I assume you're referring to [a version of Bart de Smet's Task (which currently resides in the MSBuild Extension pack)](http://stackoverflow.com/a/3465029/11635)? That's the reason for my semi-weasely OOTB bit in the question – Ruben Bartelink Oct 10 '12 at 10:41
  • On reflection, thanks for making me realize this is a duplicate question. See http://stackoverflow.com/a/12817556/11635 Can you Vote to Close this question please (assuming you agree that is) – Ruben Bartelink Oct 10 '12 at 10:49
1

Weeeeelll, you could use something long winded like this until you find a better way:-

<PropertyGroup>
  <__PsInvokeCommand>powershell "Invoke-Command</__PsInvokeCommand>
  <__BlockBegin>-ScriptBlock { $errorActionPreference='Stop';</__BlockBegin>
  <__BlockEnd>; exit $LASTEXITCODE }</__BlockEnd>
  <_PsCmdStart>$(__PsInvokeCommand) $(__BlockBegin)</PsCmdStart>
  <_PsCmdEnd>$(__BlockEnd)"</PsCmdEnd>
</PropertyGroup>

And then 'all' you need to do is:

<Exec 
  IgnoreStandardErrorWarningFormat="true"
  Command="$(_PsCmdStart)$(ThingToDo)$(_PsCmdEnd)" />

The single redeeming feature of this (other than trapping all error types I could think of), is that it works OOTB with any PowerShell version and any MSBuild version.

I'll get my coat.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249