Sitecore 9 SIF – WebDeploy Gets What WebDeploy Wants

I’ve been doing a lot with Sitecore 9 lately as we work to retrofit automation processes into the new Sitecore Installation Framework (SIF) paradigm.  It will be nice to have Sitecore’s approved way of provisioning a Sitecore environment with JSON and PowerShell . . . but it’s a shame we’ve spent years investing in our own libraries doing the same thing with essentially the same technologies 🙂

That may sound like sour grapes from me, but that’s not really the case.  It’s just not trivial to master the SIF specifics at the same time as one is digesting the whole of Sitecore 9 with xConnect, Sitecore PaaS, and Sitecore 9 for Commerce coming any day now.  Taking a step back, I’m now in the process of crafting PowerShell to automate the prequisites for Sitecore 9 SIF — and if that strikes you as ironic, I think you get my point.  Can a publicly available Sitecore 9 bootstrapper be that far away?  Lets just hope it’s not a custom miasma of JSON with PowerShell and with it’s very own prerequisites to perpetuate the cycle!

Just an aside: I think many of us are doing the same thing, just refer to this effort around Solr or this GUI to layer on top of Sitecore’s new framework.  Both these efforts, and many others, are excellent, but illustrate how Sitecore 9 SIF feels unfinished.

With that all off my chest . . . I thought I’d share a gotcha with SIF that I haven’t seen documented elsewhere in case it helps others.  Categorize this as a self-inflicted Sitecore 9 SIF wound, I can’t really blame the framework here — the exception message is actually very helpful.  While the WebDeploy task was running with any Sitecore 9 SIF installation, I would get this error every time from a few of our servers:

Could not deploy package.
Internal Error. The database platform service with type Microsoft.Data.Tools.Schema.Sql.Sql130DatabaseSchemaProvider is not valid. You must make sure the service is loaded, or you must provide the full type name
of a valid database platform service.

Here’s how it looks in situ as part of the InstallWDP : WebDeploy task with SIF:


This didn’t happen on development environments, but on some build servers or new virtual machines.

I reviewed the Sitecore installation documentation but couldn’t see anything explicitly speaking to this, and I verified the SQL Server DAC fx was consistent with the installation docs.  My initial solution was to install SQL Server Management Studio (SSMS) as that package includes the key dependencies for automating SQL Server 2016 the way SIF expects.  Then I realized it’s probably encompassed in this line item tucked into the Installation Guide:


The link reads more like VS.Net integration tooling when I glanced at it, so I initially dismissed it for my use-case . . . but WebDeploy gets what WebDeploy wants, and to get Sitecore 9 SIF running you’ll need these libraries one way or the other.

This explains why development machines or other servers that had been around a while wouldn’t exhibit this problem — they already had the SQL tooling installed through one means or another.

For posterity, here’s the output from my console in case it helps a web searcher find their resolution . . .

InstallWDP : WebDeploy 
[WebDeploy]:[Path] C:\Program Files\iis\Microsoft Web Deploy V3\msdeploy.exe
Info: Adding MsDeploy.Site (MsDeploy.Site).
Info: Adding database (user id=sqlUserNotTelling;data source=SC9Run482-SQL;initial catalog=xp0482_Processing.Pools)
Info: Initializing deployment: Pending.
Info: Analyzing deployment plan: Pending.
Info: Updating database: Pending.
Info: Creating deployment plan: Pending.
Info: Verifying deployment plan: Pending.
Info: Deploying package to database: Pending.
Info: Creating deployment plan: Running.
Info: Initializing deployment: Running.
Info: Initializing deployment (Start)
Info: Initializing deployment: Faulted.
Info: Initializing deployment (Failed)
Info: Creating deployment plan: Faulted.
Info: Verifying deployment plan: Faulted.
Info: Deploying package to database: Faulted.
msdeploy.exe : Error Code: ERROR_EXECUTING_METHOD
At C:\Program Files\WindowsPowerShell\Modules\SitecoreInstallFramework\1.1.0\Public\Tasks\Invoke-CommandTask.ps1:31 char:13
+ & $Path $Arguments | Out-Default
+ ~~~~~~~~~~~~~~~~~~
 + CategoryInfo : NotSpecified: (Error Code: ERROR_EXECUTING_METHOD:String) [], RemoteException
 + FullyQualifiedErrorId : NativeCommandError
More Information: Could not deploy package.
Internal Error. The database platform service with type Microsoft.Data.Tools.Schema.Sql.Sql130DatabaseSchemaProvider is not valid. You must make sure the service is loaded, or you must provide the full type name
 of a valid database platform service.

Powershell installation of Sitecore Performance Counters

Today was the day I bit the bullet and automated this bit of administrative work that we do for all our Sitecore projects. I think it was the fresh crop of 9 new Sitecore IIS nodes that needed this attention that was the final impetus.

Sitecore Performance Counters

This blog reviews all the perf counters Sitecore makes available.  The documentation is a bit thin from Sitecore, since these counters were added to the product several years ago and they apparently don’t get much attention.  They do require special effort to setup as part of your IIS environment, too, so it’s easy to overlook them.  They’re still very handy, though!  A future blog post could discuss the ones most worthy of attention (in my humble opininion).

You can download the .zip file with an installer for the Sitecore specific performance counters at  These files are what you’ll end up with:


The .EXE runs through all the .XML files in the directory that enumerate perf counters relevant to Sitecore, and adds the counter to the computer.  It’s easy.

Scripted Installation

One would typically click the SitecoreCounters.EXE, press the {enter} key, and then the performance counters would quickly install to the server.  Doing this for many servers, or as part of an automated provisioning effort, could be tedious . . . we actually invoke this via remote magic with Ansible (but that’s not the focus of this blog post).  I do want to go over how we automated this, however, since it wasn’t the smooth sailing I expected it to be.

I’ve posted a Powershell baseline for installing Sitecore perf counters to this github gist.  It was straight-forward Powershell until I found the .EXE was running properly, but no performance counters were actually being added.  I had to look at the decompiled .EXE source to figure out why.  Here’s the Main method of the .EXE; I’ve bolded the instruction that was giving me problems:

        private static void Main(string[] args)
            Console.WriteLine("Press enter to begin creating counters");
            Console.WriteLine("Creating Sitecore counters");
            string[] files = args;
            if (args.Length == 0)
                files = Directory.GetFiles(Environment.CurrentDirectory, "*counter*.xml");
            foreach (string str in files)
                new Counters(str).Execute();

The “Environment.CurrentDirectory” in Powershell is by default something like C:\Users\UserName, but my Powershell was using a staging location to download and unzip the perf counter executable and related xml:

$zipFileURI = ""
$stageFolder = "C:\staging" 
if( !(test-path $stageFolder) )
    mkdir $stageFolder
$downLoadZipPath = $stageFolder + "/"  
Invoke-WebRequest -Uri $zipFileURI -OutFile $downLoadZipPath
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory($downLoadZipPath, $stageFolder)

Based on what I saw in Reflector, I needed to change my staging directory or to assign the Environment.CurrentDirectory to be $stageFolder in order for the perf counters to properly be installed to the new environment.  I really wanted to use a configurable location instead of some default Powershell directory, so I sifted through Powershell documentation and figured out the magic API call was [System.IO.Directory]SetCurrentDirectory; this example makes it apparent:

Write-Output "Default directory:"
 [System.IO.Directory]::SetCurrentDirectory($stageFolder + "\sitecorecounters 7.5")
 Write-Output "Directory changed to:"

With that in place, the context of the Sitecore perf counter .EXE was set properly and the program could locate all the counters defined in the XML files.

The end result is our new Sitecore specific perf counters are ready:


You will need to recycle the Sitecore App Pool in IIS for this to take effect, something like this should suffice:

$theSite = "Cool Sitecore Site"
$thePool = (Get-Item "IIS:\Sites\$theSite"| Select-Object applicationPool).applicationPool
Restart-WebAppPool $thePool