Last active
August 29, 2015 14:07
-
-
Save sayedihashimi/70a23180243c46fdab64 to your computer and use it in GitHub Desktop.
publish-sample-script.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[cmdletbinding(SupportsShouldProcess=$true)] | |
param($PublishProperties, $OutputPath) | |
function Ensure-PublishModuleLoaded{ | |
[cmdletbinding()] | |
param($versionToInstall = '0.0.3-beta', | |
$installScriptUrl = 'https://raw.githubusercontent.com/sayedihashimi/publish-module/master/GetPublishModule.ps1', | |
$toolsDir = ("$env:LOCALAPPDATA\LigerShark\tools\"), | |
$installScriptPath = (Join-Path $toolsDir 'GetPublishModule.ps1')) | |
process{ | |
if(!(Test-Path $installScriptPath)){ | |
$installDir = [System.IO.Path]::GetDirectoryName($installScriptPath) | |
if(!(Test-Path $installDir)){ | |
New-Item -Path $installDir -ItemType Directory -WhatIf:$false | Out-Null | |
} | |
'Downloading from [{0}] to [{1}]' -f $installScriptUrl, $installScriptPath| Write-Verbose | |
(new-object Net.WebClient).DownloadFile($installScriptUrl,$installScriptPath) | Out-Null | |
} | |
&($installScriptPath) | |
} | |
} | |
$whatifpassed = !($PSCmdlet.ShouldProcess($env:COMPUTERNAME,"publish")) | |
'loading publish-module' | Write-Output | |
Ensure-PublishModuleLoaded | |
'Calling AspNet-Publish' | Write-Output | |
# call AspNet-Publish to perform the publish operation | |
AspNet-Publish -publishProperties $PublishProperties -OutputPath $OutputPath -Verbose -WhatIf:$whatifpassed |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[cmdletbinding()] | |
param($PublishProperties,$OutputPath) | |
# TODO: Can we add an MSBuild property to pass -Verbose, that would enable | |
# flowing messages from Write-Verbose. The idea is to let users set that | |
# in the .pubxml file. | |
# TODO: In this script there is a call to Get-MSDeploy. It will look at an env var | |
# named MSDeployPath. I was thinking that VS can set this env var so that we | |
# ensure the correct version of MSDeploy is picked up. Should we pass this | |
# in via $PublishProerties instead? | |
# TODO: How can we pass in the UserAgent string? We should have a different value | |
# for script execution versus from VS. Perhaps in $PublishProperties or Env Var? | |
# TODO: Can we pass in all properties listed in .pubxml? | |
# TODO: We are currently passing in positional parameters, I wonder if we should switch | |
# to using named parameters (AddParameter(string,object)) instead. With this option | |
# users don't have to be worried about putting them in the correct position. | |
# TODO: I'm thinking that we can have two models for publishing with .ps1. | |
# 1. VS/MSBuild call KPM pack and then call .ps1. The idea is that the user will take | |
# the output and then publish to the web server | |
# 2. User want's to completly customize publish and VS/MSBuild calling kpm pack is | |
# not needed. Instead they just need the path to the source folder. | |
# I'm thinking we can add a new MSBuild property in .pubxml EnableCallKpmPackOnPublish | |
# which is set to true by default in our .targets file. If the user adds that to .pubmxl | |
# it will not call kpm pack. | |
# Also we should pass the path to the source folder in $PublishProperties | |
# | |
function Get-MSDeploy { | |
[cmdletbinding()] | |
param() | |
process{ | |
$msdInstallLoc = $env:MSDeployPath | |
if(!($msdInstallLoc)) { | |
# TODO: Get this from HKLM SOFTWARE\Microsoft\IIS Extensions\MSDeploy See MSDeploy VS task for implementation | |
$progFilesFolder = (Get-ChildItem env:"ProgramFiles").Value | |
$msdLocToCheck = @() | |
$msdLocToCheck += ("{0}\IIS\Microsoft Web Deploy V3\msdeploy.exe" -f $progFilesFolder) | |
$msdLocToCheck += ("{0}\IIS\Microsoft Web Deploy V2\msdeploy.exe" -f $progFilesFolder) | |
$msdLocToCheck += ("{0}\IIS\Microsoft Web Deploy\msdeploy.exe" -f $progFilesFolder) | |
foreach($locToCheck in $msdLocToCheck) { | |
"Looking for msdeploy.exe at [{0}]" -f $locToCheck | Write-Verbose | Out-Null | |
if(Test-Path $locToCheck) { | |
$msdInstallLoc = $locToCheck | |
break; | |
} | |
} | |
} | |
if(!$msdInstallLoc){ | |
throw "Unable to find msdeploy.exe, please install it and try again" | |
} | |
"Found msdeploy.exe at [{0}]" -f $msdInstallLoc | Write-Verbose | Out-Null | |
return $msdInstallLoc | |
} | |
} | |
function Get-MSDeployFullUrlFor{ | |
[cmdletbinding()] | |
param($msdeployServiceUrl) | |
process{ | |
# Convert sayedkdemo.scm.azurewebsites.net:443 to https://sayedkdemo.scm.azurewebsites.net/msdeploy.axd | |
# TODO: This needs to be improved, it only works with Azure Websites. We have code for this. | |
'https://{0}/msdeploy.axd' -f $msdeployServiceUrl.TrimEnd(':443') | |
} | |
} | |
###################################################################### | |
# Begin script | |
###################################################################### | |
if($PublishProperties){ | |
# TODO: How can we get the password? Any security reason why we cannot pass it in? It's all in memory. | |
$publishPwd = $env:PublishPassword | |
if(!$publishPwd){ | |
throw 'Publish password is not found please set $env:PublishPassword' | |
} | |
<# | |
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" | |
-source:IisApp='C:\Users\vramak\AppData\Local\Temp\AspNetPublish\WebApplication184-93\wwwroot' | |
-dest:IisApp='vramak4',ComputerName='https://vramak4.scm.azurewebsites.net/msdeploy.axd',UserName='$vramak4',Password='<PWD>',IncludeAcls='False',AuthType='Basic' | |
-verb:sync | |
-enableRule:DoNotDeleteRule | |
-enableLink:contentLibExtension | |
-retryAttempts=2 | |
-userAgent="VS14.0:PublishDialog:WTE14.0.51027.0" | |
#> | |
$webrootOutputFolder = (get-item (Join-Path $OutputPath 'wwwroot')).FullName | |
$publishArgs = @() | |
$publishArgs += ('-source:IisApp=''{0}''' -f "$webrootOutputFolder") | |
$publishArgs += ('-dest:IisApp=''{0}'',ComputerName=''{1}'',UserName=''{2}'',Password=''{3}'',IncludeAcls=''False'',AuthType=''Basic''' -f | |
$PublishProperties['DeployIisAppPath'], | |
(Get-MSDeployFullUrlFor -msdeployServiceUrl $PublishProperties['MSDeployServiceURL']), | |
$PublishProperties['UserName'], | |
$publishPwd) | |
$publishArgs += '-verb:sync' | |
# TODO: Should we pass this property in? | |
$publishArgs += '-enableRule:DoNotDeleteRule' | |
$publishArgs += '-enableLink:contentLibExtension' | |
$publishArgs += '-retryAttempts=2' | |
'Calling msdeploy with the call {0}' -f (($publishArgs -join ' ').Replace($publishPwd,'{PASSWORD}')) | Write-Verbose | |
& (Get-MSDeploy) $publishArgs | |
} | |
else{ | |
throw 'PublishProperties is empty, cannot publish' | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[cmdletbinding()] | |
param($publishFolder, $deploySettings, $logger, $vscontext) | |
# $publishFolder | |
# publishFolder points to the folder where the outputs of kpm pack are located | |
# When publishing from VS this value will be passed in as a full path | |
# The default value should be looking for a folder relative to this .ps1 file | |
# $deploymentSettings | |
# deploymentSettings is a hashtable containing key/value pairs | |
# for deployment info. | |
# When publishing from VS the values from the publish profile will be passed in via this variable | |
# When this file is created we will take the values from publish profile and use them as defaults | |
# if this parameter is not passed in | |
# $logger | |
# Logger is an object that is passed in by the caller. It has the following methods that can be called. | |
# - LogMessage() | |
# - LogWarning() | |
# - LogError() | |
# VS will pass in this object to facilite realtime logging. For command line scenarios this will be null | |
# $vscontext | |
# This is an object that will be passed in by VS. It will be used for getting preview results and maybe for | |
# other info as well. | |
### | |
# Declare functions here | |
### | |
# Log functions below are wrappers that will call $logger if it is not null | |
function LogMessage{ | |
[cmdletbinding()] | |
param($message) | |
process{ | |
$message | Write-Output | |
if($logger){ | |
$logger.LogMessage($message) | |
} | |
} | |
} | |
function LogError{ | |
[cmdletbinding()] | |
param($message) | |
process{ | |
$message | Write-Error | |
if($logger){ | |
$logger.LogError($message) | |
} | |
} | |
} | |
function LogWarning{ | |
[cmdletbinding()] | |
param($message) | |
process{ | |
$message | Write-Error | |
if($logger){ | |
$logger.LogWarning($message) | |
} | |
} | |
} | |
function GetPublishPassword{ | |
[cmdletbinding()] | |
param() | |
process{ | |
# check to see if there is a .pubxml.user file with | |
# the encrypted password. If so then decrypt that file | |
$passwordFromUserFile = '<get-password-from-.pubxml.user>' | |
return $passwordFromUserFile | |
} | |
} | |
function ValidatePublishSettings{ | |
[cmdletbinding()] | |
param() | |
process{ | |
# here we can check to ensure that $publishFolder is on disk and settings are passed in | |
# if there is any issue throw an exception here | |
# users can customize this method with their own validation | |
LogMessage('validating publish settings') | |
} | |
} | |
function PublishFromFolder{ | |
[cmdletbinding()] | |
param($publishFolder, $deploySettings) | |
process{ | |
LogMessage('starting publish from folder []' -f $publishFolder) | |
# here is where we make the call to MSDeploy to publish from the kpm pack folder | |
} | |
} | |
### | |
# Begin script | |
### | |
# these values are placed here when the script is created. No need for us to update this file | |
# because VS will always pass these values in. | |
# The idea is that the values in this are specific to this script | |
if(!$deploySettings){ | |
$deploySettings = @{} | |
$deploySettings.MSdeployServiceUrl = 'sayeddemo02.scm.azurewebsites.net:443' | |
$deploySettings.DeployIisAppPath = 'sayeddemo02' | |
$deploySettings.SkipExtraFilesOnServer = $true | |
$deploySettings.MSDeployPublishMethod = 'WMSVC' | |
$deploySettings.Username ='$sayeddemo02' | |
# TODO: We should pass MSDeploy parameters here as well | |
# TODO: We should probably pass MSDeploy skip rules here as well | |
} | |
# if the password is not passed in try and read it from the .pubxml.user file. This will make it | |
# easy for users to use this file from the local box. | |
if(!($deploySettings.Password)){ | |
$deploySettings.Password = (GetPublishPassword) | |
} | |
ValidatePublishSettings | |
PublishFromFolder -publishFolder $publishFolder -deploySettings $deploySettings | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[cmdletbinding()] | |
param($PublishProperties,$OutputPath) | |
# TODO: Can we add an MSBuild property to pass -Verbose, that would enable | |
# flowing messages from Write-Verbose. The idea is to let users set that | |
# in the .pubxml file. | |
# TODO: In this script there is a call to Get-MSDeploy. It will look at an env var | |
# named MSDeployPath. I was thinking that VS can set this env var so that we | |
# ensure the correct version of MSDeploy is picked up. Should we pass this | |
# in via $PublishProerties instead? | |
# TODO: How can we pass in the UserAgent string? We should have a different value | |
# for script execution versus from VS. Perhaps in $PublishProperties or Env Var? | |
function Get-MSDeploy { | |
[cmdletbinding()] | |
param() | |
process{ | |
$msdInstallLoc = $env:MSDeployPath | |
if(!($msdInstallLoc)) { | |
# TODO: Get this from HKLM SOFTWARE\Microsoft\IIS Extensions\MSDeploy See MSDeploy VS task for implementation | |
$progFilesFolder = (Get-ChildItem env:"ProgramFiles").Value | |
$msdLocToCheck = @() | |
$msdLocToCheck += ("{0}\IIS\Microsoft Web Deploy V3\msdeploy.exe" -f $progFilesFolder) | |
$msdLocToCheck += ("{0}\IIS\Microsoft Web Deploy V2\msdeploy.exe" -f $progFilesFolder) | |
$msdLocToCheck += ("{0}\IIS\Microsoft Web Deploy\msdeploy.exe" -f $progFilesFolder) | |
foreach($locToCheck in $msdLocToCheck) { | |
"Looking for msdeploy.exe at [{0}]" -f $locToCheck | Write-Verbose | Out-Null | |
if(Test-Path $locToCheck) { | |
$msdInstallLoc = $locToCheck | |
break; | |
} | |
} | |
} | |
if(!$msdInstallLoc){ | |
throw "Unable to find msdeploy.exe, please install it and try again" | |
} | |
"Found msdeploy.exe at [{0}]" -f $msdInstallLoc | Write-Verbose | Out-Null | |
return $msdInstallLoc | |
} | |
} | |
function Get-MSDeployFullUrlFor{ | |
[cmdletbinding()] | |
param($msdeployServiceUrl) | |
process{ | |
# Convert sayedkdemo.scm.azurewebsites.net:443 to https://sayedkdemo.scm.azurewebsites.net/msdeploy.axd | |
'https://{0}/msdeploy.axd' -f $msdeployServiceUrl.TrimEnd(':443') | |
# TODO: This needs to be improved, it only works with Azure Websites. We have code for this. | |
} | |
} | |
function OptimizeImages{ | |
[cmdletbinding()] | |
param( | |
$folder, | |
$force = $false, | |
$customTemp = "$env:LocalAppData\CustomPublish\", | |
$imgOptUrl = 'https://raw.githubusercontent.com/ligershark/AzureJobs/master/ImageCompressor.Job/optimize-images.ps1' | |
) | |
process{ | |
if(!(Test-Path $customTemp)){New-Item $customTemp -ItemType Directory} | |
$imgOptPath = (Join-Path $customTemp 'optimize-images.ps1') | |
if(!(Test-Path $imgOptPath)){ | |
# download the file | |
'Downloading optimize-images.ps1' | Write-Verbose | |
(New-Object System.Net.WebClient).DownloadFile($imgOptUrl, $imgOptPath) | |
} | |
&$imgOptPath $folder $force | |
} | |
} | |
$customTemp = "$env:LocalAppData\CustomPublish\" | |
$imgOptPath = Join-Path $customTemp 'optimize-images.ps1' | |
$imgOptUrl = 'https://raw.githubusercontent.com/ligershark/AzureJobs/master/ImageCompressor.Job/optimize-images.ps1' | |
###################################################################### | |
# Begin script | |
###################################################################### | |
if($PublishProperties){ | |
# TODO: How can we get the password? Any security reason why we cannot pass it in? It's all in memory. | |
$publishPwd = $env:PublishPassword | |
if(!$publishPwd){ | |
throw 'Publish password is not found please set $env:PublishPassword' | |
} | |
<# | |
"C:\Program Files (x86)\IIS\Microsoft Web Deploy V3\msdeploy.exe" | |
-source:IisApp='C:\Users\vramak\AppData\Local\Temp\AspNetPublish\WebApplication184-93\wwwroot' | |
-dest:IisApp='vramak4',ComputerName='https://vramak4.scm.azurewebsites.net/msdeploy.axd',UserName='$vramak4',Password='<PWD>',IncludeAcls='False',AuthType='Basic' | |
-verb:sync | |
-enableRule:DoNotDeleteRule | |
-enableLink:contentLibExtension | |
-retryAttempts=2 | |
-userAgent="VS14.0:PublishDialog:WTE14.0.51027.0" | |
#> | |
$webrootOutputFolder = (get-item (Join-Path $OutputPath 'wwwroot')).FullName | |
OptimizeImages -folder $webrootOutputFolder | |
$publishArgs = @() | |
$publishArgs += ('-source:IisApp=''{0}''' -f "$webrootOutputFolder") | |
$publishArgs += ('-dest:IisApp=''{0}'',ComputerName=''{1}'',UserName=''{2}'',Password=''{3}'',IncludeAcls=''False'',AuthType=''Basic''' -f | |
$PublishProperties['DeployIisAppPath'], | |
(Get-MSDeployFullUrlFor -msdeployServiceUrl $PublishProperties['MSDeployServiceURL']), | |
$PublishProperties['UserName'], | |
$publishPwd) | |
$publishArgs += '-verb:sync' | |
# TODO: Should we pass this property in? | |
$publishArgs += '-enableRule:DoNotDeleteRule' | |
$publishArgs += '-enableLink:contentLibExtension' | |
$publishArgs += '-retryAttempts=2' | |
'Calling msdeploy with the call {0}' -f (($publishArgs -join ' ').Replace($publishPwd,'{PASSWORD}')) | Write-Verbose | |
& (Get-MSDeploy) $publishArgs | |
} | |
else{ | |
throw 'PublishProperties is empty, cannot publish' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment