What just happened to VSTeam?!

For those that do not know VSTeam is a PowerShell module that provides access to your Azure DevOps servers and services from PowerShell. As the module has gained in popularity (just passing half a million downloads) the number of community contributions has spiked. This is great for the module and the community. However, that much change comes with some challenges. Luckily Sebastian Schütze offered to be a maintainer of the repository to help keep up with the pull requests. Nevertheless, we found the use of PowerShell classes, the current structure of the project, and inconsistencies in functions and help was proving difficult to manage.

To address some of these challenges and to ensure VSTeam has a long life we established a GitHub organization MethodsAndPractices (named after the team I lead at Microsoft) and moved the VSTeam repository to that organization. This will ensure the module can live on even if the time comes that I can no longer be the primary maintainer. Just to be clear I am not going anywhere and just finished the most intense pull request on VSTeam to date getting ready for the 7.0 release. The 7.0 version of VSTeam will address many of the concerns listed above and much more.


The first issue we wanted to address was the use of PowerShell classes. The way they are managed and loaded during a PowerShell session created challenging situations for contributors slowing down our productivity. Therefore, the decision was made to move all the PowerShell classes into a new C# class library. The library uses .NET Core so the module and development still remains cross platform. Users and contributors can use macOS, Linux or Windows.

Moving the classes to C# not only removed the limitations in PowerShell but improved the testability of the code. We can use Visual Studio or Visual Studio Code and use their full power to achieve 100% code coverage.



VSTeam makes extensive use of PowerShell Types. The type files can be found in the Source/types folder. All the files in this folder and the types they contain were changed from VSTeamxxx to vsteam_lib.xxx. This was to align the type names with the class names in the class library. Doing so will make it easier to move a type to a class in the future. During the pull request all types were reviewed and any duplicates removed that are now C# classes.


Many of the classes also expose read-only properties named for use in pipelines. This will allow those values to map to parameters marked with the ValueFromPipelineByPropertyName attribute. For example the vsteam_lib.Release class exposes and “Id” and a “ReleaseId” that return the same value. The “ReleaseId” is a read-only property that allows the results of Get-VSTeamRelease to be to be piped into Get-VSTeamApproval.

Get-VSTeamRelease | Select-Object -First 1 | Get-VSTeamApproval


VSTeam also uses PowerShell Formats. The formats allow the default views to be defined. There are two views for any type that is returned from a function and also from the SHiPS provider classes. For example, when you call the Get-VSTeamProject function the results will appear with the following format:

Name          Description
----          -----------
Voting-App    Vote App

However, if you use the provider the projects appear formatted as a file system:

Mode   Name
----   ----
d-r-s- Agent Pools
d-r-s- Extensions
d-r-s- Feeds
d-r-s- Permissions
d----- PeopleTracker
d----- Voting-App

These changes in format are controlled by the formats selected by the type returned. When calling Get-VSTeamProject the type returned is vsteam_lib.Project while when called via the provider the type is vsteam_lib.Provider.Project. The properties and anatomy of the type is the same. They are only used to distinguish how the project was retrieved.

Formats are also used to drive consistently with the presented results. For example, the “Id” of any object should be the last column in a table or item in a list.

Project Name Parameter

Most functions in VSTeam require a ProjectName parameter. In the previous version this parameter was a positional parameter with a position of 0. This meant that you could pass the name of the project to use without -ProjectName if it was in the first position. However, because you can set the default project to be used using Set-VSTeamDefaultProject that parameter was rarely passed in explicitly. By forcing it to be a named parameter functions can now designate other parameters to position 0 and make the functions more convenient to work with. For example, if you set the default project you can add a new team to a project by simply typing:

Add-VSTeam NewTestTeam

Instead of:

Add-VSTeam -ProjectName Test -Name NewTestTeam

This will require far less typing when working with VSTeam during an interactive session.


Help is another place where we are making big investments. Users can now visit http://bit.ly/vsteam-docs to view the online documentation. This documentation is generated from the module help so there is perfect parity in the help presented online and using Get-Help cmdlet built into PowerShell. Each function has been updated with a HelpUri that will allow users to use the -Online parameter of the Get-Help cmdlet to open the help in your default browser.

help Add-VSTeam -Online


I want to take this opportunity to thank all the contributors to VSTeam. I never expected this project to be so well received by the community and supported. The support from Sebastian has been incredible and gives me confidence that VSTeam has a bright future.

Hope you enjoy the changes we have made in version 7.0 and look forward to the changes to come.

Comments (4) -

Add comment