PowerShell.PowerLibrary.MSBuildUtilizer.psm1

#region Variables
$VisualStudioVersion = '15.0';
$BuildTargetFramework = '4.6.1';

$MsBuildPossiblePaths = New-Object System.Collections.ArrayList;
$MsBuildPossiblePaths.Add('C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe');
$MsBuildPossiblePaths.Add('C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe');
$MsBuildPossiblePaths.Add('C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe');
$MsBuildPossiblePaths.Add('C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe');
#endregion

#region Functions

FUNCTION Get-MsBuild
{    
    IF($MsBuildPossiblePaths -eq $null)
    {
        Log-Error '$MsBuildPossiblePaths Cannot be null. Override $MsBuildPossiblePaths in your context';
    }
    FOREACH($Path in $MsBuildPossiblePaths)
    {
        IF([System.IO.File]::Exists($Path))
        {
            return $Path;
        }
    }
    return $null;
}

FUNCTION Start-SolutionsBuild
{
    <#
    .Synopsis
        Builds list of solutions/projects in sequence.
    .DESCRIPTION
        Builds list of solutions/projects in sequence.
    .PARAMETER ProjectSolutions
        Array of Solution or Project Paths.
    .PARAMETER BuildConfiguration
        This is Build Configuration either Debug or Release.
    .PARAMETER Path
        This is the URL Paths to loop through.
    .PARAMETER OutputPath
        This is the Path where to save the Formatted Template.
    .PARAMETER IncludedExtensions
        Array of all file extensions need to be looked up.
    .NOTES
        Depends on Global variables that might be overwritten:
        * $MsBuildPossiblePaths
        * $VisualStudioVersion
        * $BuildTargetFramework
 
        Defaults
        $VisualStudioVersion = '15.0';
        $BuildTargetFramework = '4.6.1';
 
        $MsBuildPossiblePaths = New-Object System.Collections.ArrayList;
        $MsBuildPossiblePaths.Add('C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe');
        $MsBuildPossiblePaths.Add('C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe');
        $MsBuildPossiblePaths.Add('C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe');
    #>


    param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline=$true, Position = 0)]
        [Alias('P')]
        [ValidateNotNullOrEmpty()]
        [System.Collections.ArrayList]
        $ProjectSolutions,

        [Parameter(Mandatory = $true, ValueFromPipeline=$true, Position = 1)]
        [Alias('Configuration')]
        [ValidateSet('Debug','Release')]
        [string]
        $BuildConfiguration,

        [Parameter(Mandatory = $false, ValueFromPipeline=$true, Position = 2)]
        [Alias('Progress')]
        [switch]
        $WithProgress
    );

    Write-Host "Building Solutions" -ForegroundColor Cyan;
    Write-Host;
    Write-Host "Visual Studio Version: " -NoNewline -ForegroundColor Yellow;
    Write-Host $VisualStudioVersion -ForegroundColor White;
    Write-Host "TargetFramework: " -NoNewline -ForegroundColor Yellow;
    Write-Host $BuildTargetFramework -ForegroundColor White;
    Write-Host "Build Mode: " -NoNewline -ForegroundColor Yellow;
    SWITCH($BuildConfiguration)
    {
        'Debug'
        {
            Write-Host $BuildConfiguration -ForegroundColor Red;
        }
        'Release'
        {
            Write-Host $BuildConfiguration -ForegroundColor Green;
        }
    }
    Write-Host;
    $msBuild = Get-MsBuild;
    IF($msBuild -eq $null)
    {
        Log-Error 'Unable to locate MSBuild.';
    }
    Write-Host "MSBuild Path: [$msBuild]" -ForegroundColor DarkYellow;
    IF($ProjectSolutions -eq $null)
    {
        Log-Error '$ProjectSolutions cannot be null.`r`nOverride $ProjectSolutions in your context';
    }
    IF($ProjectSolutions.Count -eq 0)
    {
        Write-Host 'Override $ProjectSolutions in your context to implement an array of solutions';
    }
    IF($WithProgress)
    {
        $Total = $ProjectSolutions.Count;
        $Index = 0;
        $Progress = 0;
        IF($Total -gt 0) 
        {
            $Progress = $Index /$Total * 100;
        }
        Write-Progress -Activity "Building Solutions" -Status "----" -PercentComplete 0;
    }
    foreach($ProjectSolution in $ProjectSolutions)
    {
        IF($WithProgress)
        {
            IF($Total -gt 0) 
            {
                $Progress = $Index /$Total * 100;
            }

            Write-Progress -Activity "Building Solution" -Status $ProjectSolution -PercentComplete $Progress;
        }
        
        Write-Host "***MS-BUILD***Started***" -ForegroundColor Gray;
        Write-Host $ProjectSolution -ForegroundColor Yellow;

        #& $msbuild $ProjectSolution /t:build /clp:ErrorsOnly /p:Configuration=Release /p:TargetFramework=v4.5 ("/p:VisualStudioVersion=$VisualStudioVersion");
        & $msbuild $ProjectSolution /t:build /clp:ErrorsOnly ("/p:Configuration=$BuildConfiguration") ("/p:TargetFramework=$BuildTargetFramework") ("/p:VisualStudioVersion=$VisualStudioVersion");

        Write-Host "***MS-BUILD***Ended***" -ForegroundColor Gray;
        Write-Host;

        IF($WithProgress)
        {
            $Index ++;
        }
    }    
    IF($WithProgress)
    {
        Write-Progress -Activity "Building Solutions Completed" -Status "----" -PercentComplete 100 -Completed:$true;
    }
    Write-Host "Buidling Solutions: " -NoNewline -ForegroundColor Cyan;
    Write-Host "Completed`n" -ForegroundColor White;
}
#endregion