In every environment you need to automate the deployment process for SharePoint solutions – weather they’re sandboxed solutions, farm solutions or apps.
But developers are lazy – and it’s so easy to click “Deploy” in VS that normally the deployment scripts are poorly tested. To get the developers to use and test the deployment scripts you have to integrate them in visual studio.
If you use PowerShell scripts for your deployments and always place them in the same location this is pretty easy. You can add the scripts as “External Tools” and then add them to the context menu.
To add an external tool just go in Visual Studio to Tools –> External Tools.
No comes the tricky part. If you start the PowerShell from within Visual Studio it gets loaded as the x86 version. Unfortunately SharePoint scripts do not run in a x86 process. To force the PowerShell to run as x64 you have to enter the “Command” as follows:
C:\windows\sysnative\WindowsPowerShell\v1.0\powershell.exe
Set the “Initial Directory” to the path of your scripts. You can use the variable $(ProjectDir) to reference a relative path to your project.
Specify the script and all “Arguments” like this:
-File .\Update-Solution.ps1 -Environment:D -Local -InstallPath:”$(BinDir)”
The variable $(BinDir) point to your output folder. To make sure your wsp gets generated with every build you have to edit your project file:
Right click Projet –> Unload Project
Right click Projet –> Edit …csproj
Add following snippet:
<PropertyGroup> <IsPackaging>True</IsPackaging> </PropertyGroup>
Right click Projet –> Reload Project
You can set “Use Output window” to execute the script inside the IDE and write the messages to the output window.
use the variable $(ProjectDir) to reference a relative path to your project.
Specify the script and all “Arguments” like this:
-File .\Update-Solution.ps1 -Environment:D -Local -InstallPath:”$(BinDir)”
The variable $(BinDir) point to your output folder. To make sure your wsp gets generated with every build you have to edit your project file:
Right click Projet à Unload Project
Right click Projet à Edit …csproj
Add following snippet:
<PropertyGroup> <IsPackaging>True</IsPackaging> </PropertyGroup>
Right click Projet à Reload Project
You can set “Use Output window” to execute the script inside the IDE and write the messages to the output window.
To create a shortcut to the commands in the context menu go to: Tools à Customize à Commands. Select “Project and Solution Context Menus | Project and click “Add Command”
Under Tools you find “External Command X”. Just select the appropriate command from the list (in my case 7).
You can now start the script directly from the solution explorer.
That’s it. The output is displayed in the output window.
Some side notes to the script:
If you use SharePoint CmdLets you have to add PSSnapIn. Make it optional to not generate errors if you run the script manually.
if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) { Add-PSSnapin "Microsoft.SharePoint.PowerShell"; }
To behave as the SharePoint Management Shell you should also set the threading model:
$ver = $host | select version if ($ver.Version.Major -gt 1) {$host.Runspace.ThreadOptions = "ReuseThread"}
Make sure to use the SPAssignemtCollection for all the SharePoint CmdLets.
You can use CmdletBindings and Parameters like this:
[CmdletBinding(SupportsShouldProcess=$False, ConfirmImpact="Medium")] param( [Parameter(Mandatory=$true, Position=0, HelpMessage="Enter the short name of the environment. Posible values are: D, T, Q and P")] [ValidatePattern("^[D|T|Q|P]$")] $Environment, [Parameter(Mandatory=$true, Position=1, HelpMessage="The path to the folder that contains the solutions and other artifacts that are needed for the deployment.")] $InstallPath, [Parameter(HelpMessage="Only run deployment on a single server.")] [Switch]$Local )
You can also use $PSCmdlet.ShouldProcess. What you can’t do (I don’t know why) ist to use Begin{}, Process{} and End{} in your script. You have to stick with try{}catch.
You also can use transcript to log the output to a file…
But enough about deployment scripts. This post is not about SharePoint deployment scripts – this would fill a book.
But if you’re already configuring you external tools you can add some more useful tools. My favorites are:
Title | GetAssemblyName |
Command | powershell.exe |
Arguments | -command “[System.Reflection.AssemblyName]::GetAssemblyName(\”$(TargetPath\”).FullName” |
Title | Get Public Key Token Tool |
Command | C:\Program Files (x86)\Micosoft SDKs\Windows\v7.0A\Bin\sn.exe |
Arguments | -Tp $(TargetPath) |