How to add a user to Project Collection Service Account in TFS / VSO

VSO and TFS have a special group called: Project Collection Service Account that has really powerful permission, and usually no user should be part of that group. There are specific circumstances, like running TFS Integration platform to move code to TFS, where the account used to access VSO needs to be part of this group to temporary have special permission.

Sadly enough, the UI does not allow you to directly add a user to that group, because the add button is disabled if you select that group.


Figure 1: You cannot add users or group to Project Collection Service Account Users directly from the ui.

The reason behind this decition is security, adding a user to this group is not part of everyday operation, users in that groups has really powerful permissions and you should add users to Service Accounts only in really specific situations and only when really required. This is the reason why you need to resort to Command Line.

	"Project Collection Service Accounts" 

TfsSecurity.Exe command line utility can add whatever users to whatever group, bypassing limitation in the UI. Remember than to remove the user from that group when he does not need anymore special permission; the commandline is the same as previous one just change /g+ to /g-

As a rule of  thumb, users should only be added to Service Account group only if strictly required, and removed from that group immediately after the specific need ceased to exist.

In older version of VSO / TFS you could obtain the same result without command line in the UI. You just selected the user you want to add to Service Group, then go to the member of section and then, pressing plus button, add the user to the group, but this is actually disabled in actual version.


Figure 2: You cannot add anymore a user directly to a group.

If you really want to avoid command line, you can still use the UI. Just create a standard TFS Group and then add the group to the Project Collection Service Accounts. First step: create a group with a Really Explicit Name.


Figure 3: This group has a specific name that immediately tells to the reader that it is a special group.

Once the group is created, you can simply add it to the Project Collection Service Account group with few click.


Figure 4: Add new group to the Project Collection Service Accounts group

Now you can simply add and remove users to the “WARN – Service Account Users” group from the UI when you need to grant or remove Service Account Permission.

Gian Maria Ricci.

Publishing a Nuget package to Nuget/Myget with VSO Build vNext

Publishing a package to myget or nuget with a TFS/VSO vNext build is a breeze. First of all you should create a .nuspec file that specify everything about your package and include it in your source control. Then Add a variable to the build called NugetVersion as shown in Figure 1.

Adding NugetVersion variable to the list of variables for this build.

Figure 1: Added NugetVersion variable to build definition.

In this build I disabled continuous integration, because I want to publish my package only when I decided that the code is good enough to be published. Publishing to a feed for each build is usually a waste of resources and a nice way to make the history of your package a pain. Since I want to do manual publishing I’ve checked the “Allow at Queue Time” checkbox, to be able to change Nuget Version Number at queue time.

Build vNext has a dedicated step called NugetPackager that takes care of creating your package from nuspec file, so you do not need to include nuget.exe in your repository or in the server. If you are curious where is nuget.exe stored, you can check installation folder of your build agent, and browse the Task Directory where all the tasks are contained. There you should find the NugetPackager folder where all the script used by the tasks are stored.

How to configure Nuget Packager to create your package.

Figure 2: Added Nuget Packager step to my build.

You can use wildchars as pattern to nuspec files; as an example you can specify **\*.nuspec to create a package for all nuspec file in your source directory. In this example I’have multiple nuspec in my repository, but I want to deploy only a specific package during this build, so I’ve decided to specify a single file to use. Thanks to the small button with ellipsis at the right of the textbox, you can choose the file browsing the repository.

Thanks to source browsing you can easily choose your nuspec file to create package.

Figure 3: Browsing source files to choose nuspec file to use.

Then I’ve choose $(Build.StagingDirectory) as Package folder, to be sure that resulting nupkg file will be created in staging directory, outside of the src folder. This is important, because if you do not choose to clean src folder before each build, you will end with multiple nupkg file in your agent work directory, one for each version you published in the past. If you use StagingDirectory as destination for your nupkg files, it will be automatically cleared before each build. With this configuration you are sure that staging directory contains only .nupkg files created by current build.

Finally in the Advanced tab I’ve used the Nuget Arguments textbox to specify the -version option to force using version specified in the $(NugetVersion) build parameter.

The last step is including a step of type Nuget Publisher, that will be used to publish your package to nuget / Myget.

Configuration of NugetPublisher step to publish your package to your feed

Figure 4: Final publishing step to publish nuget to your feed.

If you use Staging Directory as output folder for your Nuget Package step, you can specify a pattern of $(build.stagingDirectory)\*.nupkg to automatically publish all packages created in previous steps. If you will change the build in the future adding other NugetPackager steps to create other packages, you can use this single Nuget Publisher to automatically publish every .nupkg file found in staging directory.

Finally you need to specify the Nuget Server Endpoint; probably your combobox is empty, so you need to click the Manage link at the right of the combo to manage your endpoint.

Manage endpoint in your VSO account

Figure 5: Managing endpoint

Clicking Manage link, a new tab is opened in the service tab of Collection configuration, here you can add endpoint to connect your VSO account to other service. Since Nuget or MyGet is not in the list, you should add a new service endpoint of type Generic.

Specify your server url and your api key to create an endopint

Figure 6: Adding endpoint for nuget or myget server

You must specify the server url of your feed and your API KEY in the Password/Token Key field of the endpoint. Once you press OK the endpoint is created; no one will be able to read the API KEY from the configuration and your key is secured in VSO.

Now all Project Administrators can use this endpoint in your Nuget Publisher step to publish against that feed, without giving them API KEY or password. All endpoints have specific security so you can specify the list of the users that will be able to change that specific endpoint or list of users that will be only able to Read that specific endpoint. This is a nice way to save details of your nuget feed in VSO, specifying the list of the user that can use this feed, without giving password or token to anyone.

When everything is done, you can simply queue a new build, and choose the version number you want to assign to your Nuget Package.

You can queue the build specifying branch and Nuget Numbering

Figure 7: Queuing a build to publish your package with a specific number.

You have the ability to choose the branch you want to publish, as well as the Number of your nuget package to use. Once the build is finished your package should be published.

Feed detail in MyGet account correctly list packages published by my vNext build

Figure 8: Your package is published in your MyGet feed.

In previous example I’ve used master branch and published version number 1.3.1. Suppose you want to publish a pre-release package with new features that are not still stable. These features are usually in develop branch (especially true if you use GitFlow with git repositories), and thanks to configuration you can simply queue a new build to publish pre-release package.

Specifing developing branch and a package number ending with beta1 you can publish pre-release packages.

Figure 9: Publish a pre-release package using develop branch and a nuget version that has a –beta1 suffix.

I’ve specified to use develop branch and a nuget version number ending with –beta1, to specify that it is a pre-release package. When the build is finished you can check from your visual studio that everything is ok.

Verify that in Visual Studio stable and Pre-Release package is ok.

Figure 10: Verify in Visual Studio that everything is ok.

Thanks to Build vNext, publishing your package to myget or nuget or private nuget feed is just a matter of including a couple of steps and filling few textboxes.

Gian Maria.

Resolve associated Work Item at each check-in

If you work with TFVC when you Check-in your code, the default action is close associate Work Item. VS2015 has an option for you in Settings pane of the Visual Studio Team Foundation Server Source Control to change this default behavior to associate.

As you can see in Figure 1 the default value is to Resolve associated Work Items on check-in but you can easily uncheck the option to make “Associate” the default action for Work Items associated to a Check-in.


Figure 1: Option to resolve associated Work Items on Check-in

In previous version of Visual Studio (2010, 2012, 2013) you can use a Registry key, as described in this old post of Matt Mitrick to obtain the same result.

Gian Maria.

Completely remove Lab Management configuration in TFS

If you want to completely remove Lab Management configuration from your TFS instance, you probably know TfsConfig lab /Delete command, used to remove association between one Project Collection and SCVMM. The reasons behind the need to completely remove Lab Management configuration could be various, one of the most common is: you created a cloned copy of your TFS environment for testing purpose, and you want to be 100% sure that your cloned instance does not contact SCVMM, or you can simply have multiple Test TFS Instance and you need to move lab management from one instance to another.

Actual configuration, with PreviewCollection with Lab Management features enabled.

Figure 1: PreviewCollection has Lab Management configured.

In the above picture you can see that my PreviewCollection has Lab Management feature enabled, so I can simply run the command TfsConfig lab /Delete /CollectionName:PreviewCollection to remove this association.

TfsConfig lab /delete command in action

Figure 2: TfsConfig command in action.

When command completes you can verify that the collection has not Lab Management feature enabled anymore.

Project collection now have lab management feature disabled

Figure 3: PreviewCollection now has Lab Management feature disabled.

After running that command for all your Lab Management enabled Team Project Collections you can be disappointed because you still see SCVMM host configured in TFS Console.

Even if none of the team projection collection is configure, scvmm host is still listed

Figure 4: Even if none of the team projection collection is configure, scvmm host is still listed

This is usually not a big problem, but if you want to be 100% sure that your TFS installation does not maintain any connection to the SCVMM instance used to manage your Lab, you can use a simple PowerShell script you can find on this Blog Post. That post is related to TFS 2010, but the script it is still valid for newer TFS releases. To write this blog post I’ve used a TFS 2015 instance and everything went good.

In that post you have an alternative solution of directly updating Tfs_Configuration database, but I strongly discourage you to use that solution because you can end with a broken installation. Never manipulate Tfs databases  directly.

Lab Management is completely removed from your TFS instance

Figure 5: Lab Management is completely removed from your TFS instance

Now lab management configuration is completely removed from your TFS instance.

Gian Maria.

Create a safe clone of your TFS environment

ChangeServerId to avoid confusion of client tools

Around the web there are a lot of resources about how to create a clone of your TFS environment for testing purpose. The most important step was always running the TfsCongfig ChangeServerId Command as described in the Move Team Foundation Server from your hardware configuration to another.

With the new wave of guidance for TFS 2015, a new interesting article cames out on how to do a Dry Run in a pre-production environment. In that articles a couple of tricks worth a mention, because they are really interesting and easy to do.

Risk of corrupting production environment

Tfs uses a lot of extra tools and products to fulfill it functions, it is based on Sql Server database but it communicates also with Reporting Services, Sharepoint, SCVMM for Lab management, test controllers and so on. When you restore a backup of your production environment to a clone (pre-production) environment, you need to be sure that this cloned installation does not corrupt your production environment.

As an example, if cloned server still uses the same Reporting Services instance of production server, you will probably end with a corrupted Reporting Services Database.

Protect your environment

In the above article, a couple of simple technique are described to avoid your cloned pre-production TFS corrupt something in production environment.

Edit your hosts file to make all of production servers not reachable from cloned server.

This is the simplest but most efficient trick, if you modifiy hosts file in cloned machine, giving an inexistent ip address for all the names of machines related to TFS environment, you are pretty sure that cloned environment cannot corrupt other services.

If for some reason you forgot to change Lab Management SCVMM Address or Sharepoint, cloned machine is not able to reach them, because name resolves to invalid address.

Use a different user to run TFS Service cloned environment, and be sure that this user has no special permission

Usually TFS Services runs with an account called TFService, and this account has lot of privileges in all machines related to TFS environment. As an example, it has right to manage SCVMM in a Lab Management scenario. If you create a user called TFSClonedService or TFSServiceCloned, withouth no special permission, and use that user to run cloned TFS environment, you are pretty sure that if cloned environment try to contact some external service (Ex SCVMM, Report Service, Etc) you will get a Unauthorized exception.

Remember that running a cloned TFS instance is an operation that should be done with great care, and you should adopt all techniques useful to limit accidental damage to production environment.

Gian Maria.