Navigate Visual Studio Team Services Projects like a file system using PowerShell

Visual Studio Team Services or VSTS is a great tool for continuous integration and continuous deployment. It is a cloud based SaaS offering from Microsoft. So most of the time you would be navigating it using a web browser like google chrome, firefox or Edge. In this blog post, we will learn how to treat VSTS like a file system using PowerShell.


You must have PowerShell version 5 or later or PowerShell core installed on your operating system for this to work.

Few words about SHiPS

SHiPS or Simple Hierarchy in PowerShell is a PowerShell provider that allows any data store to be exposed like a file system as if it were a mounted drive. In other words, the data in your data store can be treated like files and directories so that a user can navigate data via cd or dir. SHiPS is a PowerShell provider. To be more precise it’s a provider utility that simplifies developing PowerShell providers.

It is an open source project available at Here, you can view more details on this project as well as start contributing to it.

VSTeam PowerShell Module

VSTeam is a PowerShell module that exposes portions of the REST API for Visual Studio Team Services and Team Foundation Server. It is purely written in PowerShell only and available for Mac, Linux or Windows operating systems.
Since we must have PowerShell v5 or later installed, we can simply use Install-Module cmdlet to download and install it.

Install-Module -Name VSTeam -Confirm:$false -Verbose

Above command will also download and install dependent module SHiPS for it to work:

Install vsteam powershell module

Create Personal Access Token or PAT in VSTS

For VSTeam module to work, we need to provide a personal access token which have proper access to VSTS projects. To create a PAT, open VSTS account, go to your profile and then select security. After this, you can create PAT. Do note that since VSTS does not stores PATs, you need to save it for later before refreshing the page.

Connecting VSTeam Module with VSTS account

We need to first import VSTeam Module into current PowerShell window before we can start using it. Let’s import it with verbose enabled so that we can also see what are the cmdlets and functions exposed by this module. Command to do the same would be:

Import-Module -Name VSTeam -Verbose

Import module VSTeam

Next, we need to create VSTeam Profile. For this, we need to run the below command:

Add-VSTeamProfile -Account '[VSTSOrTFSAccountName]' -PersonalAccessToken '[personalaccesstoken]' -Name '[ProfileName]'

where VSTS account name would simple be your account name without the suffix and https://:

Add vsteam profile

As you might have guessed, this cmdlet basically stores your account name and personal access token as a profile for use with the Add-TeamAccount function.

Once this is done, we now need to create SHiPS drive named vsteam for our VSTS account. This can be done using:

Add-VSTeamAccount -Profile [profilename] -Drive vsteam
New-PSDrive -Name vsteam -PSProvider SHiPS -Root 'VSTeam#VSAccount'

Create and add SHiPS drive

Navigate VSTS Projects like file system

First we need to navigate to the newly created PSDrive. We can do that by using below command:

cd vsteam:

Once its done, we can get list of projects in VSTS accounts by simply using get-ChildItem:

Start using vsteam drive
Start using vsteam drive

We can then see projects details as:

Start using vsteam drive - 2

The ability to use VSTS as filesystem is very Powerful. Some of the more elaborate examples include getting list of builds and releases, getting list of failed and passed builds/releases, no of builds requested for a specific developer, etc.

Few examples released from Microsoft in one of the blog posts are as below:

#region find all rejected releases for specific requestor
Get-ChildItem ..\Releases | Where-Object {$_.createdByUser -eq 'Stefan Stranger'} |
Where-Object {$_.Environments.status -eq 'rejected'} |
Select-Object createdByUser |
Group-Object -Property createdByUser -NoElement

#region find all rejected releases grouped by creator
Get-ChildItem ..\Releases |
Where-Object {$_.Environments.status -eq 'rejected'} |
Select-Object createdByUser |
Group-Object -Property createdByUser -NoElement |
Sort-Object -Property Count

#region overview of failed releases per release definition
Get-ChildItem ..\Releases |
Where-Object {$_.Environments.status -eq 'rejected'} |
Select-Object createdByUser, @{'L' = 'Name'; E = {$[0]}} |
Group-Object -Property Name |
Sort-Object -Property Count -Descending

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s