<p>Anyone know of any good MSBuild tasks that will execute a PowerShell script and pass it different parameters?</p>

<p>I was able to find <a href="http://bartdesmet.net/blogs/bart/archive/2008/02/16/invoking-powershell-scripts-from-msbuild.aspx" rel="nofollow noreferrer">B# .NET Blog: Invoking PowerShell scripts from MSBuild</a>, but I'm hoping for something that is a little more polished.</p>

<p>If I can't find anything I will of course just go ahead and polish my own using that blog post as a starter.</p>

[{'answer_id': 80276, 'author': 'Steven Murawski', 'author_id': 1233, 'author_profile': 'https://Stackoverflow.com/users/1233', 'pm_score': 3, 'selected': False, 'text': '<p>You might also want to look at <a href="https://github.com/psake/psake" rel="nofollow noreferrer">Psake</a> - a PowerShell based build environment.</p>\n'}, {'answer_id': 3465029, 'author': 'Ruben Bartelink', 'author_id': 11635, 'author_profile': 'https://Stackoverflow.com/users/11635', 'pm_score': 3, 'selected': False, 'text': '<p>One could use <a href="http://powershellmsbuild.codeplex.com/" rel="nofollow noreferrer">http://powershellmsbuild.codeplex.com/</a> for 3.5. <a href="https://web.archive.org/web/20171226175241/http://powershellmsbuild.codeplex.com/discussions/348378" rel="nofollow noreferrer">It\'d be nice if there was a NuGet package for it that one could leverage via NuGet package restore</a>.</p>\n<p>4.0 has a <a href="https://devblogs.microsoft.com/visualstudio/msbuild-task-factories-guest-starring-windows-powershell/" rel="nofollow noreferrer">Windows Powershell Task Factory</a> which <strike>you can get <a href="https://learn.microsoft.com/en-us/samples/browse/" rel="nofollow noreferrer">in the code gallery</a></strike> has been rolled into\n<a href="https://archive.codeplex.com/?p=msbuildextensionpack" rel="nofollow noreferrer">MSBuild Extension Pack (one of the top task libraries - 400+ Tasks &amp; recommended in Inside MSBuild)</a> has <code>PowerShellTaskFactory</code> (download the help file from <a href="https://web.archive.org/web/20150203103526/http://msbuildextensionpack.codeplex.com:80/releases/view/77212" rel="nofollow noreferrer">the download section of this example release</a> to have a peek).</p>\n'}, {'answer_id': 12817556, 'author': 'Ruben Bartelink', 'author_id': 11635, 'author_profile': 'https://Stackoverflow.com/users/11635', 'pm_score': 3, 'selected': False, 'text': '<p><a href="https://stackoverflow.com/questions/11648530/in-msbuild-how-do-i-run-something-powershell-and-have-all-errors-reported">Duplicate Question and Answer I Posted</a>, here for posterity for when it has been vote to closed. The key difference is that this question was constrained to being <strong>OOTB</strong> and my self-answer stays within that constraint.</p>\n\n<h1>Question</h1>\n\n<p>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., <code>cmd.exe</code>, <a href="https://stackoverflow.com/questions/11647987/how-do-i-get-errors-to-propagate-in-the-teamcity-powershell-runner">TeamCity</a> etc.</p>\n\n<p>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 <code>.ps1</code> script.</p>\n\n<p>I\'m thinking it should be something normal like:</p>\n\n<pre><code>&lt;Exec \n  IgnoreStandardErrorWarningFormat="true"\n  Command="PowerShell &amp;quot;$(ThingToDo)&amp;quot;" /&gt;\n</code></pre>\n\n<hr>\n\n<p>That sadly doesn\'t work:-</p>\n\n<ol>\n<li>if <code>ThingToDo</code> fails to parse, it fails silently</li>\n<li>if <code>ThingToDo</code> is a script invocation that doesn\'t exist, it fails</li>\n<li>if you want to propagate an <code>ERRORLEVEL</code> based <code>.cmd</code> result, it gets hairy</li>\n<li>if you want to embed <code>"</code> quotes in the <code>ThingToDo</code>, it won\'t work</li>\n</ol>\n\n<p>So, what is the bullet proof way of running PowerShell from MSBuild supposed to be? Is there something I can <a href="http://psget.net/" rel="nofollow noreferrer">PsGet</a> to make everything OK?</p>\n\n<h1>Answer</h1>\n\n<p>Weeeeelll, you could use something long winded like this until you find a better way:-</p>\n\n<pre><code>&lt;PropertyGroup&gt;\n  &lt;__PsInvokeCommand&gt;powershell "Invoke-Command&lt;/__PsInvokeCommand&gt;\n  &lt;__BlockBegin&gt;-ScriptBlock { $errorActionPreference=\'Stop\';&lt;/__BlockBegin&gt;\n  &lt;__BlockEnd&gt;; exit $LASTEXITCODE }&lt;/__BlockEnd&gt;\n  &lt;_PsCmdStart&gt;$(__PsInvokeCommand) $(__BlockBegin)&lt;/_PsCmdStart&gt;\n  &lt;_PsCmdEnd&gt;$(__BlockEnd)"&lt;/_PsCmdEnd&gt;\n&lt;/PropertyGroup&gt;\n</code></pre>\n\n<p>And then \'all\' you need to do is:</p>\n\n<pre><code>&lt;Exec \n  IgnoreStandardErrorWarningFormat="true"\n  Command="$(_PsCmdStart)$(ThingToDo)$(_PsCmdEnd)" /&gt;\n</code></pre>\n\n<p>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.</p>\n\n<p>I\'ll get my coat.</p>\n'}, {'answer_id': 41051774, 'author': 'Garrett Serack', 'author_id': 181469, 'author_profile': 'https://Stackoverflow.com/users/181469', 'pm_score': 2, 'selected': False, 'text': '<p>With a bit of fun, I managed to come up with a fairly clean way of making this work:</p>\n\n<pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;\n&lt;Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;\n  &lt;!-- #1 Place this line at the top of any msbuild script (ie, csproj, etc) --&gt;\n  &lt;PropertyGroup&gt;&lt;PowerShell&gt;# 2&gt;nul || type %~df0|find /v "setlocal"|find /v "errorlevel"|powershell.exe -noninteractive -&amp;amp; exit %errorlevel% || #&lt;/PowerShell&gt;&lt;/PropertyGroup&gt;\n\n  &lt;!-- #2 in any target you want to run a script --&gt;\n  &lt;Target Name="default" &gt;\n\n    &lt;PropertyGroup&gt; &lt;!-- #3 prefix your powershell script with the $(PowerShell) variable, then code as normal! --&gt;\n      &lt;myscript&gt;$(PowerShell)\n      #\n      # powershell script can do whatever you need.\n      #\n      dir ".\\*.cs" -recurse |% {\n        write-host Examining file named:  $_.FullName\n        # do other stuff here...\n      } \n      $answer = 2+5\n      write-host Answer is $answer !\n      &lt;/myscript&gt;\n    &lt;/PropertyGroup&gt;\n\n    &lt;!-- #4 and execute the script like this --&gt;\n    &lt;Exec Command="$(myscript)" EchoOff="true" /&gt; \n  &lt;/Target&gt;\n&lt;/Project&gt;\n</code></pre>\n\n<h1>Notes:</h1>\n\n<ul>\n<li>You can still use the standard Exec Task features! (see: <a href="https://msdn.microsoft.com/en-us/library/x8zx72cd.aspx" rel="nofollow noreferrer">https://msdn.microsoft.com/en-us/library/x8zx72cd.aspx</a>)</li>\n<li><p>if your powershell script needs to use &lt; > or &amp; characters, just place the contents in a CDATA wrapper:</p>\n\n<pre><code>&lt;script2&gt;&lt;![CDATA[  $(PowerShell)\n  # your powershell code goes here!\n  write-host "&lt;&lt;Hi mom!&gt;&gt;"\n]]&gt;&lt;/script2&gt;\n</code></pre></li>\n<li><p>if you want return items to the msbuild script you can get them:</p>\n\n<pre><code>&lt;script3&gt;$(PowerShell)\n  # your powershell code goes here!\n  (dir "*.cs" -recurse).FullName\n&lt;/script3&gt;\n\n&lt;Exec Command="$(script3)" EchoOff="true" ConsoleToMSBuild="true"&gt; \n    &lt;Output TaskParameter="ConsoleOutput" PropertyName="items" /&gt;\n&lt;/Exec&gt;\n&lt;Touch Files="$(items)" /&gt; \n</code></pre></li>\n</ul>\n\n<p>See! then you can use those items with another msbuild Task :D</p>\n'}]
['https://Stackoverflow.com/questions/78069', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3957/']