Sitecore 9 and the Sitecore Installation Framework
Author
Tom Dudfield
Date Published

Prior to Sitecore 9, setting up an instance of Sitecore either relied on running the Sitecore installer or extracting a ZIP file and jumping through a few hoops. This process was simplified with the introduction of Sitecore Instance Manager but it was still tedious when configuring different server roles. I will show you how to setup a Sitecore 9 instance, while it is not completely straightforward it is a lot more flexible.
Sitecore 9 Requirements
Base
* IIS 10 (IIS 8.5 is supported but I would recommend moving away from it)
* Windows Server 2016 ideally 64-bit (2012 R2 is supported but best avoided to use IIS 10)
* .NET Framework 4.6.2 or newer
* Microsoft Visual C++ 2015 Redistributable
* Microsoft SQL Server 2016 SP1
* Solr 6.6.2 or an Azure Search instance (if you are deploying to Azure PaaS it is recommended to use the same search provider for development as your hosting platform)
For development
* Visual Studio 2017 for development
* Windows 10 or Windows Server 2016 ideally 64-bit (8.1 and 2012 R2 are supported but best avoided to use IIS 10)
* At a minimum a 4 core CPU and 16GB RAM, ideally an i7 and 32GB RAM
* At least a dual-monitor setup
SIF has the following dependencies
* WebAdministration Module
* Web Deploy 3.6 for Hosting Servers
* URL Rewrite 2.1
* Microsoft SQL Server Data-Tier Application Framework (DacFx) version 2016
Contained Database Authentication
This needs to be enabled to use Web Deploy Packages
The following should be run in SQL Management Studio
1sp_configure 'contained database authentication', 1;2GO3RECONFIGURE;4GO
Solr Setup
The next step is to install and configure Solr, fortunately Jeremy Davis has taken the pain out of this process and produced a script that not only installs Solr it creates and certificate and configures it.
Before running this script, make sure you have 1.8.0_151 64-bit version of JRE installed.
1Param(2 $solrVersion = "6.6.2",3 $installFolder = "c:\solr",4 $solrPort = "8983",5 $solrHost = "solr",6 $solrSSL = $true,7 $nssmVersion = "2.24",8 $JREVersion = "1.8.0_151"9)1011$JREPath = "C:\Program Files\Java\jre$JREVersion"12$solrName = "solr-$solrVersion"13$solrRoot = "$installFolder\$solrName"14$nssmRoot = "$installFolder\nssm-$nssmVersion"15$solrPackage = "https://archive.apache.org/dist/lucene/solr/$solrVersion/$solrName.zip"16$nssmPackage = "https://nssm.cc/release/nssm-$nssmVersion.zip"17$downloadFolder = "~\Downloads"1819## Verify elevated20## https://superuser.com/questions/749243/detect-if-powershell-is-running-as-administrator21$elevated = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")22if($elevated -eq $false)23{24 throw "In order to install services, please run this script elevated."25}2627function downloadAndUnzipIfRequired28{29 Param(30 [string]$toolName,31 [string]$toolFolder,32 [string]$toolZip,33 [string]$toolSourceFile,34 [string]$installRoot35 )3637 if(!(Test-Path -Path $toolFolder))38 {39 if(!(Test-Path -Path $toolZip))40 {41 Write-Host "Downloading $toolName..."42 Start-BitsTransfer -Source $toolSourceFile -Destination $toolZip43 }4445 Write-Host "Extracting $toolName to $toolFolder..."46 Expand-Archive $toolZip -DestinationPath $installRoot47 }48}49# download & extract the solr archive to the right folder50$solrZip = "$downloadFolder\$solrName.zip"51downloadAndUnzipIfRequired "Solr" $solrRoot $solrZip $solrPackage $installFolder5253# download & extract the nssm archive to the right folder54$nssmZip = "$downloadFolder\nssm-$nssmVersion.zip"55downloadAndUnzipIfRequired "NSSM" $nssmRoot $nssmZip $nssmPackage $installFolder5657# Ensure Java environment variable58$jreVal = [Environment]::GetEnvironmentVariable("JAVA_HOME", [EnvironmentVariableTarget]::Machine)59if($jreVal -ne $JREPath)60{61 Write-Host "Setting JAVA_HOME environment variable"62 [Environment]::SetEnvironmentVariable("JAVA_HOME", $JREPath, [EnvironmentVariableTarget]::Machine)63}6465# if we're using HTTP66if($solrSSL -eq $false)67{68 # Update solr cfg to use right host name69 if(!(Test-Path -Path "$solrRoot\bin\solr.in.cmd.old"))70 {71 Write-Host "Rewriting solr config"7273 $cfg = Get-Content "$solrRoot\bin\solr.in.cmd"74 Rename-Item "$solrRoot\bin\solr.in.cmd" "$solrRoot\bin\solr.in.cmd.old"75 $newCfg = $newCfg | % { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$solrHost" }76 $newCfg | Set-Content "$solrRoot\bin\solr.in.cmd"77 }78}7980# Ensure the solr host name is in your hosts file81if($solrHost -ne "localhost")82{83 $hostFileName = "c:\\windows\system32\drivers\etc\hosts"84 $hostFile = [System.Io.File]::ReadAllText($hostFileName)85 if(!($hostFile -like "*$solrHost*"))86 {87 Write-Host "Updating host file"88 "`r`n127.0.0.1`t$solrHost" | Add-Content $hostFileName89 }90}9192# if we're using HTTPS93if($solrSSL -eq $true)94{95 # Generate SSL cert96 $existingCert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"97 if(!($existingCert))98 {99 Write-Host "Creating & trusting an new SSL Cert for $solrHost"100101 # Generate a cert102 # https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps103 $cert = New-SelfSignedCertificate -FriendlyName "$solrName" -DnsName "$solrHost" -CertStoreLocation "cert:\LocalMachine" -NotAfter (Get-Date).AddYears(10)104105 # Trust the cert106 # https://stackoverflow.com/questions/8815145/how-to-trust-a-certificate-in-windows-powershell107 $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root","LocalMachine"108 $store.Open("ReadWrite")109 $store.Add($cert)110 $store.Close()111112 # remove the untrusted copy of the cert113 $cert | Remove-Item114 }115116 # export the cert to pfx using solr's default password117 if(!(Test-Path -Path "$solrRoot\server\etc\solr-ssl.keystore.pfx"))118 {119 Write-Host "Exporting cert for Solr to use"120121 $cert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"122123 $certStore = "$solrRoot\server\etc\solr-ssl.keystore.pfx"124 $certPwd = ConvertTo-SecureString -String "secret" -Force -AsPlainText125 $cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null126 }127128 # Update solr cfg to use keystore & right host name129 if(!(Test-Path -Path "$solrRoot\bin\solr.in.cmd.old"))130 {131 Write-Host "Rewriting solr config"132133 $cfg = Get-Content "$solrRoot\bin\solr.in.cmd"134 Rename-Item "$solrRoot\bin\solr.in.cmd" "$solrRoot\bin\solr.in.cmd.old"135 $newCfg = $cfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_KEY_STORE=$certStore" }136 $newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE_PASSWORD=secret", "set SOLR_SSL_KEY_STORE_PASSWORD=secret" }137 $newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_TRUST_STORE=$certStore" }138 $newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret", "set SOLR_SSL_TRUST_STORE_PASSWORD=secret" }139 $newCfg = $newCfg | % { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$solrHost" }140 $newCfg | Set-Content "$solrRoot\bin\solr.in.cmd"141 }142}143144# install the service & runs145$svc = Get-Service "$solrName" -ErrorAction SilentlyContinue146if(!($svc))147{148 Write-Host "Installing Solr service"149 &"$installFolder\nssm-$nssmVersion\win64\nssm.exe" install "$solrName" "$solrRoot\bin\solr.cmd" "-f" "-p $solrPort"150 $svc = Get-Service "$solrName" -ErrorAction SilentlyContinue151}152if($svc.Status -ne "Running")153{154 Write-Host "Starting Solr service"155 Start-Service "$solrName"156}157158# finally prove it's all working159$protocol = "http"160if($solrSSL -eq $true)161{162 $protocol = "https"163}164Invoke-Expression "start $($protocol)://$($solrHost):$solrPort/solr/#/"
What the SIF?
Sitecore 9 has now introduced the Sitecore Installation Framework (SIF). SIF comprises of a PowerShell module that supports both local and remote installations of Sitecore. It is fully extensible through JSON configuration and PowerShell scripts which deploy Web Deploy Packages into an environment. It is possible to deploy the entire Sitecore Experience Platform or just Experience Management.
To install SIF you can download and install it from the Sitecore Gallery using the following PowerShell commands in an administrator shell:
1Register-PSRepository -Name SitecoreGallery -SourceLocation https://sitecore.myget.org/F/sc-powershell/api/v22Install-Module SitecoreInstallFramework
If you get a prompt when installing modules from an untrusted repository, press Y and ENTER

For developer installations, it is also required to install the Sitecore Fundamentals module which allows the creation of self-signed certificates for development environments.
1Install-Module SitecoreFundamentals
If you get a prompt when installing modules from an untrusted repository, press Y and ENTER

Single Server Development Instance
This might have seen like a lot of steps to jump through to get this far however you only need to configure these things once, no matter how many instances of Sitecore you install. Unless you have a very specific scenario, typically you will want an XP Single (XP0) instance for development purposes.
First things first, download the latest version of Sitecore 9 for On-Premises deployment, in my instance, this was Sitecore 9.0.1 rev. 171219 (WDP XP0 packages).zip. Once the file is downloaded make sure that you unblock it.

Once extracted, go into the extracted files and extract XP0 Configuration files 9.0.1 rev. 171219.zip and copy all the files into the root folder alongside the scwdp zip files.
Also, locate your license.xml file and copy it into this directory.
To simply this process Sitecore has provided a PowerShell script to call SIF with the payload JSON. This will need to be adapted to match the configuration of your local environment.
1# Add the Sitecore MyGet repository to PowerShell2#Register-PSRepository -Name SitecoreGallery -SourceLocation https://sitecore.myget.org/F/sc-powershell/api/v234# Install the Sitecore Install Framwork module5#Install-Module SitecoreInstallFramework67# Install the Sitecore Fundamentals module (provides additional functionality for local installations like creating self-signed certificates)8#Install-Module SitecoreFundamentals910# Import the modules into your current PowerShell context (if necessary)11Import-Module SitecoreFundamentals12Import-Module SitecoreInstallFramework1314#define parameters15$prefix = "sc90"16$PSScriptRoot = "C:\Users\tomdudfield\Downloads\Sitecore 9.0.1 rev. 171219 (WDP XP0 packages)"17$XConnectCollectionService = "$prefix.xconnect"18$sitecoreSiteName = "$prefix.local"19$SolrUrl = "https://solr:8983/solr"20$SolrRoot = "C:\solr\solr-6.6.2"21$SolrService = "solr-6.6.2"22$SqlServer = "localhost"23$SqlAdminUser = "sa"24$SqlAdminPassword = "Pa55word"2526#install client certificate for xconnect27$certParams =28@{29 Path = "$PSScriptRoot\xconnect-createcert.json"30 CertificateName = "$prefix.xconnect_client"31}32Install-SitecoreConfiguration @certParams -Verbose3334#install solr cores for xdb35$solrParams =36@{37 Path = "$PSScriptRoot\xconnect-solr.json"38 SolrUrl = $SolrUrl39 SolrRoot = $SolrRoot40 SolrService = $SolrService41 CorePrefix = $prefix42}43Install-SitecoreConfiguration @solrParams -Verbose4445#deploy xconnect instance46$xconnectParams =47@{48 Path = "$PSScriptRoot\xconnect-xp0.json"49 Package = "$PSScriptRoot\Sitecore 9.0.1 rev. 171219 (OnPrem)_xp0xconnect.scwdp.zip"50 LicenseFile = "$PSScriptRoot\license.xml"51 Sitename = $XConnectCollectionService52 XConnectCert = $certParams.CertificateName53 SqlDbPrefix = $prefix54 SqlServer = $SqlServer55 SqlAdminUser = $SqlAdminUser56 SqlAdminPassword = $SqlAdminPassword57 SolrCorePrefix = $prefix58 SolrURL = $SolrUrl59}60Install-SitecoreConfiguration @xconnectParams -Verbose6162#install solr cores for sitecore63$solrParams =64@{65 Path = "$PSScriptRoot\sitecore-solr.json"66 SolrUrl = $SolrUrl67 SolrRoot = $SolrRoot68 SolrService = $SolrService69 CorePrefix = $prefix70}71Install-SitecoreConfiguration @solrParams -Verbose7273#install sitecore instance74$sitecoreParams =75@{76 Path = "$PSScriptRoot\sitecore-XP0.json"77 Package = "$PSScriptRoot\Sitecore 9.0.1 rev. 171219 (OnPrem)_single.scwdp.zip"78 LicenseFile = "$PSScriptRoot\license.xml"79 SqlDbPrefix = $prefix80 SqlServer = $SqlServer81 SqlAdminUser = $SqlAdminUser82 SqlAdminPassword = $SqlAdminPassword83 SolrCorePrefix = $prefix84 SolrUrl = $SolrUrl85 XConnectCert = $certParams.CertificateName86 Sitename = $sitecoreSiteName87 XConnectCollectionService = "https://$XConnectCollectionService"88}89Install-SitecoreConfiguration @sitecoreParams -Verbose
Save this into the directory and run the script.

Once complete you should have a clean Sitecore 9 instance.
This is the simplest way to get Sitecore installed, for more advanced scenarios the JSON payload or SCWDP's can be adapted to support this. This process can be used for production servers and even to remotely deploy Sitecore, although it is worth turning to the Sitecore official documentation to ensure this process is followed correctly.

In this article I am going to run through how to provision Sitecore 9 XP on Microsoft Azure in a PaaS configuration.

Since the release of Sitecore 8.2, they now provide a new mechanism to deploy in a PaaS setup to Azure using Web Apps.