Continuing my current theme of installation automation via PowerShell, the next task I found myself looking at was how to enable Sitecore's analytics for a newly installed Sitecore instance. This is a task that the standard .exe installer doesn't do for the v6.6 sites I'm working with, but is relatively simple to automate.
The tasks we need to perform to get DMS up and running are as follows:
None of these tasks are particularly hard, but thinking about these while considering how to improve on the previous bits of script I'd created made me realise that there's lots of site configuration data required by these scripts. And that means the scripts need a sensible place to find this data in order to make it easy to reuse the PowerShell code for different Sitecore instances.
Some simple-to-read XML to describe that data might look like this:
<config> <params> <param name="InstanceName">Test</param> <param name="LicenseFile">.\files\License-2014.xml</param> <param name="SitecoreInstaller">.\files\Sitecore 6.6.0 rev. 140410.exe</param> <param name="DMSFiles">.\files\DMS 6.6.0 rev. 140410.zip</param> </params> <hostnames> <hostname>www.test.dev</hostname> </hostnames> <modules> <module>.\files\MyPackage-1.0.zip</module> </modules> </config>
PowerShell is pretty good at dealing with data in XML, so we can easily make the location of one of these config documents a required parameter of our "install an instance" script, and parse the file into an XML document. The individual config functions can then query this document.
Loading the data might look like:
param([Parameter(Mandatory=$true)][string]$configFile) if( -not (Test-Path $configFile) ) { throw "Config file must exist" } [xml]$xml = Get-Content $configFile # # Validate the XML here # # # Rest of script can use the XML data now #
By declaring a
param()
section at the top of our script file, we say that this parameter is coming from the command line. It can be marked as required with attributes - which will ensure that PowerShell receives a value from the user. And we can then also test that the value we received is a valid file.
The script can then use the
Get-Content
commandlet to return an XML document which we can query later. At this point I've not added any code to validate that the XML loaded has the correct schema – but that would be a useful thing to add in later.
And then the data can be read with some simple helper functions:
function Get-ConfigParam([string] $name) { $val = Select-Xml "/config/params/param[@name='$name']/text()" $xml if([string]::IsNullOrEmpty($val)) { throw "Parameter $name is missing from config" } return [string]$val } function Get-ConfigHostnames() { return Select-Xml "/config/hostnames/hostname/text()" $xml } function Get-ConfigModules() { return Select-Xml "/config/modules/module/text()" $xml }
The
Get-ConfigParam
function looks up a named value from the set of general configuration data and returns it. The
Get-ConfigHostnames
and
Get-ConfigModules
return lists of strings which can be iterated over by other code.
With these functions in place, the basic script can now call the "install instance" script from last week's post, fetching the parameters to pass to the MSI installer from a config file.
function Add-DMS() { # fetch the zip $dmsZip = Get-ConfigParam "DMSFiles" # decompress it Write-Host "Decompressing DMS files..." Expand-ZipFile $dmsZip '.\dms' $siteName = Get-ConfigParam "InstanceName" $sitecoreFolder = "C:\Inetpub\wwwroot\$($siteName)" # copy config files to right place Write-Host "Copying DMS config" Copy-Item ".\dms\*.config" "$($sitecoreFolder)\Website\App_Config\Include" -force # copy db files to right place Write-Host "Copying DMS DB Files" Copy-Item ".\dms\*.mdf" "$($sitecoreFolder)\Database\MDF" -force Copy-Item ".\dms\*.ldf" "$($sitecoreFolder)\Database\LDF" -force # Attach databases Write-Host "Attaching DMS database" $osql = "OSQL.EXE" $dbFile = Get-Item ".\dms\*.mdf" | % { Join-Path "$($sitecoreFolder)\Database\MDF" $_.Name } $lgFile = Get-Item ".\dms\*.ldf" | % { Join-Path "$($sitecoreFolder)\Database\LDF" $_.Name } $dbName = "$($siteName)_Sitecore_Analytics" $query = "CREATE DATABASE [$dbName] ON ( FILENAME = N'$($dbFile)' ),( FILENAME = N'$($lgFile)' ) FOR ATTACH" &$osql -S localhost -E -Q "$($query)" # can't ignore connection string - it's needed for WFfM install Write-Host "Adding DMS connection string" $conStrFile = "$($sitecoreFolder)\Website\App_Config\ConnectionStrings.config" Add-DMSConnectionString $conStrFile $dbName # tidy mess Write-Host "Removing DMS temp folder" rmdir ".\dms" -Recurse -Force }
The code gets the location of the DMS zip file downloaded from SDN from the config code above, and then decompresses it to a temporary folder. It can then get the instance name of your Sitecore install, and work out the correct disk folder that our previous Sitecore install script used.
The DMS config include files can then be copied to the instance's config include folder, and the DMS database files can be copied to the Sitecore database folders.
Next the code works out the absolute path to the DMS database files that were just copied, and works out the correct database name. Then it uses the SQL Server command line tool to run a T-SQL command to attach the database correctly.
The code then calls another function to add the connection string, before tidying up the temporary folder.
The function to add the connection string might look like this:
function Add-DMSConnectionString([string] $conStrFile, [string] $dbName) { $sqlUser = Get-ConfigParam "sqlUser" $sqlPassword = Get-ConfigParam "sqlPassword" $sqlServer = Get-ConfigParam "sqlServer" # work out correct connection string $constr = "user id=$sqlUser;password=$sqlPassword;Data Source=$sqlServer;Database=$dbName" # Get connection file as XML Document [xml] $conStrXml = Get-Content $conStrFile # build the new entry $entry = $conStrXml.CreateElement("add") $nameAttr = $conStrXml.CreateAttribute("name") $nameAttr.Value = "analytics" $entry.Attributes.Append($nameAttr) | out-null $conAttr = $conStrXml.CreateAttribute("connectionString") $conAttr.Value = $constr $entry.Attributes.Append($conAttr) | out-null # Add the entry to the file $connections = $conStrXml.SelectSingleNode("/connectionStrings") $connections.AppendChild($entry) | Out-Null # Save the file $conStrXml.Save($conStrFile) }
This bit of code takes the location of the connection string file and the name of the database to attach. It then uses the config functions to get the SQL server, user and password.
Then it can calculate the correct connection string, before adding the extra XML element and its attributes and then saving the changes.
Next week, my plan is to look at how you can automatically add modules or packages into your Sitecore instance after it's been installed.
↑ Back to top