Friday, January 4, 2013

Automate your Sitecore website deployment with PowerCore


I'm trying to free your mind, Neo. But I can only show you the door. You're the one that has to walk through it..."

In this blog post I want to free your mind and show you that automated website deployment is extremely easy these days. Even when you have a web farm of hundreds Sitecore servers: if you can describe deployment procedure using checklist - you can automate it with PowerShell.

I've seen most complicated scenarios ever, with many external systems involved, thirty-pages deployment manual and weird logic of making decisions when it comes to naming databases or folders. And PowerShell  did its job, saved tons of time for developers and allowed us to automate 100% of action items.

So, I'd like to share some helper cmdlets which can be used to create simple Sitecore website deployment script in something like 50 lines of code.

I've assembled them into the framework that you can find at GitHub repository - PowerCore. Here's the brief description of files:

DBUtils.ps1
Basic DB operations - backup / restore / execute, etc.

  • Create-Database
  • Restore-Database
  • Backup-Database
  • Attach-Database
  • Execute-File

FileUtils.ps1
Used to download / extract / package files, etc.

  • Download-File
  • Extract-Package
  • Set-Permissions
  • Unzip-Archive
  • Add-HostFileContent

ConfigUtils.ps1
All about editing .config files - web.config, include files, ConnectionStrings.config

  • Uncomment-ConfigSection
  • Set-ConnectionString
  • Set-SitecoreSetting
  • Set-ConfigAttribute
  • Set-ExecutionTimeout

and many other cmdlets

IISUtils.ps1
Used to create Sites / AppPools in IIS

  • Create-AppPool
  • Create-Site

SvnUtils.ps1
Contains single commandlet which will Checkout / Revert / Update folder from specified SVN repository. It can be split into a few different ones, I plan to do it in future.

WebUtils.ps1
Includes single commandlet for invoking a web page

And here's the sample script that installs clean Sitecore website using the framework. Wrap it into Invoke-Command and execute remotely at multiple servers at a time if needed.
Clear-Host
# Framework initialization
$scriptRoot = Split-Path (Resolve-Path $myInvocation.MyCommand.Path)
.$scriptRoot\Framework\FileUtils.ps1
.$scriptRoot\Framework\DBUtils.ps1
.$scriptRoot\Framework\ConfigUtils.ps1
.$scriptRoot\Framework\IISUtils.ps1

# Main variables
$siteName = "PowerCoreSample"
$licensePath = "C:\license.xml"
$sourcePath = "C:\Sitecore 6.5.0 rev. 120706.zip"
$targetFolder = "E:\inetpub\wwwroot"

# Additional variables
$packageFileName = [System.IO.Path]::GetFileNameWithoutExtension($sourcePath)
$dataFolder = "$destination\$packageFileName\Data"
$websiteFolder = "$destination\$packageFileName\Website"
$serverName = $env:COMPUTERNAME
$sqlServerName = "$serverName\SQLEXPRESS"

# Main Script
Unzip-Archive $sourcePath $targetFolder

$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") $sqlServerName
$databases = "core", "master", "web"
foreach ($db in $databases)
{
    Attach-Database $server "$siteName.$db" "$targetFolder\$packageFileName\Databases\Sitecore.$db.mdf" "$destination\$packageFileName\Databases\Sitecore.$db.ldf"
 Set-ConnectionString "$websiteFolder\App_Config\ConnectionStrings.config" "$db" "Trusted_Connection=Yes;Data Source=$sqlServerName;Database=$siteName.$db"
}

Set-ConfigAttribute "$websiteFolder\web.config" "sitecore/sc.variable[@name='dataFolder']" "value" $dataFolder   

Copy-Item $licensePath $dataFolder
Create-AppPool $siteName "v4.0"
Create-Site $siteName "$siteName.local"  "$destination\$packageFileName"
Add-HostFileContent "127.0.0.1" "$siteName.local"

If you have any questions regarding these scripts or just need help automating Sitecore deployment with PowerShell - do no hesitate to contact me! I'll be glad to help and also extend the framework.