Skip to content

Automate ASP.NET Deployment with Powershell: Install and Update

ASP.Net Deployment is not easy a task. It has to deal with different operating systems, web servers, databases, and etc… It often involves manual process. All these things make deployment a error prone and slow process. ¬†It is a task you have to do it again and again. Let’s automate the whole process and relieve us of deployment hell.

1. Identify the tasks in deployment

Install, Update, Remove, Backup and Rollback. Among these tasks, Install and Update are used more frequently than others. Let’s focus on these two tasks now.

2. Deployment Tools

Let’s look at the tools available on windows platform: Windows installer, capistrano, msdeploy.

  • Windows installer – I used WIX to create installer for my web application. It’s sufficient for simple web site. There two obvious drawbacks:
    (1) WIX uses xml to create installer, but writing in XML is just pain and slow; (2) There is no easy way to handle multiple instances installation.
  • Capistrano – a popular deployment tool for rails, but it doesn’t play well with windows.
  • MS Deploy – I’ve been scared away by its complexity.

All I want is an easy and flexible solution with minimum requirements. None of them above satisfies my requirements.
Finally, I narrowed down my choices to powershell and psake. Powershell is a scripting  language for windows platform, similar to bash script in Linux. If you have used make, rake, nant, msbuild, you will find psake is quite similar. Psake is a build automation tool written in powershell.

3. Demo

Here I will create small powershell script to deploy mvc application in IIS7.

Create deployment package stucture.

\PSCommon – all our powershell modules used for deployment are in this folder

\WebApp – web application files

\default.ps1 – powershell script file contains all psake tasks

\run.bat – start a powerhell console with required modules for deployment

Create Install and Update task. To make it simple, here are install and update tasks to get started.

task Install {
	"task install"
}
 
task Update {
	"update install"
}

To execute the two tasks, click run.bat. Type

ipsake install

or

ipsake update

What’s in run.bat?

  • Start powershell console
  • Load required powershell modules
  • Set alias ipsake
powershell.exe -noexit -ExecutionPolicy unrestricted -command import-module .\PScommon\psake\psake.psm1;import-module .\PSCommon\WebAdministration;Set-Alias -Name ipsake -Value Invoke-psake

Time to add more stuff into tasks.

Install task – Create and configure web site

task Install {
    New-WebAppPool demo_pool
    $pool = Get-Item "IIS:\AppPools\demo_pool"
    $pool.managedRuntimeVersion = "v4.0"
    $pool.processModel.identityType = 2 #NetworkService
    $pool | Set-Item
    if (-not (Test-Path "c:\inetpub\demo")) {
        mkdir "c:\inetpub\demo"
    }
    cp .\WebApp\* c:\inetpub\demo -Force -Recurse
    New-Website -Name "demo" -PhysicalPath c:\inetpub\demo -ApplicationPool "demo_pool" -Port 8686
}

Update task – Stop current web site; remove old files; copy new files.

task Update {
    $webSite = Get-Item "IIS:\Sites\demo"
    $filesToDelete = $webSite.physicalPath + "\*"
 
    if ((Get-WebsiteState -Name "demo").Value -ne "Stopped") {
        $webSite.Stop()
    }
    $poolName = $webSite.applicationPool
    $pool = Get-Item "IIS:\AppPools\$poolName"
 
    if ((Get-WebAppPoolState -Name $poolName).Value -ne "Stopped") {
        $pool.Stop()
    }
 
    rm $filesToDelete -Recurse -Force
    cp .\WebApp\* $webSite.physicalPath -Force -Recurse
 
    $pool.Start()
    $webSite.Start()
}

Remove task – Remove installed web application.

task Remove {
    $webSite = Get-Item "IIS:\Sites\demo"
    if ((Get-WebsiteState -Name "demo").Value -ne "Stopped") {
        $webSite.Stop()
    }
    $poolName = $webSite.applicationPool
    $pool = Get-Item "IIS:\AppPools\$poolName"
 
    if ((Get-WebAppPoolState -Name $poolName).Value -ne "Stopped") {
        $pool.Stop()
    }
    Remove-Website -Name "demo"
 
	Remove-WebAppPool -Name $poolName
 
    rm $webSite.physicalPath -Recurse -Force
}

Download demo. To test the demo, install IIS7, powershell 2.0, IIS 7 Web Administration Module and mvc3 framework.

Use powershell to automate deployment is easy and flexible with minimum requirements on the server. You can script your own logic for deployment. This is just a simple example to get started.

Further reading:

https://github.com/JamesKovacs/psake

http://en.wikipedia.org/wiki/Windows_PowerShell

http://wekeroad.com/post/4373719917/asp-net-deployment-needs-to-be-fixed

http://stackoverflow.com/questions/499728/how-to-create-where-to-get-wix-bootstrapper-for-multiple-instances

https://github.com/capistrano/capistrano/wiki