This project aims to make using MSBuild easier from powershell
PowerShell C# Batchfile
Latest commit a4182a0 Oct 16, 2016 @sayedihashimi sayedihashimi Merge branch 'dev'

README.md

psbuild

Build status

The main purpose of this project to provide a better experience calling msbuild.exe from PowerShell. When using psbuild by default you'll get:

  • the latest version of msbuild.exe on your machine
  • multi-core build
  • log files, three formats: detailed, diagnostic and markdown
  • 32 bit version of msbuild.exe. Using the 64 bit version accidently can cause issues

It also simplifies passing in properties, targets by handling the work to translate PowerShell syntax to the call to msbuild.exe.

psbuild also has some functionality that you can use to create and edit MSBuild files from PowerShell.

To see the full set of commands that psbuild makes available just execute.

Get-Command -Module psbuild

Getting Started

download and install psbulid

(new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/ligershark/psbuild/master/src/GetPSBuild.ps1") | iex

build an msbuild file

Invoke-MSBuild C:\temp\msbuild\msbuild.proj

build a file and specify Configuration, Platform and VisualStudioVersion

psbuild has first class support for some well known properties. Configuration, Platform and VisualStudioVersion are just a few.

Invoke-MSBuild C:\temp\msbuild\msbuild.proj -configuration Release -platform 'Mixed Platforms' -visualStudioVersion 14.0

build a file passing arbitrary properties

To pass in properties that psbuild doesn't have first class support just use the -properties parameter.

Invoke-MSBuild C:\temp\msbuild\msbuild.proj -properties @{'MyProperty01'='myp1';'MyProperty02'='myp2'}

build an msbuild file and execute a specific target

Invoke-MSBuild C:\temp\msbuild\msbuild.proj -targets Demo

build an msbuild file and execute multiple targets

Invoke-MSBuild C:\temp\msbuild\msbuild.proj -targets Build,Demo

how to get the log file for the last build

When calling Invoke-MSBuild log files will be written by default in a temp folder. You can access those log files using the Open-PSBuildLog after the build completes. There are three log files by default: detailed, diagnostic and markdown.

PS> Invoke-MSBuild C:\temp\msbuild\proj1.proj
# returns the detailed log in the default editor
PS> Open-PSBuildLog

# returns the log in markdown format
PS> Open-PSBuildLog markdown

# returns the diagnostic
PS> Open-PSBuildLog diagnostic

how to open the log directory

To see logs from previous builds use the Open-PSBuildLogDirectory command. In this directory you'll find a folder for each project, each with log files.

How to pass extra arguments to msbuild.exe

When you call Invoke-MSBuild the call to msbuild.exe will be constructed for you. If you need to add additional arguments to msbuild.exe you can use the -extraArgs parameter. For example if you wanted to attach a custom logger or write a log file to a specific location.

Invoke-MSBuild C:\temp\msbuild\msbuild.proj -extraArgs '/flp3:v=d;logfile="C:\temp\msbuild\msbuild.detailed.log"'

show msbuild reserved properties

When authoring MSBuild files you'll often need to use some of MSBuild's reserved properties. You can either look this up on the web, or use psbuild to give you the info.

Get-MSBuildReservedProperties

This will display the list of known reserved properties and their values.

show common msbuild escape characters

When authoring MSBuild files there are a few special characters that you'll need to escape. Instead of searching the web for the result you can simply call this.

Get-MSBuildEscapeCharacters

You can also create a new MSBuild file with the following

When creating a new MSBuild file from scratch most people copy an existing one and remove the contents. psbuild offers a command to enable you to easily create a new empty MSBuild project file.

New-MSBuildProject -filePath C:\temp\msbuild\fromps.proj

to see what commands are available

Get-Command -Module psbuild

Most functions have help defined so you can use get-help on most commands for more details.

How to add psbuild to your build script.

If you're automating your build process then you should make sure they are portable. You can add the function below to your build script, and call it before using psbuild. If psbuild is not already installed it will be downloaded.

<#
.SYNOPSIS
    You can add this to you build script to ensure that psbuild is available before calling
    Invoke-MSBuild. If psbuild is not available locally it will be downloaded automatically.
#>
function EnsurePsbuildInstlled{
    [cmdletbinding()]
    param(
        [string]$psbuildInstallUri = 'https://raw.githubusercontent.com/ligershark/psbuild/master/src/GetPSBuild.ps1'
    )
    process{
        if(-not (Get-Command "Invoke-MsBuild" -errorAction SilentlyContinue)){
            'Installing psbuild from [{0}]' -f $psbuildInstallUri | Write-Verbose
            (new-object Net.WebClient).DownloadString($psbuildInstallUri) | iex
        }
        else{
            'psbuild already loaded, skipping download' | Write-Verbose
        }

        # make sure it's loaded and throw if not
        if(-not (Get-Command "Invoke-MsBuild" -errorAction SilentlyContinue)){
            throw ('Unable to install/load psbuild from [{0}]' -f $psbuildInstallUri)
        }
    }
}

Debug mode

In many cases after a build it would be helpful to be able to answer questions like the following.

  • What is the value of x property?
  • What is the value of y property?
  • What would the expression '@(Compile->'%(FullPath)') be?

But when you call msbuild.exe the project that is built is created in memory and trashed at the end of the process. Invoke-MSBuild now has a way that you can invoke your build and then have a "handle" to your project that was built. Using this object you can evaluate the properties and items. To enable this you just need to pass in the -debugMode switch to Invoke-MSBuild (Note: this is actively under development so if you run into an problems please open an issue). Here are some examples of what you can do.

PS> $bResult = Invoke-MSBuild .\temp.proj -debugMode

PS> $bResult.EvalProperty('someprop')
default

PS> $bResult.EvalItem('someitem')
temp.proj

PS> $bResult.ExpandString('$(someprop)')
default

PS> $bResult.ExpandString('@(someitem->''$(someprop)\%(Filename)%(Extension)'')')
default\temp.proj

You can get full access to the ProjectInstance object with the ProjectInstance property.

More functionality is available via the ProjectInstance object.

PS> $bResult.ProjectInstance.GetItems('someitem').EvaluatedInclude
temp.proj

You can get the BuildResuilt via the BuildResult parameter.

PS> $bResult.BuildResult.OverallResult
Failure

Reporting Issues

To report any issues please create an new item on the issues page.

Release Notes

Contributing

Contributing is pretty simple. The project mostly consists of one .psm1 file located at /src/psbuild.psm1. You should send PRs to the dev branch. If it's a simple bug fix feel free to go ahead and submit the fix as a PR. If you have a feature please propose it in the issues section so that we can dicsuss your idea.

Credits

This project uses the following open source components.