Tips for Writing PowerShell Scripts to Use in Build and Release Tasks
Premier Developer ALM Consultant Dave Burnison brings us this awesome collection of tips and tricks for using PowerShell in VSTS and TFS.
You can now do almost anything in your build and release definitions in VSTS and TFS 2015. One of the most powerful ways to add your specific logic is to use the PowerShell task or the PowerShell on Target Machines task. The documentation that I have found shows you how to use these tasks but, it does not provide many details on how to manage your scripts or write PowerShell scripts that provide feedback to the user via the build and release hubs in Team Web Access. The goal of this blog is to show you how to use some of the commands that are documented here in your TFS Build and/or Release definitions when calling a PowerShell script. I will also show you how to manage shared scripts that can be used across team projects. The examples are from my VSTS account but, as of the time I am writing this, these examples are valid for on-premises TFS as well (TFS 2015 Update 2). For these examples, my source code is stored in TFVC.
Sharing Scripts Across Team Projects
I have a HelloWorld team project that has the application that I am going to build (e.g. $/HelloWorld/Main/HelloWorld.sln) and a Build team project that has common scripts that I want to use in multiple team projects (e.g. $/Build/PSScripts). I can see both source trees in Visual Studio.
When you first define a PowerShell script task it appears that you can only select scripts that live in the current team project. I cannot navigate to $/Build/PSScripts while in the HelloWorld team project.
To get around this, let’s first, add a mapping to $/Build/PSScripts on the Repository tab of the HelloWorld – Main build definition to create a Build folder in the local workspace on the build agent.
Now I’ll edit my PowerShell tasks. I cannot navigate to $/Build/PSScripts…however, I can manually enter the scripts folder that is now part of the build workspace in the Script filename box. Please note how I am using the $(build.sourcesDirectory) variable in the path to the .PS1 file.
Set a variable in one PowerShell task and access the updated value in subsequent tasks
Using variables in PowerShell scripts is documented here. If you just set the variable like this $env:DynamicVariable = “Temporary Value Set In Script”, the scope of the new value is only within the current task, (see “1” in the image below). To set a variable in one PowerShell task and access the updated value in subsequent tasks you need to use a special command: Write-Host “##vso[task.setvariable variable=DynamicVariable]Persistent Value Set In Script”, (see “2” in the image below).
Set progress and current operation for current task
My PowerShell script has a long running process so I want to provide a progress indicator in my build output. First I use Write-Host “Begin a lengthy process…” to indicate that I am starting a long running process. Second I use the Write-Host “##vso[task.setprogress value=$i;]Sample Progress Indicator” command to update the progress. The progress indicator is displayed next to the name of the PowerShell script task, (see the PowerShell code inset in the image below).
Displaying Warnings and Errors in the build output
You can leverage the Write-Warning & Write-Error PowerShell commands to display warnings and errors, or you can use the TFS specific task.logissue command to ensure the warnings and errors appears in the build summary. Here are the various commands:
1. # The following will appear in the console output preceded by “WARNING: ”
Write-Warning “This is a warning generated in a PowerShell script”
2. # The following will appear Build Summary as a Warning and in the task specific log in YELLOW text.
Write-Host “##vso[task.logissue type=warning;] PowerShell Warning Test”
3. # The following will appear in the Build Summary and the console output with additional error information”.
Write-Error “This is an error generated in a PowerShell script”
4. # The following will appear Build Summary as an Error and in the task specific log in YELLOW text.
Write-Host “##vso[task.logissue type=error;] PowerShell Error Test”
Here is what the output looks like in the console window as the build is running.
Here is what the output looks like in the Build Summary after the build has completed.
Bonus Info: Add your own section to the Build Summary output
If you want to add your own section to the Build Summary refer to the VSTS Extension Samples on GitHub, Look specifically at the “Build Results Enhancer” section.
Sample PowerShell Scripts
See the attached file, VSTSPowerShellScripts, for the two scripts I used in my examples above.
I’ve given you a taste of how to make your PowerShell scripts work in harmony with the VSTS/TFS Build and Release systems. For more details on the commands that I have used and additional commands that are available, refer to this documentation on GitHub.