Jeremy Davis
Jeremy Davis
Sitecore, C# and web development
Article printed from:

Automated package installs

Published 29 June 2015
Updated 25 August 2016

After you've finished installing an instance of Sitecore for development or test (as I've been discussing in my previous few posts – Installing, Adding DMS, Hosts & SSL), chances are you'll need to deploy some modules or packages onto it. Things like Web Forms for Marketers are regularly needed as a basis for development work. So what can you do if you'd like to automate this with PowerShell as well?

Choosing a tool to allow packages to be installed

There are two sorts of package file you can install into Sitecore – standard content packages and upgrade packages. While upgrade packages can be useful for developers, I'm specifically interested in standard packages here. This is because I've been focusing on automating the installation of Sitecore Modules such as Web Forms for Marketers or Email Campaign Manager.

There's UI in Sitecore for installing these packages, but no publicly exposed external API – just some .Net objects which can be used. A bit of research into this topic lead me to some useful work from another developer which can be reused here.

[NB: The solution presented here is aimed at scripting private development instances. If you wish to apply a similar approach to public sites you should pay close attention to the security of endpoints like this, as they represent an opportunity for denial of service attacks, or even security breaches. At the very least you should consider IP address restrictions for pages like this.]

The .aspx file from the GitHub link above can be dropped into a suitable location in your Sitecore install, before calling it with a list of package names (these package files need to be in the Data/Packages folder) to install them.

(Note that there's also an equivalent file for installing upgrade packages in the repo linked above. This is an alternative to using something like Sitecore.Ship if you prefer something lighweight and want to install .update files automatically)

Required configuration and installing the helper

To add this automation to the install script, we need to start with some extra configuration. We need to know where the .aspx file is, and where the packages to be installed are. Based on the configuration storage I talked about previously, we can update our config xml with some extra data. We need to know the path to the file containing the package install tool, and we need to know what packages to install. For the purposes of testing, I tried adding quite a few:

    <param name="InstanceName">TestInstance</param>

    <!-- rest of the original properties go here -->

    <param name="PackageUploadTool">.\files\PackageDeploy.aspx</param>
    <!-- whatever hosts are being configured -->
    <module>.\files\Web Forms for Marketers 2.3 rev.</module>
    <module>.\files\SPEAK 1.0.0 rev.</module>
    <module>.\files\E-mail Campaign Manager 2.0.0 rev.</module>
    <module>.\files\ECM 2 Save Actions 1.0.0 rev.</module>


Based on that, we can write a simple function to install the package deployment tool into our fresh Sitecore instance:

function Add-PackageUpload() {
    $siteName = Get-ConfigParam "InstanceName"
    $sitecoreFolder = "C:\Inetpub\wwwroot\$($siteName)\Website"
    $uploadTool = Get-ConfigParam "PackageUploadTool"
    Write-Host "Adding package upload tool to Sitecore..."
    Copy-Item $uploadTool $sitecoreFolder -force


It just works out the correct path and copies the .aspx file into the root of the Sitecore instance.

Note that I'm using these scripts only for development and test instances. If you wanted to adopt this sort of scripting for publicly exposed instances you should apply proper security to the package deploy process.

Installing packages

Once the package upload tool has been added, we need some script to install the packages. This might look like:

function Add-Packages() {
    $siteName = Get-ConfigParam "InstanceName"
    $sitecoreFolder = "C:\Inetpub\wwwroot\$($siteName)\Data\packages"   
    foreach($module in Get-ConfigModules) {
        # make querystring
        $query = (Split-Path -Path $module -Leaf)
        # Copy the package
        Write-Host "Copying package $query to Sitecore package folder..."
        Copy-Item $module $sitecoreFolder -force
        Write-Host "Calling package upload tool for $query"
        # call tool
        $url = "http://$siteName/PackageDeploy.aspx?modules=$query"
        $result = Invoke-WebRequest -Uri $url -TimeoutSec 600 -OutFile ".\$siteName-PackageResponse-$query.log" -PassThru
        if($result.StatusCode -ne 200) {
            Write-Host "StatusCode: $($result.StatusCode)"
            throw "Package install failed for $($query)"
        # Removing installed package file
        $file = Join-Path $sitecoreFolder $query
        Remove-Item $file -Force

    write-host "Package tool done..."


This code goes through the set of module package files that the Get-ConfigModules function returns. (See previous post) For each one, it copies it from the source location to the Sitecore packages folder.

It then makes an HTTP request to the package install tool's URL, specifying the package file we want to install. The result of the request is written to disk here for debug purposes – but you don't need to do that. I've also set a long timeout for this HTTP request to cope with big packages.

After the HTTP request completes the code checks the response – it should be 200 for success, so we can throw an error should this not be the response.

And finally the now redundant package file is removed from Sitecore's package folder. This is optional – you might prefer your script to leave these files available.

Note that the code here is processing each package in turn. The package tool can accept multiple packages to install in one go. However I found that (particularly when installing large packages like Email Campaign Manager) the process tended to take too long and cause timeout errors. Processing the packages individually seems to enable the process to succeed.

↑ Back to top