Pentia.Publish-WebProject.psm1
<#
.SYNOPSIS Publishes a web project to the specified output directory using MSBuild. .PARAMETER WebProjectFilePath Absolute or relative path of the web project file. .PARAMETER OutputPath Absolute or relative path of the output directory. .PARAMETER MSBuildExecutablePath Absolute or relative path of MSBuild.exe. If null or empty, the script will attempt to find the latest MSBuild.exe installed with Visual Studio 2017 or later. .EXAMPLE Publish-WebProject -WebProjectFilePath "C:\Path\To\MyProject.csproj" -OutputPath "C:\Websites\MyWebsite" Publish a project. .EXAMPLE Publish-WebProject -WebProjectFilePath "C:\Path\To\MyProject.csproj" -OutputPath "C:\Websites\MyWebsite" -MSBuildExecutablePath "C:\Path\To\MsBuild.exe" Publish a project and specify which MSBuild.exe to use. #> function Publish-WebProject { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline)] [string]$WebProjectFilePath, [Parameter(Mandatory = $true)] [string]$OutputPath, [Parameter(Mandatory = $false)] [string]$MSBuildExecutablePath ) process { if (!(Test-Path $WebProjectFilePath -PathType Leaf)) { throw "File path '$WebProjectFilePath' not found." } if (-not ([System.IO.Path]::IsPathRooted($OutputPath))) { $OutputPath = [System.IO.Path]::Combine($PWD, $OutputPath) } Write-Verbose "Publishing '$WebProjectFilePath' to '$OutputPath'." $buildArgs = @( "/t:WebPublish", "/p:WebPublishMethod=FileSystem", "/p:PublishUrl=""$OutputPath""", "/p:DeleteExistingFiles=false", "/p:MSDeployUseChecksum=true", "/m" ) Invoke-MSBuild -MSBuildExecutablePath $MSBuildExecutablePath -ProjectOrSolutionFilePath $WebProjectFilePath -BuildArgs $buildArgs } } <# .SYNOPSIS Publishes a web project to the specified output directory using MSBuild and applies all relevant XDTs. .DESCRIPTION Publishes a web project to the specified output directory using MSBuild and applies all relevant XDTs. The XDTs are then deleted. Optional function parameters which are omitted, will be read from the settings found in "<solution root>\.pentia\user-settings.json". If no settings file exists, the user is prompted for input. .PARAMETER WebProjectFilePath Absolute or relative path of the web project file. .PARAMETER OutputPath Absolute or relative path of the output directory. .EXAMPLE Publish-ConfiguredWebProject -WebProjectFilePath "C:\Path\To\MyProject.csproj" -OutputPath "C:\Websites\MyWebsite" -BuildConfiguration "Debug" Publish a project, and apply all XDTs for the "Debug" configuration. .EXAMPLE Publish-ConfiguredWebProject -WebProjectFilePath "C:\Path\To\MyProject.csproj" -OutputPath "C:\Websites\MyWebsite" -BuildConfiguration "Debug" -MSBuildExecutablePath "C:\Path\To\MsBuild.exe" Publish a project, apply all XDTs for the "Debug" configuration, and use the specified MSBuild.exe. "./MyProject.csproj" | Publish-ConfiguredWebProject Publish the project "MyProject.csproj", using the settings found in "<solution root>\.pentia\user-settings.json". Get-WebProject | Publish-ConfiguredWebProject Retrive all web projects in or under the current directory, and publish them using the settings found in "<solution root>\.pentia\user-settings.json". #> function Publish-ConfiguredWebProject { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline)] [string]$WebProjectFilePath, [Parameter(Mandatory = $false)] [string]$WebrootOutputPath, [Parameter(Mandatory = $false)] [string]$DataOutputPath, [Parameter(Mandatory = $false)] [string]$BuildConfiguration ) process { if (-not (Test-Path $WebProjectFilePath -PathType Leaf)) { throw "File path '$WebProjectFilePath' not found." } $solutionRootPath = $WebProjectFilePath | Find-SolutionRootPath $settings = Get-MergedParametersAndUserSettings -SolutionRootPath $solutionRootPath -WebrootOutputPath $WebrootOutputPath -DataOutputPath $DataOutputPath -BuildConfiguration $BuildConfiguration Publish-WebProject -WebProjectFilePath $WebProjectFilePath -OutputPath $settings.webrootOutputPath $projectDirectory = [System.IO.Path]::GetDirectoryName($WebProjectFilePath) Invoke-AllConfigurationTransforms -SolutionOrProjectRootPath $projectDirectory -WebrootOutputPath $settings.webrootOutputPath -BuildConfiguration $settings.buildConfiguration # Delete XDTs Get-ConfigurationTransformFile -SolutionRootPath $settings.webrootOutputPath | ForEach-Object { Remove-Item -Path $_ } } } function Find-SolutionRootPath { [CmdletBinding()] [OutputType([string])] param ( [Parameter(Mandatory = $true, ValueFromPipeline)] [string]$SearchStartPath ) process { if (-not (Test-Path $SearchStartPath)) { throw "Path '$SearchStartPath' not found." } $absoluteSearchStartPath = Resolve-Path $SearchStartPath if (Test-Path $absoluteSearchStartPath -PathType Leaf) { $directory = [System.IO.Path]::GetDirectoryName($absoluteSearchStartPath) } else { $directory = $absoluteSearchStartPath } $userSettingsFilePath = Get-UserSettingsFilePath -SolutionRootPath $directory if (Test-Path $userSettingsFilePath) { return "$directory" } $parent = Split-Path $directory -Parent if ([string]::IsNullOrWhiteSpace($parent)) { return $null } Find-SolutionRootPath -SearchStartPath $parent } } New-Alias -Name Publish-UnconfiguredWebProject -Value Publish-WebProject Export-ModuleMember -Function Publish-WebProject, Publish-ConfiguredWebProject -Alias Publish-UnconfiguredWebProject |