Part 14: Execute a PowerShell script
Posted
on Ewald Hofman
See other posts from Ewald Hofman
Published on Tue, 09 Nov 2010 14:32:19 +0100
Indexed on
2010/12/29
18:00 UTC
Read the original article
Hit count: 686
VS 2010
|Team Build
In the series the following parts have been published
- Part 1: Introduction
- Part 2: Add arguments and variables
- Part 3: Use more complex arguments
- Part 4: Create your own activity
- Part 5: Increase AssemblyVersion
- Part 6: Use custom type for an argument
- Part 7: How is the custom assembly found
- Part 8: Send information to the build log
- Part 9: Impersonate activities (run under other credentials)
- Part 10: Include Version Number in the Build Number
- Part 11: Speed up opening my build process template
- Part 12: How to debug my custom activities
- Part 13: Get control over the Build Output
- Part 14: Execute a PowerShell script
- Part 15: Fail a build based on the exit code of a console application
With PowerShell you can add powerful scripting to your build to for example execute a deployment. If you want more information on PowerShell, please refer to http://technet.microsoft.com/en-us/library/aa973757.aspx
For this example we will create a simple PowerShell script that prints “Hello world!”. To create the script, create a new text file and name it “HelloWorld.ps1”. Add to the contents of the script:
Write-Host “Hello World!”
To test the script do the following:
- Open the command prompt
- To run the script you must change the execution policy. To do this execute in the command prompt:
powershell set-executionpolicy remotesigned - Now go to the directory where you have saved the PowerShell script
- Execute the following command
powershell .\HelloWorld.ps1
In this example I use a relative path, but when the path to the PowerShell script contains spaces, you need to change the syntax to
powershell "& '<full path to script>' "
for example:
powershell "& ‘C:\sources\Build Customization\SolutionToBuild\PowerShell Scripts\HellloWorld.ps1’ "
In this blog post, I create a new solution and that solution includes also this PowerShell script. I want to create an argument on the Build Process Template that holds the path to the PowerShell script. In the Build Process Template I will add an InvokeProcess activity to execute the PowerShell command. This InvokeProcess activity needs the location of the script as an argument for the PowerShell command. Since you don’t know the full path at the build server of this script, you can either specify in the argument the relative path of the script, but it is hard to find out what the relative path is. I prefer to specify the location of the script in source control and then convert that server path to a local path. To do this conversion you can use the ConvertWorkspaceItem activity.
So to complete the task, open the Build Process Template CustomTemplate.xaml that we created in earlier parts, follow the following steps
- Add a new argument called “DeploymentScript” and set the appropriate settings in the metadata. See Part 2: Add arguments and variables for more information.
- Scroll down beneath the TryCatch activity called “Try Compile, Test, and Associate Changesets and Work Items”
- Add a new If activity and set the condition to "Not String.IsNullOrEmpty(DeploymentScript)" to ensure it will only run when the argument is passed.
- Add in the Then branch of the If activity a new Sequence activity and rename it to “Start deployment”
- Click on the activity and add a new variable called DeploymentScriptFilename (scoped to the “Start deployment” Sequence
- Add a ConvertWorkspaceItem activity on the “Start deployment” Sequence
- Add a InvokeProcess activity beneath the ConvertWorkspaceItem activity in the “Start deployment” Sequence
- Click on the ConvertWorkspaceItem activity and change the properties
DisplayName = Convert deployment script filename
Input = DeploymentScript
Result = DeploymentScriptFilename
Workspace = Workspace - Click on the InvokeProcess activity and change the properties
Arguments = String.Format(" ""& '{0}' "" ", DeploymentScriptFilename)
DisplayName = Execute deployment script
FileName = "PowerShell" - To see results from the powershell command drop a WriteBuildMessage activity on the "Handle Standard Output" and pass the stdOutput variable to the Message property.
- Do the same for a WriteBuildError activity on the "Handle Error Output"
- To publish it, check in the Build Process Template
This leads to the following result
We now go to the build definition that depends on the template and set the path of the deployment script to the server path to the HelloWorld.ps1. (If you want to see the result of the PowerShell script, change the Logging verbosity to Detailed or Diagnostic). Save and run the build.
A lot of the deployment scripts you have will have some kind of arguments (like username / password or environment variables) that you want to define in the Build Definition. To make the PowerShell configurable, you can follow the following steps.
Create a new script and give it the name "HelloWho.ps1". In the contents of the file add the following lines:
param (
$person
)
$message = [System.String]::Format(“Hello {0}!", $person)
Write-Host $message
When you now run the script on the command prompt, you will see the following
So lets change the Build Process Template to accept one parameter for the deployment script. You can of course make it configurable to add a for-loop that reads through a collection of parameters but that is out of scope of this blog post.
- Add a new Argument called DeploymentScriptParameter
- In the InvokeProcess activity where the PowerShell command is executed, modify the Arguments property to String.Format(" ""& '{0}' '{1}' "" ", DeploymentScriptFilename, DeploymentScriptParameter)
- Check in the Build Process Template
Now modify the build definition and set the Parameter of the deployment to any value and run the build.
You can download the full solution at BuildProcess.zip. It will include the sources of every part and will continue to evolve.
© Ewald Hofman or respective owner