JochemQuery
JochemQuery

Reputation: 1547

Executing msbuild task from powershell

I am following this blog: http://sedodream.com/2010/04/26/ConfigTransformationsOutsideOfWebAppBuilds.aspx

it's linked in this question as answer: Web.Config transforms outside of Microsoft MSBuild?

Every step works as described but I want to call the transformation from a powershell script. I want to do this command in powershell msbuild trans.proj /t:Demo I found some forums saying that I should use invoke-expression

When I try I get this error

Powershell:

Invoke-Expression $msbuild transformCommand.proj /t:Demo

Result

Invoke-Expression : Cannot bind argument to parameter 'Command' because it is null.
At D:/Somewhere
+ Invoke-Expression <<<<  $msbuild transformCommand.proj /t:Demo
    + CategoryInfo          : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpre
   ssionCommand

I also tried:

Invoke-Expression msbuild transformCommand.proj /t:Demo

With result

 D:\Somewhere
Invoke-Expression : A positional parameter cannot be found that accepts argument 'transformCommand.proj'.
At D:\Redgate\Communited.Timeblockr.Api\PreDeploy1.ps1:14 char:18
+ Invoke-Expression <<<<  msbuild transformCommand.proj /t:Demo
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Expression], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeExpressionCommand

Small note: this is my first time using powershell.

TransformCommand.proj

<Project ToolsVersion="4.0" DefaultTargets="Demo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <UsingTask TaskName="TransformXml"
             AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll"/>
    <Target Name="Demo">
        <TransformXml Source="Web.Test.config"
                      Transform="transform.xml"
                      Destination="Web.acceptatie.config"/>
    </Target>
</Project>

My questions are: Is this possible? And how is it possible?

Edit:

$a = "Path\transformCommand.proj /t:Demo"
#Invoke-Expression $msbuild $a

Start-Process -FilePath "C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" -ArgumentList $a | Write-Host 

This actually does everything I need..

Still if there are ways to do this more "indepent" or better ways, please post it.

Upvotes: 5

Views: 26980

Answers (3)

mvndaai
mvndaai

Reputation: 3831

If you add all the differences from the %PATH% from the Developer Command Prompt for VS... to powershell then you can run msbuild in powershell just like you would in the command prompt and everything seems to work. You also need to copy the variable %VCInstallDir%.

Here is a powershell function that I wrote to get the differences.

function Find-Path-Differences {
    $defaultPath = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
    $env:path.split(';') | Sort-Object -Unique | Where-Object { $defaultPath.split(';') -notcontains $_ }  | Foreach-Object { "`$env:path += `";$_`"`r" } | echo
    echo "function VCInstallDir {return `"$VCInstallDir`"}`r"
}

If you open powershell and type echo $profile that will give you a filepath. Create or open the file then paste the function into it and the function will be available when powershell starts. Then in the Developer Command Prompt ... run this command:

powershell Find-Path-Differences

And out will pop a bunch of lines like these:

$env:path += ";C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\\MSBuild\15.0\bin"
...
$env:path += ";C:\Windows\Microsoft.NET\Framework\v4.0.30319"

Copy and paste those lines into the file from echo $profile then open a new powershell window and you can now use msbuild in powershell.

Upvotes: 1

BrandonAGr
BrandonAGr

Reputation: 6017

I ended up doing the following to build a solution with multiple parameters

&$msbuildExe ('solution.sln','/verbosity:q','/p:configuration=Release','/t:Clean,Build')
if (!$?) {
    echo "!!! ABORTING !!!";pause;exit    
}

Upvotes: 1

otaku
otaku

Reputation: 964

Make sure you define the PowerShell variable $msbuild as below before calling Invoke-Expression $msbuild

$msbuild = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"

Upvotes: 9

Related Questions