Continuous Learning and Sharing of Team Foundation Server and Application Lifecycle Management RSS 2.0
# Saturday, July 02, 2011

PowerShell is an awesome technology.  It has become an essential tool for doing automated deployments with Team Foundation Server 2010.  Creating deployment scripts in PowerShell are very easy to manage and maintain by the entire development without having to know about the details of the build definitions.  In future posts, I will explain how I use the build definitions and PowerShell to perform the deployments.  With this post I wanted to share a small tip on being able to catch all errors with a Try, Catch.

In PowerShell, there are two types of errors. Terminating errors and non-terminating errors.  Terminating errors will automatically be caught in a Try, Catch block but non-terminating errors will not.  Look at this example below.

try
{
    copy-item "c:\notexists\file.txt" "c:\temp"
}
catch {

write-host "bad copy"

}

This command looks like it should write to the out the error message because the folder and file do not exists. However when you run this, it will only display the PowerShell error message. 

Copy-Item : Cannot find path 'C:\notexists\file.txt' because it does not exist.
At C:\temp\copyitem.ps1:3 char:14
+     copy-item <<<<  "c:\notexists\file.txt" "c:\temp"
    + CategoryInfo          : ObjectNotFound: (C:\notexists\file.txt:String) [Copy-Item], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemCommand

This is an example of a non-terminating error.  There are two ways to fix this.  The –ErrorAction ”Stop” flag can be added to many of cmdlets. 

copy-item "c:\notexists\file.txt" "c:\temp" -ErrorAction "Stop"

Now, when the script is run, it will display the error message, “bad copy”.

This is great but if you are like me, you don’t want to have to add this to every command.   Luckily there is a way to do this for the entire script.  At the beginning of the script, you can set $ErrorActionPreference = “Stop”.  If you want to be able to toggle it, it default setting is “Continue”.

$ErrorActionPreference = "Stop"

Here is the final script.  Enjoy!

$ErrorActionPreference = "Stop"

try
{
    copy-item "c:\notexists\file.txt" "c:\temp"
}
catch {

write-host "bad copy"

}

 

Saturday, July 02, 2011 10:14:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [0] -
PowerShell | Team Build 2010

# Tuesday, December 07, 2010

Team Deploy 2010 is a custom add-on for Team Foundation Server 2010 (TFS) to deploy MSIs to servers and PCs.  The deploy activity uses an XML file to manage the servers and steps for deployment including starting/stopping services and installing/uninstalling the MSIs.  This is very effective for automated deployments in environments where automated deployments are allowed.  This however does not provide a practice run into downstream environments where automated deployments are not allowed such as Staging/Integration and Production.

An alternative to this that does offer some deployment consistencies beyond the MSI is to have Team Deploy 2010 (or Team Deploy for TFS 2008 also supports this) execute a PowerShell script to perform the deployment steps.  The advantage of this is that the PowerShell scripts can also be used to perform the manual deployments to these other environments.  This won’t work in every scenario but should in a lot.  In this post, I am going to explain how to do this.

The first thing to do is to install Team Deploy 2010.  This is free and can be downloaded at http://TeamDeploy.CodePlex.com.  The installation instructions are detailed on the site.  For this, I will assume Team Deploy 2010 is already installed.

Next open Visual Studio 2010 and create a new build definition workflow.  Create 3 arguments called RemoteExecuteFilename, TargetMachine, and RemoteCommand.

Instead of using the Deploy activity, add the RemoteExecute activity in an AgentScope container.

image

Set the properties on the RemoteExecute activity to the arguments passed in.

image

Next, set the properties that were exposed as arguments of the build definition.  For the RemoteCommand, here is where you want to specify calling PowerShell.exe and the script file that will be executed on the target machine.  One thing I have learned after taking this snapshot is that if you have a space in the path for the script than use this syntax:

PowerShell.exe –File “\\buildserver\deploy scripts\Update.ps1”

Next specify the path where the PSTools were installed and finally specify the machine that you want to run the remote script.

image

The final step is to create the deployment script.  Thanks to the power of PowerShell, these deployment scripts can perform any action.  I have created steps for starting/stoping services, applying SQL Server schema changes, search and replace strings in configuration files, etc. Essentially anything you can do in a batch file and in .NET code, can be done in PowerShell.

Here is a small sample script that I created.  I have creates some much more complicated scripts and ran them on remote machines without any issues.

"Performing removal steps..."

$servicename = "PLA"
$service = Get-Service $servicename
if($service.Status -eq "Running")
{
    "Stopping " + $servicename
    Stop-Service $servicename
}
"status=" + $service.Status
Remove-Item "c:\miketest2"
msiexec /qn /x "{26260DBA-1519-4967-9118-D827793EF3B3}"

"Removal complete.  Starting the installation steps..."

msiexec /qb! /i "\\buildserver\deploy\simple.msi"
New-Item "c:\miketest2" -type directory

"Applying SQL Server Schema changes..."
sqlcmd -S W2K8R2BOOT -E -i \\buildserver\deploy\dropaddcooltable.sql

if($service.Status -eq "Stopped")
{
    "Starting " + $servicename
    Start-Service $servicename
}

This is it. Here are also a couple things to consider. Copy MSIs, SQL Scripts, and the deployment script to a versioned folder.  The folder is the snapshot in time including the deployment file.  Keep the deployment scripts in source control.  Lastly there is a new feature in PowerShell 2.0 called PowerShell Remoting.  I have tried it, but it looks like this could also work.  It is on my list to research and I will be sure to report back when I find out more information.

Enjoy!

Mike

This was cross posted at http://www.deliveron.com/blog/post/Executing-PowerShell-Scripts-on-Remote-Machines-with-TFS-2010-and-Team-Deploy-2010.aspx on the Deliveron’s blog at http://www.deliveron.com/blog.

Tuesday, December 07, 2010 11:45:00 PM (Central Standard Time, UTC-06:00)  #    Comments [0] -
ALM | PowerShell | Team Build 2010 | Team Deploy | TFS 2010 | Visual Studio 2010

Visual Studio ALM MVP
Microsoft Visual Studio ALM MVP
Archive
<February 2012>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2012
Mike Douglas
Sign In
Statistics
Total Posts: 76
This Year: 0
This Month: 0
This Week: 0
Comments: 53
All Content © 2012, Mike Douglas
DasBlog theme 'Business' created by Christoph De Baene (delarou)