I briefly mentioned a technique I used to deploy custom assemblies for SSRS to the GAC in my PASS presentation on
Building a Reporting Services Framework. I didn’t spend a lot of time on that, but I did get some questions on it, so I thought I’d go into more detail here. Here’s a pointer to the documentation around custom assembly deployment from MS. This post is how to automate the process if you’re using the GAC method.
Here is a code sample showing how I perform the remote deployment.
Before we actually get around to deploying to the server we need to be able to test our custom assembly locally. I use the following Post-Build Event in my custom assembly. If you aren’t familiar with Build Events, you get to them by right-clicking on the project and choosing ‘Build Events’ in the left hand side of the properties.
[sourcecode language="bash" padlinenumbers="true"] copy "$(TargetPath)" "%ProgramFiles%Microsoft Visual Studio 9.0Common7IDEPrivateAssemblies" gacutil.exe -i $(TargetPath) copy /Y "$(TargetPath)" "C:_PASS_DemoDeployAssemblies" [/sourcecode]
This build event does three things:
- Copies the dll to the PrivateAssemblies directory. This makes the custom assembly available to BIDS so you can use it in Preview Mode. You have to restart BIDS after updating the custom assembly for the new version to be loaded.
- GAC’s the custom assembly so it can be used by your local Reporting Services instance. This will require a restart of the service to be live, but I typically don’t include that in the build process because it takes a few seconds and I’m use it less often.
- Copies the dll to the Deployment section of my solution. I typically source control the dll, and use the process described later in this post to deploy the assembly to other environments.
Here is the solution that I found for automating deployments for other servers. You have to jump through a few hoops to be able to do this (at least with Windows Server 2008 R2). If you search the web you’ll find a few other solutions to this problem, but I didn’t find any that met my specific needs. The specific scenario I was trying to enable was unattended deployments. If you log in to the machine, or if you’re able to provide credentials, this is an easier problem. This was the only way I found to do this without manually collecting credentials. If you do that and use credssp, you can use PowerShell to do this remotely. If you are willing to send an admin password clear text, you can use PSExec. Neither of those two solutions met my needs, so I chose the following approach:
- Copy the assembly to the target machine.
- Install the assembly using System.EnterpriseServices executed via a remote call.
- Verify the assembly was actually installed (the installation procedure doesn’t return failures).
- Restart the ReportServer service.
You might need to tweak the example scripts a little bit for your environment. You might also want to dot source the DeploymentLibrary script (i.e., ./DeploymentLibrary.ps1) in deploy_ssrs_assemblies.ps1. I have all my libraries load as part of my profile, so this may assume the library is already loaded. The installation process just takes the path you deployed the assembly to (such as “\Server01-devd$ReportsdeploymentassembliesEltUtilities.dll”) and figures out the name of the assembly and the server from it.
The sample I provided is laid out as follows:
- Deployment – The root of the deployment structure.
- Assemblies – The assemblies we want to deploy. I also typically include other libraries used for other types of automated deployments here as well.
- Dev – This contains a simple driver file that sets all the variables necessary for a deployment to the dev environment. I usually also have a localhost, qa, and prod folder as well (identical scripts except for the variables). The code to set up the logging should probably be refactored into another method in the PowerShell library, but that’s on the TODO list.
- deploy_ssrs_assemblies.ps1 – The script that handles the orchestration of the deployment. This is common, parameter driven functionality that is called by the drivers for each of the environments.
- DeploymentLibrary.ps1 – The methods that install the assembly on the remote server and restart the services.
There are a few moving pieces to this process, but the example should be pretty well documented.
That’s about it. If this solution doesn’t meet your specific needs, there are a few other ones out there (such as Remote GAC Manager) that might, or you can just use the standard PSExec approach. Happy automating!