Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run powershell script during MSBuild

I have a .NET Framework 4.5.2 WebAPI2 project. While building the project in Visual Studio, I want a powershell script I wrote to run before each and every build. If the powershell script exits with any non-zero code, I want the build to fail and the error message from the powershell script visible in the Visual Studio output.

This is how I've modified my csproj file so far:

<Project ToolsVersion="12.0" DefaultTargets="MyCustomTarget;Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<Target Name="MyCustomTarget">
  <PropertyGroup>
    <PowerShellExe Condition=" '$(PowerShellExe)'=='' "> 
      %WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe
    </PowerShellExe>
    <ScriptLocation Condition=" '$(ScriptLocation)'=='' ">
      C:\Code\MyScript.ps1
    </ScriptLocation>
  </PropertyGroup>
  <Exec Command="$(PowerShellExe) -NonInteractive -executionpolicy Unrestricted -command &quot;&amp; { $(ScriptLocation) } &quot;" />
</Target>

For simplicity's sake, my script is the following:

if(((get-date -Format "mm") % 2) -eq 0){ exit 0 } else { write-error "The minute is not equally divisible by 2.";exit 1 }

However, when I go to build the project, I now see my powershell script open in notepad and the build stops until I close notepad. Once closed, I'm getting an error and I am not finding any way of resolving the error. Any assistance would be much appreciated.

The command " 
    %WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe
   -NonInteractive -executionpolicy Unrestricted -command "& { 
    C:\Code\MyScript.ps1
   } "" exited with code 9009.  MyWebApi2Project    C:\Code\MySolution\MyWebApi2Project\MyWebApi2Project.csproj 269 
like image 509
mckennawebdev Avatar asked Sep 20 '18 20:09

mckennawebdev


2 Answers

I was able to get everything working by changing the following. This builds off of Apoorva's answer:

<Target Name="BeforeBuild">
  <TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" /><!-- existing line, not part of answer -->
  <Exec Command="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -executionpolicy Unrestricted -command &quot;&amp; { .\MyScript.ps1 } &quot;" LogStandardErrorAsError="True" ContinueOnError="False" WorkingDirectory="$(MSBuildProjectDirectory)" />
</Target>

For me, the inclusion of PowerShellExe and ScriptLocation variables were both causing an error. Removing these lines and stripping the Exec line down fixed the issue. The inclusion of 'ContinueOnError="False"' and 'LogStandardErrorAsError="True"' ensured the build process would halt if a non-zero exit code was thrown by the powershell script.

like image 169
mckennawebdev Avatar answered Oct 02 '22 13:10

mckennawebdev


I edited the Target Name="BeforeBuild" as below instead of creating new Target. So before start of the build the powershell script is executed and build is passed or failed accordingly

<Target Name="BeforeBuild">
   <PropertyGroup>
    <PowerShellExe Condition=" '$(PowerShellExe)'=='' "> 
     C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    </PowerShellExe>
    <ScriptLocation Condition=" '$(ScriptLocation)'=='' ">
      C:\Code\MyScript.ps1
    </ScriptLocation>
  </PropertyGroup>
  <Exec Command="$(PowerShellExe) -NonInteractive -executionpolicy Unrestricted -command &quot;&amp; { $(ScriptLocation) } &quot;" />
  </Target>

(Edited to add 's' to windows)

like image 40
Apoorva Raju Avatar answered Oct 02 '22 12:10

Apoorva Raju