How to invoke MSBuild from PowerShell using & operator?

The issues you are seeing results from PowerShell parsing arguments. In the first example, when PowerShell sees $a it passes it as a single parameter msbuild. We can see this using the echoargs utility from PSCX:.

PS> $a = "C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build"
PS> & echoargs $a
Arg 0 is <C:\some\project\or\other\src\Solution.sln /target:Clean /target:Build>

The second example is even worse because you are telling powershell to invoke "$echoargs $a" as the command name and it isn't a valid command name.

The third line works because CMD.exe gets the expanded form of "$echoargs $a" as a single argument which is parses and executes:

You have a couple of options here. First I do it this way:

PS> & $msbuild C:\some\project\or\other\src\Solution.sln `
    /target:Clean /target:Build

The other option is to use Invoke-Expression like so:

PS> Invoke-Expression "$msbuild $a"

In general I try to be very careful with Invoke-Expression particularly if any part of the string that gets invoked is provided by the user.


Ugh.

$collectionOfArgs = @("C:\some\project\or\other\src\Solution.sln", 
    "/target:Clean", "/target:Build")
& $msbuild $collectionOfArgs

This works. & takes a collection of arguments, so you must split up strings containing multiple arguments into a collection of string arguments.


You can also try using the free Invoke-MsBuild powershell script/module. This essentially gives you an Invoke-MsBuild PowerShell cmdlet that you can call instead of trying to invoke the msbuild.exe manually yourself.

Tags:

Powershell