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

Filed under:
|

In the series the following parts have been published

  1. Part 1: Introduction
  2. Part 2: Add arguments and variables
  3. Part 3: Use more complex arguments
  4. Part 4: Create your own activity
  5. Part 5: Increase AssemblyVersion
  6. Part 6: Use custom type for an argument
  7. Part 7: How is the custom assembly found
  8. Part 8: Send information to the build log
  9. Part 9: Impersonate activities (run under other credentials)
  10. Part 10: Include Version Number in the Build Number
  11. Part 11: Speed up opening my build process template
  12. Part 12: How to debug my custom activities
  13. Part 13: Get control over the Build Output
  14. Part 14: Execute a PowerShell script
  15. 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:

  1. Open the command prompt
  2. To run the script you must change the execution policy. To do this execute in the command prompt:

    powershell set-executionpolicy remotesigned
  3. Now go to the directory where you have saved the PowerShell script
  4. Execute the following command

    powershell .\HelloWorld.ps1

image_thumb1

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

  1. Add a new argument called “DeploymentScript” and set the appropriate settings in the metadata. See Part 2: Add arguments and variables  for more information.
  2. Scroll down beneath the TryCatch activity called “Try Compile, Test, and Associate Changesets and Work Items”
  3. 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.
  4. Add in the Then branch of the If activity a new Sequence activity and rename it to “Start deployment”
  5. Click on the activity and add a new variable called DeploymentScriptFilename (scoped to the “Start deployment” Sequence
  6. Add a ConvertWorkspaceItem activity on the “Start deployment” Sequence
  7. Add a InvokeProcess activity beneath the ConvertWorkspaceItem activity in the “Start deployment” Sequence
  8. Click on the ConvertWorkspaceItem activity and change the properties
    DisplayName = Convert deployment script filename
    Input = DeploymentScript
    Result = DeploymentScriptFilename
    Workspace = Workspace
  9. Click on the InvokeProcess activity and change the properties
    Arguments = String.Format(" ""& '{0}' "" ", DeploymentScriptFilename)
    DisplayName = Execute deployment script
    FileName = "PowerShell"
  10. 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.
  11. Do the same for a WriteBuildError activity on the "Handle Error Output"
  12. To publish it, check in the Build Process Template

This leads to the following result

image_thumb[14]

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.

image_thumb[16]

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

image_thumb[18]

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.

  1. Add a new Argument called DeploymentScriptParameter
  2. In the InvokeProcess activity where the PowerShell command is executed, modify the Arguments property to String.Format(" ""& '{0}' '{1}' "" ", DeploymentScriptFilename, DeploymentScriptParameter)
  3. 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.

image_thumb[21]


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

Related posts about VS 2010

Related posts about Team Build