[cmdletbinding()] param( $versionToInstall = '1.2.0-beta', $appDataDir = ("$env:LOCALAPPDATA\LigerShark\psbuild\"), $nugetDownloadUrl = 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', $nugetSource = 'https://api.nuget.org/v3/index.json' ) function GetPsModulesPath{ [cmdletbinding()] param() process{ $Destination = $null if(Test-Path 'Env:PSModulePath'){ $ModulePaths = @($Env:PSModulePath -split ';') $ExpectedUserModulePath = Join-Path -Path ([Environment]::GetFolderPath('MyDocuments')) -ChildPath WindowsPowerShell\Modules $Destination = $ModulePaths | Where-Object { $_ -eq $ExpectedUserModulePath} | Select-Object -First 1 if (-not $Destination) { $Destination = $ModulePaths | Select-Object -Index 0 } } $Destination } } # originally based off of the scrit at http://psget.net/GetPsGet.ps1 function Install-PSBuild { # this will download using nuget if its not in %temp% [System.IO.FileInfo]$psbPsm1File = GetPsBuildPsm1 if($psbPsm1File -eq $null){ throw ('Unable to locate psbuild.psm1 file as expected') } [System.IO.FileInfo]$modsFolder = $null try{ $modsFolder= GetPsModulesPath } catch{ 'Error installing psbuld to modules folder: {0}' | Write-Error } $moduleFile = $null if(-not [string]::IsNullOrWhiteSpace($modsFolder)){ $destFolder = (join-path $modsFolder.FullName 'psbuild\') $destFile = (join-path $destFolder 'psbuild.psm1') if(!(test-path $destFolder)){ new-item -path $destFolder -ItemType Directory -Force | out-null } Copy-Item -Path "$($psbPsm1File.Directory.FullName)\*" -Destination $destFolder -Recurse $moduleFile = $destFile } else{ $moduleFile = Join-Path $psbPsm1File.Directory.FullName 'psbuild.psd1' } if ((Get-ExecutionPolicy) -eq "Restricted"){ Write-Warning @" Your execution policy is $executionPolicy, this means you will not be able import or use any scripts including modules. To fix this change your execution policy to something like RemoteSigned. PS> Set-ExecutionPolicy RemoteSigned For more information execute: PS> Get-Help about_execution_policies "@ } else{ Import-Module -Name $moduleFile -DisableNameChecking -Force } Write-Output "psbuild is installed and ready to use" Write-Output @" USAGE: PS> Invoke-MSBuild 'C:\temp\msbuild\msbuild.proj' PS> Invoke-MSBuild C:\temp\msbuild\path.proj -properties (@{'OutputPath'='c:\ouput\';'visualstudioversion'='12.0'}) -extraArgs '/nologo' For more details: get-help Invoke-MSBuild Or visit http://msbuildbook.com/psbuild "@ } <# .SYNOPSIS If nuget is in the tools folder then it will be downloaded there. #> function Get-Nuget{ [cmdletbinding()] param( $toolsDir = $appDataDir, $nugetDownloadUrl = 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' ) process{ $nugetDestPath = Join-Path -Path $toolsDir -ChildPath nuget.exe if(!(Test-Path $nugetDestPath)){ $nugetDir = ([System.IO.Path]::GetDirectoryName($nugetDestPath)) if(!(Test-Path $nugetDir)){ New-Item -Path $nugetDir -ItemType Directory | Out-Null } 'Downloading nuget.exe' | Write-Verbose (New-Object System.Net.WebClient).DownloadFile($nugetDownloadUrl, $nugetDestPath) # double check that is was written to disk if(!(Test-Path $nugetDestPath)){ throw 'unable to download nuget' } } # return the path of the file $nugetDestPath } } function Invoke-CommandString{ [cmdletbinding()] param( [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)] [string[]]$command, [switch] $ignoreErrors ) process{ foreach($cmdToExec in $command){ 'Executing command [{0}]' -f $cmdToExec | Write-Verbose cmd.exe /D /C $cmdToExec | Out-Null if(-not $ignoreErrors -and ($LASTEXITCODE -ne 0)){ $msg = ('The command [{0}] exited with code [{1}]' -f $cmdToExec, $LASTEXITCODE) throw $msg } } } } # see if the particular version is installed under %temp% function GetPsBuildPsm1{ [cmdletbinding()] param( $toolsDir = $appDataDir, $nugetDownloadUrl = 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' ) process{ if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory | out-null } $psbuildPsm1 = (Get-ChildItem -Path "$toolsDir\psbuild.$versionToInstall" -Include 'psbuild.psm1' -Recurse -ErrorAction SilentlyContinue | Sort-Object -Descending -ErrorAction SilentlyContinue | Select-Object -First 1 -ErrorAction SilentlyContinue) if(!$psbuildPsm1){ try{ Push-Location | Out-Null Set-Location ((Resolve-Path $toolsDir).ToString()) | Out-Null 'Downloading psbuild to the toolsDir' | Write-Verbose # nuget install psbuild -Version 0.0.3-beta -Prerelease -OutputDirectory C:\temp\nuget\out\ $cmdArgs = @('install','psbuild','-Version',$versionToInstall,'-Prerelease','-source',$nugetSource) $nugetPath = (Get-Nuget -toolsDir $toolsDir -nugetDownloadUrl $nugetDownloadUrl) 'Calling nuget to install psbuild with the following args. [{0} {1}]' -f $nugetPath, ($cmdArgs -join ' ') | Write-Verbose $command = '"{0}" {1}' -f $nugetPath,($cmdArgs -join ' ') $command | Invoke-CommandString | Out-Null $psbuildPsm1 = (Get-ChildItem -Path "$toolsDir\psbuild.$versionToInstall" -Include 'psbuild.psm1' -Recurse | Sort-Object -Descending | Select-Object -First 1) } finally{ Pop-Location | Out-Null } } if(!$psbuildPsm1){ throw ("psbuild not found, and was not downloaded successfully. sorry.`n`tCheck your nuget.config (default path={0}) file to ensure that nuget.org is enabled.`n`tYou can also try changing the versionToInstall value.`n`tYou can file an issue at https://github.com/ligershark/psbuild/issues." -f ("$env:APPDATA\NuGet\NuGet.config")) } $psbuildPsm1 } } function Repair-ToolsDir{ [CmdletBinding()] param($toolsDir = $appDataDir) process{ $systemDir = [Environment]::GetFolderPath('System') if ($toolsDir.StartsWith($systemDir) -and ($PSVersionTable.CLRVersion.Major -ge 4)) { $sysWowDir = [Environment]::GetFolderPath('SystemX86') $toolsDir = $toolsDir.Replace($systemDir, $sysWowDir) } $toolsDir } } $appDataDir = Repair-ToolsDir $appDataDir Install-PSBuild